Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 65.1% 309 / 0 / 475
Functions: -% 0 / 1 / 1
Branches: 48.2% 165 / 0 / 342

OMCompiler/Compiler/FrontEnd/Inline.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package Inline
37 " file: Inline.mo
38 package: Inline
39 description: inline functions
40
41
42 This module contains data structures and functions for inline functions.
43
44 The entry point is the inlineCalls function, or inlineCallsInFunctions
45 "
46
47 import Absyn;
48 import AbsynUtil;
49 import AvlSetPath;
50 import AvlTreePathFunction;
51 import BaseHashTable;
52 import DAE;
53 import HashTableCG;
54 import SCode;
55 import UnorderedMap;
56 import Util;
57
58 type Functiontuple = tuple<Option<AvlTreePathFunction.Tree>,list<DAE.InlineType>>;
59 type ArgMemo = UnorderedMap<DAE.ComponentRef, DAE.Exp>;
60 type ReplaceArgsTuple = tuple<list<tuple<DAE.ComponentRef,DAE.Exp>>,HashTableCG.HashTable,Boolean,ArgMemo>;
61
62 protected
63
64 import ClassInf;
65 import ComponentReference;
66 protected import ComponentReferenceBasics;
67 import Config;
68 import DAEDump;
69 import DAEUtil;
70 import Debug;
71 import ElementSource;
72 import Error;
73 import Expression;
74 import ExpressionSimplify;
75 import Flags;
76 import Global;
77 import HashTable2;
78 import HashTable3;
79 import List;
80 import SCodeUtil;
81 import Types;
82 import TypesDump;
83 import VarTransform;
84 import ClassInfUtil;
85 import ExpressionBasics;
86
87 public function inlineStartAttribute
88 input Option<DAE.VariableAttributes> inVariableAttributesOption;
89 input DAE.ElementSource isource;
90 input Functiontuple fns;
91 output Option<DAE.VariableAttributes> outVariableAttributesOption;
92 output DAE.ElementSource osource;
93 output Boolean b;
94 algorithm
95 (outVariableAttributesOption,osource,b):=matchcontinue inVariableAttributesOption
96 local
97 DAE.ElementSource source;
98 DAE.Exp r;
99 Option<DAE.Exp> quantity,unit,displayUnit,fixed,nominal,min,max;
100 Option<DAE.StartOrigin> so;
101 Option<DAE.StateSelect> stateSelectOption;
102 Option<DAE.Uncertainty> uncertainOption;
103 Option<DAE.Distribution> distributionOption;
104 Option<DAE.Exp> equationBound;
105 Option<Boolean> isProtected,finalPrefix;
106 case NONE() then (NONE(),isource,false);
107 case
108 SOME(DAE.VAR_ATTR_REAL(quantity=quantity,unit=unit,displayUnit=displayUnit,min=min,max=max,start = SOME(r),
109 fixed=fixed,nominal=nominal,stateSelectOption=stateSelectOption,uncertainOption=uncertainOption,
110 distributionOption=distributionOption,equationBound=equationBound,isProtected=isProtected,finalPrefix=finalPrefix,
111 startOrigin=so))
112 algorithm
113
2/2
✓ Branch 1 taken 358467 times.
✓ Branch 2 taken 1091 times.
359558 (r,source,true,_) := inlineExp(r,fns,isource);
114 1091 then (SOME(DAE.VAR_ATTR_REAL(quantity,unit,displayUnit,min,max,SOME(r),fixed,nominal,
115 stateSelectOption,uncertainOption,distributionOption,equationBound,isProtected,finalPrefix,so)),source,true);
116 case SOME(DAE.VAR_ATTR_INT(quantity=quantity,min=min,max=max,start = SOME(r),
117 fixed=fixed,uncertainOption=uncertainOption,distributionOption=distributionOption,equationBound=equationBound,
118 isProtected=isProtected,finalPrefix=finalPrefix,startOrigin=so))
119 algorithm
120
1/2
✓ Branch 1 taken 1936 times.
✗ Branch 2 not taken.
1936 (r,source,true,_) := inlineExp(r,fns,isource);
121 ✗ then (SOME(DAE.VAR_ATTR_INT(quantity,min,max,SOME(r),fixed,uncertainOption,distributionOption,equationBound,isProtected,finalPrefix,so)),source,true);
122 case SOME(DAE.VAR_ATTR_BOOL(quantity=quantity,start = SOME(r),
123 fixed=fixed,equationBound=equationBound,isProtected=isProtected,finalPrefix=finalPrefix,startOrigin=so))
124 algorithm
125
1/2
✓ Branch 1 taken 7674 times.
✗ Branch 2 not taken.
7674 (r,source,true,_) := inlineExp(r,fns,isource);
126 ✗ then (SOME(DAE.VAR_ATTR_BOOL(quantity,SOME(r),fixed,equationBound,isProtected,finalPrefix,so)),source,true);
127 case SOME(DAE.VAR_ATTR_STRING(quantity=quantity,start = SOME(r),fixed=fixed,
128 equationBound=equationBound,isProtected=isProtected,finalPrefix=finalPrefix,startOrigin=so))
129 algorithm
130
1/2
✓ Branch 1 taken 156 times.
✗ Branch 2 not taken.
156 (r,source,true,_) := inlineExp(r,fns,isource);
131 ✗ then (SOME(DAE.VAR_ATTR_STRING(quantity,SOME(r),fixed,equationBound,isProtected,finalPrefix,so)),source,true);
132 case SOME(DAE.VAR_ATTR_ENUMERATION(quantity=quantity,min=min,max=max,start = SOME(r),
133 fixed=fixed,equationBound=equationBound,
134 isProtected=isProtected,finalPrefix=finalPrefix,startOrigin=so))
135 algorithm
136
1/2
✓ Branch 1 taken 1949 times.
✗ Branch 2 not taken.
1949 (r,source,true,_) := inlineExp(r,fns,isource);
137 ✗ then (SOME(DAE.VAR_ATTR_ENUMERATION(quantity,min,max,SOME(r),fixed,equationBound,isProtected,finalPrefix,so)),source,true);
138 else (inVariableAttributesOption,isource,false);
139 end matchcontinue;
140 end inlineStartAttribute;
141
142 public function inlineCallsInFunctions
143 "inlines calls in DAEElements"
144 input list<DAE.Function> inElementList;
145 input Functiontuple inFunctions;
146 output list<DAE.Function> outElementList;
147 protected
148 list<DAE.Element> body;
149 DAE.FunctionDefinition fn_def;
150 list<DAE.FunctionDefinition> fn_defs;
151 algorithm
152
4/4
✓ Branch 0 taken 11644 times.
✓ Branch 1 taken 1259 times.
✓ Branch 2 taken 11644 times.
✓ Branch 3 taken 1259 times.
12903 outElementList := list(
153 matchcontinue fn
154 case DAE.FUNCTION(functions = (fn_def as DAE.FUNCTION_DEF()) :: fn_defs)
155 algorithm
156
1/2
✓ Branch 1 taken 6187 times.
✗ Branch 2 not taken.
6187 (body, true) := inlineDAEElements(fn_def.body, inFunctions, {}, false);
157 ✗ fn_def.body := body;
158 ✗ fn.functions := fn_def :: fn_defs;
159 then
160 fn;
161
162 case DAE.FUNCTION(functions = (fn_def as DAE.FUNCTION_EXT()) :: fn_defs)
163 algorithm
164
1/2
✓ Branch 1 taken 1143 times.
✗ Branch 2 not taken.
1143 (body, true) := inlineDAEElements(fn_def.body, inFunctions, {}, false);
165 ✗ fn_def.body := body;
166 ✗ fn.functions := fn_def :: fn_defs;
167 then
168 fn;
169
170 11644 else fn;
171 end matchcontinue
172 for fn in inElementList);
173 end inlineCallsInFunctions;
174
175
176 protected function inlineDAEElementsLst
177 input list<list<DAE.Element>> inElementList;
178 input Functiontuple inFunctions;
179 input list<list<DAE.Element>> iAcc;
180 input Boolean iInlined;
181 output list<list<DAE.Element>> outElementList;
182 output Boolean OInlined;
183 algorithm
184 (outElementList,OInlined) := match inElementList
185 local
186 list<DAE.Element> elem;
187 list<list<DAE.Element>> rest,acc;
188 Boolean inlined;
189 ✗ case {} then (listReverse(iAcc),iInlined);
190 case elem::rest
191 algorithm
192 ✗ (elem,inlined) := inlineDAEElements(elem,inFunctions,{},false);
193 ✗ (acc,inlined) := inlineDAEElementsLst(rest,inFunctions,elem::iAcc,inlined or iInlined);
194 then
195 (acc,inlined);
196 end match;
197 end inlineDAEElementsLst;
198
199 protected function inlineDAEElements
200 input list<DAE.Element> inElementList;
201 input Functiontuple inFunctions;
202 input list<DAE.Element> iAcc;
203 input Boolean iInlined;
204 output list<DAE.Element> outElementList;
205 output Boolean OInlined;
206 algorithm
207 (outElementList,OInlined) := match inElementList
208 local
209 DAE.Element elem;
210 list<DAE.Element> rest,acc;
211 Boolean inlined;
212 7330 case {} then (listReverse(iAcc),iInlined);
213 case elem::rest
214 algorithm
215 59750 (elem,inlined) := inlineDAEElement(elem,inFunctions);
216 59750 (acc,inlined) := inlineDAEElements(rest,inFunctions,elem::iAcc,inlined or iInlined);
217 then
218 (acc,inlined);
219 end match;
220 end inlineDAEElements;
221
222 protected function inlineDAEElement
223 "inlines calls in DAEElements"
224 input DAE.Element inElement;
225 input Functiontuple inFunctions;
226 output DAE.Element outElement;
227 output Boolean inlined;
228 algorithm
229 (outElement,inlined) := matchcontinue(inElement,inFunctions)
230 local
231 Functiontuple fns;
232 list<DAE.Element> elist,elist_1;
233 list<list<DAE.Element>> dlist,dlist_1;
234 DAE.Element el,el_1;
235 DAE.ComponentRef componentRef;
236 DAE.VarKind kind;
237 DAE.VarDirection direction;
238 DAE.VarParallelism parallelism;
239 DAE.VarVisibility protection;
240 DAE.Type ty;
241 DAE.Exp binding,binding_1,exp,exp_1,exp1,exp1_1,exp2,exp2_1,exp3,exp3_1;
242 DAE.InstDims dims;
243 DAE.ConnectorType ct;
244 Option<DAE.VariableAttributes> variableAttributesOption;
245 Option<SCode.Comment> absynCommentOption;
246 Absyn.InnerOuter innerOuter;
247 Boolean e;
248 DAE.Dimensions dimension;
249 DAE.Algorithm alg,alg_1;
250 String i;
251 list<DAE.Exp> explst,explst_1;
252 DAE.ElementSource source;
253 Boolean b1,b2,b3;
254
255 case (DAE.VAR(componentRef,kind,direction,parallelism,protection,ty,SOME(binding),dims,ct,
256 source,variableAttributesOption,absynCommentOption,innerOuter,e),fns)
257 algorithm
258
1/2
✓ Branch 1 taken 6583 times.
✗ Branch 2 not taken.
6583 (binding_1,source,true,_) := inlineExp(binding,fns,source);
259 ✗ then
260 (DAE.VAR(componentRef,kind,direction,parallelism,protection,ty,SOME(binding_1),dims,ct,
261 source,variableAttributesOption,absynCommentOption,innerOuter,e),true);
262
263 case (DAE.DEFINE(componentRef,exp,source) ,fns)
264 algorithm
265 ✗ (exp_1,source,true,_) := inlineExp(exp,fns,source);
266 ✗ then
267 (DAE.DEFINE(componentRef,exp_1,source),true);
268
269 case(DAE.INITIALDEFINE(componentRef,exp,source) ,fns)
270 algorithm
271 ✗ (exp_1,source,true,_) := inlineExp(exp,fns,source);
272 ✗ then
273 (DAE.INITIALDEFINE(componentRef,exp_1,source),true);
274
275 case(DAE.EQUATION(exp1,exp2,source),fns)
276 algorithm
277 ✗ (exp1_1,source,b1,_) := inlineExp(exp1,fns,source);
278 ✗ (exp2_1,source,b2,_) := inlineExp(exp2,fns,source);
279 ✗ true := b1 or b2;
280 ✗ then
281 (DAE.EQUATION(exp1_1,exp2_1,source),true);
282
283 case(DAE.ARRAY_EQUATION(dimension,exp1,exp2,source),fns)
284 algorithm
285 ✗ (exp1_1,source,b1,_) := inlineExp(exp1,fns,source);
286 ✗ (exp2_1,source,b2,_) := inlineExp(exp2,fns,source);
287 ✗ true := b1 or b2;
288 ✗ then
289 (DAE.ARRAY_EQUATION(dimension,exp1_1,exp2_1,source),true);
290
291 case(DAE.INITIAL_ARRAY_EQUATION(dimension,exp1,exp2,source),fns)
292 algorithm
293 ✗ (exp1_1,source,b1,_) := inlineExp(exp1,fns,source);
294 ✗ (exp2_1,source,b2,_) := inlineExp(exp2,fns,source);
295 ✗ true := b1 or b2;
296 ✗ then
297 (DAE.INITIAL_ARRAY_EQUATION(dimension,exp1_1,exp2_1,source),true);
298
299 case(DAE.COMPLEX_EQUATION(exp1,exp2,source),fns)
300 algorithm
301 ✗ (exp1_1,source,b1,_) := inlineExp(exp1,fns,source);
302 ✗ (exp2_1,source,b2,_) := inlineExp(exp2,fns,source);
303 ✗ true := b1 or b2;
304 ✗ then
305 (DAE.COMPLEX_EQUATION(exp1_1,exp2_1,source),true);
306
307 case(DAE.INITIAL_COMPLEX_EQUATION(exp1,exp2,source),fns)
308 algorithm
309 ✗ (exp1_1,source,b1,_) := inlineExp(exp1,fns,source);
310 ✗ (exp2_1,source,b2,_) := inlineExp(exp2,fns,source);
311 ✗ true := b1 or b2;
312 ✗ then
313 (DAE.INITIAL_COMPLEX_EQUATION(exp1_1,exp2_1,source),true);
314
315 case(DAE.WHEN_EQUATION(exp,elist,SOME(el),source),fns)
316 algorithm
317 ✗ (exp_1,source,b1,_) := inlineExp(exp,fns,source);
318 ✗ (elist_1,b2) := inlineDAEElements(elist,fns,{},false);
319 ✗ (el_1,b3) := inlineDAEElement(el,fns);
320 ✗ true := b1 or b2 or b3;
321 ✗ then
322 (DAE.WHEN_EQUATION(exp_1,elist_1,SOME(el_1),source),true);
323
324 case(DAE.WHEN_EQUATION(exp,elist,NONE(),source),fns)
325 algorithm
326 ✗ (exp_1,source,b1,_) := inlineExp(exp,fns,source);
327 ✗ (elist_1,b2) := inlineDAEElements(elist,fns,{},false);
328 ✗ true := b1 or b2;
329 ✗ then
330 (DAE.WHEN_EQUATION(exp_1,elist_1,NONE(),source),true);
331
332 case(DAE.IF_EQUATION(explst,dlist,elist,source) ,fns)
333 algorithm
334 ✗ (explst_1,source,b1) := inlineExps(explst,fns,source);
335 ✗ (dlist_1,b2) := inlineDAEElementsLst(dlist,fns,{},false);
336 ✗ (elist_1,b3) := inlineDAEElements(elist,fns,{},false);
337 ✗ true := b1 or b2 or b3;
338 ✗ then
339 (DAE.IF_EQUATION(explst_1,dlist_1,elist_1,source),true);
340
341 case(DAE.INITIAL_IF_EQUATION(explst,dlist,elist,source) ,fns)
342 algorithm
343 ✗ (explst_1,source,b1) := inlineExps(explst,fns,source);
344 ✗ (dlist_1,b2) := inlineDAEElementsLst(dlist,fns,{},false);
345 ✗ (elist_1,b3) := inlineDAEElements(elist,fns,{},false);
346 ✗ true := b1 or b2 or b3;
347 ✗ then
348 (DAE.INITIAL_IF_EQUATION(explst_1,dlist_1,elist_1,source),true);
349
350 case(DAE.INITIALEQUATION(exp1,exp2,source),fns)
351 algorithm
352 ✗ (exp1_1,source,_,_) := inlineExp(exp1,fns,source);
353 ✗ (exp2_1,source,_,_) := inlineExp(exp2,fns,source);
354 ✗ then
355 (DAE.INITIALEQUATION(exp1_1,exp2_1,source),true);
356
357 case((DAE.ALGORITHM(alg,source)),fns)
358 algorithm
359
1/2
✓ Branch 1 taken 6177 times.
✗ Branch 2 not taken.
6177 (alg_1,true) := inlineAlgorithm(alg,fns);
360 ✗ then
361 (DAE.ALGORITHM(alg_1,source),true);
362
363 case((DAE.INITIALALGORITHM(alg,source)) ,fns)
364 algorithm
365 ✗ (alg_1,true) := inlineAlgorithm(alg,fns);
366 ✗ then
367 (DAE.INITIALALGORITHM(alg_1,source),true);
368
369 case(DAE.COMP(i,elist,source,absynCommentOption),fns)
370 algorithm
371 ✗ (elist_1,true) := inlineDAEElements(elist,fns,{},false);
372 ✗ then
373 (DAE.COMP(i,elist_1,source,absynCommentOption),true);
374
375 case(DAE.ASSERT(exp1,exp2,exp3,source) ,fns)
376 algorithm
377 ✗ (exp1_1,source,b1,_) := inlineExp(exp1,fns,source);
378 ✗ (exp2_1,source,b2,_) := inlineExp(exp2,fns,source);
379 ✗ (exp3_1,source,b3,_) := inlineExp(exp3,fns,source);
380 ✗ true := b1 or b2 or b3;
381 ✗ then
382 (DAE.ASSERT(exp1_1,exp2_1,exp3_1,source),true);
383
384 case(DAE.INITIAL_ASSERT(exp1,exp2,exp3,source) ,fns)
385 algorithm
386 ✗ (exp1_1,source,b1,_) := inlineExp(exp1,fns,source);
387 ✗ (exp2_1,source,b2,_) := inlineExp(exp2,fns,source);
388 ✗ (exp3_1,source,b3,_) := inlineExp(exp3,fns,source);
389 ✗ true := b1 or b2 or b3;
390 ✗ then
391 (DAE.INITIAL_ASSERT(exp1_1,exp2_1,exp3_1,source),true);
392
393 case(DAE.TERMINATE(exp,source),fns)
394 algorithm
395 ✗ (exp_1,source,true,_) := inlineExp(exp,fns,source);
396 ✗ then
397 (DAE.TERMINATE(exp_1,source),true);
398
399 case(DAE.INITIAL_TERMINATE(exp,source),fns)
400 algorithm
401 ✗ (exp_1,source,true,_) := inlineExp(exp,fns,source);
402 ✗ then
403 (DAE.INITIAL_TERMINATE(exp_1,source),true);
404
405 case(DAE.REINIT(componentRef,exp,source),fns)
406 algorithm
407 ✗ (exp_1,source,true,_) := inlineExp(exp,fns,source);
408 ✗ then
409 (DAE.REINIT(componentRef,exp_1,source),true);
410
411 case(DAE.NORETCALL(exp,source),fns)
412 algorithm
413 ✗ (exp,source,true,_) := inlineExp(exp,fns,source);
414 ✗ then
415 (DAE.NORETCALL(exp,source),true);
416
417 case(DAE.INITIAL_NORETCALL(exp,source),fns)
418 algorithm
419 ✗ (exp,source,true,_) := inlineExp(exp,fns,source);
420 ✗ then
421 (DAE.INITIAL_NORETCALL(exp,source),true);
422
423 case(el,_)
424 then
425 (el,false);
426 end matchcontinue;
427 end inlineDAEElement;
428
429 public function inlineAlgorithm
430 "inline calls in an DAE.Algorithm"
431 input DAE.Algorithm inAlgorithm;
432 input Functiontuple inElementList;
433 output DAE.Algorithm outAlgorithm;
434 output Boolean inlined;
435 algorithm
436 (outAlgorithm,inlined) := match(inAlgorithm,inElementList)
437 local
438 list<DAE.Statement> stmts,stmts_1;
439 Functiontuple fns;
440 case(DAE.ALGORITHM_STMTS(stmts),fns)
441 algorithm
442 6177 (stmts_1,inlined) := inlineStatements(stmts,fns,{},false);
443
1/2
✓ Branch 1 taken 6177 times.
✗ Branch 2 not taken.
6177 then
444 (DAE.ALGORITHM_STMTS(stmts_1),inlined);
445 else
446 algorithm
447 ✗ true := Flags.isSet(Flags.FAILTRACE);
448 ✗ Debug.trace("Inline.inlineAlgorithm failed\n");
449 ✗ then
450 fail();
451 end match;
452 end inlineAlgorithm;
453
454 public function inlineStatements
455 input list<DAE.Statement> inStatements;
456 input Functiontuple inElementList;
457 input list<DAE.Statement> iAcc;
458 input Boolean iInlined;
459 output list<DAE.Statement> outStatements;
460 output Boolean OInlined;
461 algorithm
462 (outStatements,OInlined) := match inStatements
463 local
464 DAE.Statement stmt;
465 list<DAE.Statement> rest,acc;
466 Boolean inlined;
467 49861 case {} then (listReverse(iAcc),iInlined);
468 case stmt::rest
469 algorithm
470 138718 (stmt,inlined) := inlineStatement(stmt,inElementList);
471 138718 (acc,inlined) := inlineStatements(rest,inElementList,stmt::iAcc,inlined or iInlined);
472 then
473 (acc,inlined);
474 end match;
475 end inlineStatements;
476
477 protected function inlineStatement
478 "inlines calls in an DAE.Statement"
479 input DAE.Statement inStatement;
480 input Functiontuple inElementList;
481 output DAE.Statement outStatement;
482 output Boolean inlined;
483 algorithm
484 (outStatement,inlined) := matchcontinue(inStatement,inElementList)
485 local
486 Functiontuple fns;
487 DAE.Statement stmt,stmt_1;
488 DAE.Type t;
489 DAE.Exp e,e_1,e1,e1_1,e2,e2_1,e3,e3_1;
490 list<DAE.Exp> explst,explst_1;
491 DAE.Else a_else,a_else_1;
492 list<DAE.Statement> stmts,stmts_1;
493 Boolean b,b1,b2,b3;
494 String i;
495 DAE.ElementSource source;
496 list<DAE.ComponentRef> conditions;
497 Boolean initialCall;
498 list<tuple<DAE.ComponentRef, array<DAE.Exp>>> sub_iters;
499 case (DAE.STMT_ASSIGN(t,e1,e2,source),fns)
500 algorithm
501 102329 (e1_1,source,b1,_) := inlineExp(e1,fns,source);
502 102329 (e2_1,source,b2,_) := inlineExp(e2,fns,source);
503
3/4
✓ Branch 0 taken 102329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 102327 times.
✓ Branch 3 taken 2 times.
102329 true := b1 or b2;
504 2 then
505 (DAE.STMT_ASSIGN(t,e1_1,e2_1,source),true);
506 case(DAE.STMT_TUPLE_ASSIGN(t,explst,e,source),fns)
507 algorithm
508 1610 (explst_1,source,b1) := inlineExps(explst,fns,source);
509 1610 (e_1,source,b2,_) := inlineExp(e,fns,source);
510
2/4
✓ Branch 0 taken 1610 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1610 times.
✗ Branch 3 not taken.
1610 true := b1 or b2;
511 ✗ then
512 (DAE.STMT_TUPLE_ASSIGN(t,explst_1,e_1,source),true);
513 case(DAE.STMT_ASSIGN_ARR(t,e1,e2,source),fns)
514 algorithm
515 2067 (e1_1,source,b1,_) := inlineExp(e1,fns,source);
516 2067 (e2_1,source,b2,_) := inlineExp(e2,fns,source);
517
2/4
✓ Branch 0 taken 2067 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2067 times.
✗ Branch 3 not taken.
2067 true := b1 or b2;
518 ✗ then
519 (DAE.STMT_ASSIGN_ARR(t,e1_1,e2_1,source),true);
520 case(DAE.STMT_IF(e,stmts,a_else,source),fns)
521 algorithm
522 10314 (e_1,source,b1,_) := inlineExp(e,fns,source);
523 10314 (stmts_1,b2) := inlineStatements(stmts,fns,{},false);
524 10314 (a_else_1,source,b3) := inlineElse(a_else,fns,source);
525
3/6
✓ Branch 0 taken 10314 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10314 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10314 times.
✗ Branch 5 not taken.
10314 true := b1 or b2 or b3;
526 ✗ then
527 (DAE.STMT_IF(e_1,stmts_1,a_else_1,source),true);
528 case(DAE.STMT_FOR(t,b,i,e,stmts,source,sub_iters),fns)
529 algorithm
530 3840 (e_1,source,b1,_) := inlineExp(e,fns,source);
531 3840 (stmts_1,b2) := inlineStatements(stmts,fns,{},false);
532
2/4
✓ Branch 0 taken 3840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3840 times.
✗ Branch 3 not taken.
3840 true := b1 or b2;
533 ✗ then
534 (DAE.STMT_FOR(t,b,i,e_1,stmts_1,source,sub_iters),true);
535 case(DAE.STMT_WHILE(e,stmts,source),fns)
536 algorithm
537 217 (e_1,source,b1,_) := inlineExp(e,fns,source);
538 217 (stmts_1,b2) := inlineStatements(stmts,fns,{},false);
539
2/4
✓ Branch 0 taken 217 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 217 times.
✗ Branch 3 not taken.
217 true := b1 or b2;
540 ✗ then
541 (DAE.STMT_WHILE(e_1,stmts_1,source),true);
542 case(DAE.STMT_WHEN(e,conditions,initialCall,stmts,SOME(stmt),source),fns)
543 algorithm
544 988 (e_1,source,b1,_) := inlineExp(e,fns,source);
545 988 (stmts_1,b2) := inlineStatements(stmts,fns,{},false);
546 988 (stmt_1,b3) := inlineStatement(stmt,fns);
547
3/6
✓ Branch 0 taken 988 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 988 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 988 times.
✗ Branch 5 not taken.
988 true := b1 or b2 or b3;
548 ✗ then
549 (DAE.STMT_WHEN(e_1,conditions,initialCall,stmts_1,SOME(stmt_1),source),true);
550 case(DAE.STMT_WHEN(e,conditions,initialCall,stmts,NONE(),source),fns)
551 algorithm
552 2455 (e_1,source,b1,_) := inlineExp(e,fns,source);
553 2455 (stmts_1,b2) := inlineStatements(stmts,fns,{},false);
554
3/4
✓ Branch 0 taken 2455 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2453 times.
✓ Branch 3 taken 2 times.
2455 true := b1 or b2;
555
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
4 then
556 (DAE.STMT_WHEN(e_1,conditions,initialCall,stmts_1,NONE(),source),true);
557 case(DAE.STMT_ASSERT(e1,e2,e3,source),fns)
558 algorithm
559 14015 (e1_1,source,b1,_) := inlineExp(e1,fns,source);
560 14015 (e2_1,source,b2,_) := inlineExp(e2,fns,source);
561 14015 (e3_1,source,b3,_) := inlineExp(e3,fns,source);
562
4/6
✓ Branch 0 taken 13999 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 13999 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13999 times.
✗ Branch 5 not taken.
14015 true := b1 or b2 or b3;
563 16 then
564 (DAE.STMT_ASSERT(e1_1,e2_1,e3_1,source),true);
565 case(DAE.STMT_TERMINATE(e,source),fns)
566 algorithm
567
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 (e_1,source,true,_) := inlineExp(e,fns,source);
568 ✗ then
569 (DAE.STMT_TERMINATE(e_1,source),true);
570 case(DAE.STMT_REINIT(e1,e2,source),fns)
571 algorithm
572 460 (e1_1,source,b1,_) := inlineExp(e1,fns,source);
573 460 (e2_1,source,b2,_) := inlineExp(e2,fns,source);
574
2/4
✓ Branch 0 taken 460 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 460 times.
✗ Branch 3 not taken.
460 true := b1 or b2;
575 ✗ then
576 (DAE.STMT_REINIT(e1_1,e2_1,source),true);
577 case(DAE.STMT_NORETCALL(e,source),fns)
578 algorithm
579
2/2
✓ Branch 1 taken 1006 times.
✓ Branch 2 taken 1 time.
1007 (e_1,source,true,_) := inlineExp(e,fns,source);
580 1 then
581 (DAE.STMT_NORETCALL(e_1,source),true);
582 case(DAE.STMT_FAILURE(stmts,source),fns)
583 algorithm
584 ✗ (stmts_1,true) := inlineStatements(stmts,fns,{},false);
585 ✗ then
586 (DAE.STMT_FAILURE(stmts_1,source),true);
587 case(stmt,_) then (stmt,false);
588 end matchcontinue;
589 end inlineStatement;
590
591 protected function inlineElse
592 "inlines calls in an DAE.Else"
593 input DAE.Else inElse;
594 input Functiontuple inElementList;
595 input DAE.ElementSource inSource;
596 output DAE.Else outElse;
597 output DAE.ElementSource outSource;
598 output Boolean inlined;
599 algorithm
600 (outElse,outSource,inlined) := matchcontinue(inElse,inElementList,inSource)
601 local
602 Functiontuple fns;
603 DAE.Else a_else,a_else_1;
604 DAE.Exp e,e_1;
605 list<DAE.Statement> stmts,stmts_1;
606 DAE.ElementSource source;
607 Boolean b1,b2,b3;
608 case (DAE.ELSEIF(e,stmts,a_else),fns,source)
609 algorithm
610 3091 (e_1,source,b1,_) := inlineExp(e,fns,source);
611 3091 (stmts_1,b2) := inlineStatements(stmts,fns,{},false);
612 3091 (a_else_1,source,b3) := inlineElse(a_else,fns,source);
613
3/6
✓ Branch 0 taken 3091 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3091 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3091 times.
✗ Branch 5 not taken.
3091 true := b1 or b2 or b3;
614 ✗ then
615 (DAE.ELSEIF(e_1,stmts_1,a_else_1),source,true);
616 case (DAE.ELSE(stmts),fns,source)
617 algorithm
618
1/2
✓ Branch 1 taken 4067 times.
✗ Branch 2 not taken.
4067 (stmts_1,true) := inlineStatements(stmts,fns,{},false);
619 ✗ then
620 (DAE.ELSE(stmts_1),source,true);
621 case (a_else,_,source) then (a_else,source,false);
622 end matchcontinue;
623 end inlineElse;
624
625 public function inlineExpOpt "
626 function: inlineExpOpt
627 inlines calls in an DAE.Exp"
628 input Option<DAE.Exp> inExpOption;
629 input Functiontuple inElementList;
630 input DAE.ElementSource inSource;
631 output Option<DAE.Exp> outExpOption;
632 output DAE.ElementSource outSource;
633 output Boolean inlined;
634 algorithm
635 (outExpOption,outSource,inlined) := match inExpOption
636 local
637 DAE.Exp exp;
638 DAE.ElementSource source;
639 Boolean b;
640 case NONE() then (NONE(),inSource,false);
641 case SOME(exp)
642 algorithm
643 918745 (exp,source,b,_) := inlineExp(exp,inElementList,inSource);
644 918745 then
645 (SOME(exp),source,b);
646 end match;
647 end inlineExpOpt;
648
649 public function inlineExp "
650 function: inlineExp
651 inlines calls in a DAE.Exp"
652 input DAE.Exp inExp;
653 input Functiontuple inElementList;
654 input DAE.ElementSource inSource;
655 output DAE.Exp outExp;
656 output DAE.ElementSource outSource;
657 output Boolean inlined;
658 output list<DAE.Statement> assrtLstOut;
659 algorithm
660 (outExp,outSource,inlined,assrtLstOut) := match inExp
661 local
662 DAE.Exp e_1,e_2;
663 DAE.ElementSource source;
664 list<DAE.Statement> assrtLst;
665 Boolean b;
666
667 // never inline WILD!
668 case DAE.CREF(componentRef = DAE.WILD()) then (inExp,inSource,false,{});
669
670 else
671 algorithm
672 try
673 8449589 (e_1,assrtLst) := Expression.traverseExpBottomUp(inExp,function inlineCall(fns=inElementList),{});
674
2/2
✓ Branch 0 taken 8413431 times.
✓ Branch 1 taken 36158 times.
8449589 false := referenceEq(inExp, e_1);
675
2/2
✓ Branch 1 taken 81 times.
✓ Branch 2 taken 36077 times.
36158 if Flags.isSet(Flags.INFO_XML_OPERATIONS) then
676 81 source := ElementSource.addSymbolicTransformation(inSource,DAE.OP_INLINE(DAE.PARTIAL_EQUATION(inExp),DAE.PARTIAL_EQUATION(e_1)));
677
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 81 times.
81 (DAE.PARTIAL_EQUATION(e_2),source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.PARTIAL_EQUATION(e_1), source);
678 else
679 36077 e_2 := ExpressionSimplify.simplify(e_1);
680 source := inSource;
681 end if;
682 b := true;
683 else
684 8413431 (e_2,source,b,assrtLst) := (inExp,inSource,false,{});
685 end try;
686 8449589 then
687 (e_2,source,b,assrtLst);
688 end match;
689 end inlineExp;
690
691 public function forceInlineExp "
692 function: inlineExp
693 inlines calls in an DAE.Exp"
694 input DAE.Exp inExp;
695 input Functiontuple inElementList;
696 input DAE.ElementSource inSource;
697 input CevalConstFunc cevalConst;
698 output DAE.Exp outExp;
699 output DAE.ElementSource outSource;
700 output Boolean inlineperformed;
701 partial function CevalConstFunc
702 input DAE.Exp exp;
703 input AvlTreePathFunction.Tree functions;
704 output DAE.Exp oexp;
705 end CevalConstFunc;
706 algorithm
707 (outExp,outSource,inlineperformed) := match (inExp,inElementList,inSource)
708 local
709 Functiontuple fns;
710 DAE.Exp e,e_1;
711 DAE.ElementSource source;
712 AvlTreePathFunction.Tree functionTree;
713 Boolean b;
714 case (e,(SOME(functionTree),_),source)
715 guard
716 Expression.isConst(inExp)
717 algorithm
718 try
719
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1619 times.
1619 e_1 := cevalConst(inExp, functionTree);
720 1619 source := ElementSource.addSymbolicTransformation(source,DAE.OP_INLINE(DAE.PARTIAL_EQUATION(e),DAE.PARTIAL_EQUATION(e_1)));
721 b := true;
722 else
723 e_1 := inExp;
724 source := inSource;
725 b := false;
726 end try;
727 then (e_1,source,b);
728 case (e,fns,source)
729 algorithm
730 37919 (e_1,_) := Expression.traverseExpBottomUp(e,function forceInlineCall(fns=fns, visitedPaths=AvlSetPath.Tree.EMPTY()),{});
731 37919 b := not referenceEq(e, e_1);
732
2/2
✓ Branch 0 taken 8582 times.
✓ Branch 1 taken 29337 times.
37919 if b then
733 8582 source := ElementSource.addSymbolicTransformation(source,DAE.OP_INLINE(DAE.PARTIAL_EQUATION(e),DAE.PARTIAL_EQUATION(e_1)));
734
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 8582 times.
8582 (DAE.PARTIAL_EQUATION(e_1),source) := ExpressionSimplify.simplifyAddSymbolicOperation(DAE.PARTIAL_EQUATION(e_1), source);
735 end if;
736 then
737 (e_1,source,b);
738 else (inExp,inSource,false);
739 end match;
740 end forceInlineExp;
741
742 public function inlineExps "
743 function: inlineExp
744 inlines calls in an DAE.Exp"
745 input list<DAE.Exp> inExps;
746 input Functiontuple inElementList;
747 input DAE.ElementSource inSource;
748 output list<DAE.Exp> outExps;
749 output DAE.ElementSource outSource;
750 output Boolean inlined;
751 algorithm
752 1779 (outExps,outSource,inlined) := inlineExpsWork(inExps,inElementList,inSource,{},false);
753 end inlineExps;
754
755 protected function inlineExpsWork "
756 function: inlineExp
757 inlines calls in an DAE.Exp"
758 input list<DAE.Exp> inExps;
759 input Functiontuple fns;
760 input DAE.ElementSource inSource;
761 input list<DAE.Exp> iAcc;
762 input Boolean iInlined;
763 output list<DAE.Exp> outExps;
764 output DAE.ElementSource outSource;
765 output Boolean oInlined;
766 algorithm
767 (outExps,outSource,oInlined) := match inExps
768 local
769 DAE.Exp e;
770 list<DAE.Exp> exps;
771 DAE.ElementSource source;
772 Boolean b;
773
774 1779 case {} then (listReverse(iAcc),inSource,iInlined);
775 case e::exps
776 algorithm
777 5048 (e,source,b,_) := inlineExp(e,fns,inSource);
778 5048 (exps,source,b) := inlineExpsWork(exps,fns,source,e::iAcc,b or iInlined);
779 then
780 (exps,source,b);
781 end match;
782 end inlineExpsWork;
783
784 public function checkExpsTypeEquiv
785 "@author: adrpo
786 check two types for equivalence"
787 input DAE.Exp inExp1;
788 input DAE.Exp inExp2;
789 output Boolean bEquiv;
790 algorithm
791 bEquiv := match inExp2
792 local
793 DAE.Type ty1,ty2;
794 Boolean b;
795 case _
796 algorithm
797
2/2
✓ Branch 1 taken 61863 times.
✓ Branch 2 taken 378 times.
62241 if Config.acceptMetaModelicaGrammar() then
798 // adrpo: DO NOT COMPARE TYPES for equivalence for MetaModelica!
799 b := true;
800 else // compare
801 61863 ty1 := Expression.typeof(inExp1);
802 61863 ty2 := Expression.typeof(inExp2);
803 61863 ty2 := Types.traverseType(ty2, -1, Types.makeExpDimensionsUnknown);
804 61863 b := Types.equivtypesOrRecordSubtypeOf(ty1,ty2);
805 end if;
806 then b;
807 end match;
808 end checkExpsTypeEquiv;
809
810 public function inlineCall
811 "replaces an inline call with the expression from the function"
812 input output DAE.Exp exp;
813 input output list<DAE.Statement> assrtLst;
814 input Functiontuple fns;
815 algorithm
816 () := match exp
817 case DAE.CALL()
818 algorithm
819 1414955 (exp, assrtLst) := inlineCallWork(exp, assrtLst, fns);
820 then ();
821 else ();
822 end match;
823 end inlineCall;
824
825 protected function inlineCallWork
826 input output DAE.Exp exp;
827 input output list<DAE.Statement> assrtLst;
828 input Functiontuple fns;
829 algorithm
830 (exp,assrtLst) := matchcontinue exp
831 local
832 list<DAE.Element> fn;
833 Absyn.Path p;
834 list<DAE.Exp> args;
835 list<DAE.ComponentRef> crefs;
836 list<tuple<DAE.ComponentRef, DAE.Exp>> argmap;
837 list<DAE.ComponentRef> lst_cr;
838 DAE.Exp newExp,newExp1, e1;
839 DAE.InlineType inlineType;
840 DAE.Statement assrt;
841 HashTableCG.HashTable checkcr;
842 list<DAE.Statement> stmts,assrtStmts;
843 VarTransform.VariableReplacements repl;
844 Boolean generateEvents;
845 Option<SCode.Comment> comment;
846 DAE.Type ty;
847 DAE.Function func;
848
849 // If we disable inlining by use of flags, we still inline builtin functions
850 case DAE.CALL(attr=DAE.CALL_ATTR(inlineType=inlineType))
851 algorithm
852
1/2
✓ Branch 1 taken 1414955 times.
✗ Branch 2 not taken.
1414955 false := Flags.isSet(Flags.INLINE_FUNCTIONS);
853 ✗ false := valueEq(DAE.BUILTIN_EARLY_INLINE(), inlineType);
854 ✗ then (exp,assrtLst);
855
856 // remove empty calls entirely if it is not impure
857 case DAE.CALL(p,_,DAE.CALL_ATTR(ty=ty))
858 algorithm
859 // no return value?
860
2/2
✓ Branch 1 taken 1414075 times.
✓ Branch 2 taken 100 times.
1414955 0 := Types.getDimensionProduct(ty);
861 // is impure?
862 100 func := getFunction(p,fns);
863
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
16 false := DAEUtil.getFunctionImpureAttribute(func);
864 16 newExp := Expression.makeArray({}, ty, true);
865 16 then (newExp, assrtLst);
866
867 case e1 as DAE.CALL(p,args,DAE.CALL_ATTR(ty=ty,inlineType=inlineType))
868 algorithm
869 //true = DAEUtil.convertInlineTypeToBool(inlineType);
870
2/2
✓ Branch 1 taken 1355595 times.
✓ Branch 2 taken 59344 times.
1414939 true := checkInlineType(inlineType,fns);
871 59344 (fn,comment) := getFunctionBody(p,fns);
872 43097 (checkcr,repl) := getInlineHashTableVarTransform();
873
2/2
✓ Branch 1 taken 378 times.
✓ Branch 2 taken 42719 times.
43097 if (Config.acceptMetaModelicaGrammar()) then // MetaModelica
874 378 crefs := List.map(fn,getInputCrefs);
875 378 crefs := List.select(crefs,removeWilds);
876 378 argmap := List.zip(crefs,args);
877
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 378 times.
378 false := List.any(fn,DAEUtil.isProtectedVar);
878 378 newExp := getRhsExp(fn);
879 // compare types
880
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 378 times.
378 true := checkExpsTypeEquiv(e1, newExp);
881 378 (argmap,checkcr) := extendCrefRecords(argmap,checkcr);
882 // add noEvent to avoid events as usually for functions
883 // MSL 3.2.1 need GenerateEvents to disable this
884 378 newExp := Expression.addNoEventToRelationsAndConds(newExp);
885 378 newExp := replaceArgsInExp(newExp,argmap,checkcr);
886 // for inlinecalls in functions
887 378 (newExp1,assrtLst) := Expression.traverseExpBottomUp(newExp,function inlineCall(fns=fns),assrtLst);
888 else // normal Modelica
889 // get inputs, body and output
890 42719 (crefs,lst_cr,stmts,repl) := getFunctionInputsOutputBody(fn, repl);
891 // merge statements to one line
892 42183 (repl,assrtStmts) := mergeFunctionBody(stmts,repl,{});
893 // depend on detection of assert or not
894
2/2
✓ Branch 0 taken 41764 times.
✓ Branch 1 taken 6 times.
41770 if (listEmpty(assrtStmts)) then // no assert detected
895
896 // output
897
4/4
✓ Branch 0 taken 41784 times.
✓ Branch 1 taken 41711 times.
✓ Branch 2 taken 41784 times.
✓ Branch 3 taken 41711 times.
83495 newExp := Expression.makeTuple(list( getReplacementCheckComplex(repl,cr,ty) for cr in lst_cr));
898 // compare types
899
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 41711 times.
41711 true := checkExpsTypeEquiv(e1, newExp);
900 // input map cref again function args
901 41711 argmap := List.zip(crefs,args);
902 41711 (checkcr,_) := getInlineHashTableVarTransform();
903 41711 (argmap,checkcr) := extendCrefRecords(argmap,checkcr);
904 // add noEvent to avoid events as usually for functions
905 // MSL 3.2.1 need GenerateEvents to disable this
906 41711 generateEvents := hasGenerateEventsAnnotation(comment);
907
1/2
✓ Branch 0 taken 41711 times.
✗ Branch 1 not taken.
41711 newExp := if not generateEvents then Expression.addNoEventToRelationsAndConds(newExp) else newExp;
908 41711 newExp := replaceArgsInExp(newExp,argmap,checkcr);
909 41700 newExp := setTsubTypesFromCall(newExp, ty);
910 // for inlinecalls in functions
911 41700 (newExp1,assrtLst) := Expression.traverseExpBottomUp(newExp,function inlineCall(fns=fns),assrtLst);
912 else // assert detected
913
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 true := listLength(assrtStmts) == 1;
914 6 assrt := listHead(assrtStmts);
915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 DAE.STMT_ASSERT() := assrt;
916 //newExp = getReplacementCheckComplex(repl,cr,ty); // the function that replaces the output variable
917
4/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
12 newExp := Expression.makeTuple(list( getReplacementCheckComplex(repl,cr,ty) for cr in lst_cr));
918 // compare types
919
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 true := checkExpsTypeEquiv(e1, newExp);
920 6 argmap := List.zip(crefs,args);
921 6 (argmap,checkcr) := extendCrefRecords(argmap,checkcr);
922 // add noEvent to avoid events as usually for functions
923 // MSL 3.2.1 need GenerateEvents to disable this
924 6 generateEvents := hasGenerateEventsAnnotation(comment);
925
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 newExp := if not generateEvents then Expression.addNoEventToRelationsAndConds(newExp) else newExp;
926 6 newExp := replaceArgsInExp(newExp,argmap,checkcr);
927 6 newExp := setTsubTypesFromCall(newExp, ty);
928 6 assrt := inlineAssert(assrt,fns,argmap,checkcr);
929 // for inlinecalls in functions
930 6 (newExp1,assrtLst) := Expression.traverseExpBottomUp(newExp,function inlineCall(fns=fns),assrt::assrtLst);
931 end if;
932 end if;
933 42084 then
934 (newExp1,assrtLst);
935
936 1372855 else (exp,assrtLst);
937
938 end matchcontinue;
939 end inlineCallWork;
940
941 protected function setTsubTypesFromCall
942 "A function body (a, b) := f(x, xi) is inlined as (f(..)[1], f(..)[2]). The type
943 of each TSUB is the type of the output variable inside the function, so its
944 dimensions may refer to the function's inputs, e.g. Real[size(xi, 1)], which can
945 not be evaluated in the calling model. Use the type of the inlined call instead,
946 which is evaluated for the actual arguments (ticket #14185).
947 If the body just passes all outputs of f through, the result is f(..) itself."
948 input DAE.Exp inExp;
949 input DAE.Type inCallType;
950 output DAE.Exp outExp;
951 algorithm
952 outExp := match (inExp, inCallType)
953 local
954 list<DAE.Exp> expLst;
955 list<DAE.Type> types;
956 DAE.Exp call;
957 DAE.CallAttributes attr;
958 Option<list<String>> names;
959
960 // (f(..)[1], ..., f(..)[n]) with all outputs of f in order -> f(..)
961 // keeps the output names of f, but uses the evaluated types of the call
962 case (DAE.TUPLE(PR=expLst as DAE.TSUB(exp=call as DAE.CALL(attr=attr as DAE.CALL_ATTR(ty=DAE.T_TUPLE(names=names))))::_), DAE.T_TUPLE(types=types))
963 guard isTsubTupleOfCall(expLst, call)
964 algorithm
965 10 attr.ty := DAE.T_TUPLE(types, names);
966 5 call.attr := attr;
967 then call;
968
969 case (DAE.TUPLE(PR=expLst), DAE.T_TUPLE(types=types))
970 guard listLength(expLst) == listLength(types)
971
7/8
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 20 times.
✓ Branch 5 taken 10 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 10 times.
30 then DAE.TUPLE(list(setTsubType(e, t) threaded for e in expLst, t in types));
972
973 case (DAE.TSUB(), _)
974 ✗ then setTsubType(inExp, inCallType);
975
976 else inExp;
977 end match;
978 end setTsubTypesFromCall;
979
980 protected function isTsubTupleOfCall
981 "Returns true if inExpLst is {call[1], call[2], ..., call[n]} with all n outputs of call."
982 input list<DAE.Exp> inExpLst;
983 input DAE.Exp inCall;
984 output Boolean b;
985 protected
986 Integer i = 1;
987 list<DAE.Type> types;
988 algorithm
989
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
5 DAE.CALL(attr=DAE.CALL_ATTR(ty=DAE.T_TUPLE(types=types))) := inCall;
990 5 b := listLength(inExpLst) == listLength(types);
991
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
20 for e in inExpLst loop
992 b := b and (match e
993
2/4
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
15 case DAE.TSUB() then e.ix == i and ExpressionBasics.expEqual(e.exp, inCall);
994 else false;
995 end match);
996 15 i := i + 1;
997 end for;
998 end isTsubTupleOfCall;
999
1000 protected function setTsubType
1001 input DAE.Exp inExp;
1002 input DAE.Type inType;
1003 output DAE.Exp outExp;
1004 algorithm
1005 outExp := match inExp
1006 ✗ case DAE.TSUB() then DAE.TSUB(inExp.exp, inExp.ix, inType);
1007 else inExp;
1008 end match;
1009 end setTsubType;
1010
1011 protected function inlineAssert "inlines an assert.
1012 author:Waurich TUD 2013-10"
1013 input DAE.Statement assrtIn;
1014 input Functiontuple fns;
1015 input list<tuple<DAE.ComponentRef, DAE.Exp>> argmap;
1016 input HashTableCG.HashTable checkcr;
1017 output DAE.Statement assrtOut;
1018 protected
1019 DAE.ElementSource source;
1020 DAE.Exp cond, msg, level;
1021 algorithm
1022
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 DAE.STMT_ASSERT(cond=cond, msg=msg, level=level, source=source) := assrtIn;
1023 6 cond := replaceArgsInExp(cond,argmap,checkcr);
1024 //print("ASSERT inlined: "+ExpressionBasics.printExpStr(cond)+"\n");
1025 6 msg := replaceArgsInExp(msg,argmap,checkcr);
1026 // These clear checkcr/repl and need to be performed last
1027 // (cond,_,_,_) := inlineExp(cond,fns,source);
1028 // (msg,_,_,_) := inlineExp(msg,fns,source);
1029 6 assrtOut := DAE.STMT_ASSERT(cond, msg, level, source);
1030 end inlineAssert;
1031
1032
1033 public function hasGenerateEventsAnnotation
1034 input Option<SCode.Comment> comment;
1035 output Boolean b;
1036 algorithm
1037 b := match comment
1038 local
1039 SCode.Annotation anno;
1040 case SOME(SCode.COMMENT(annotation_=SOME(anno)))
1041 59825 then
1042 SCodeUtil.hasBooleanNamedAnnotation(anno,"GenerateEvents");
1043 else false;
1044 end match;
1045 end hasGenerateEventsAnnotation;
1046
1047 protected function dumpArgmap
1048 input tuple<DAE.ComponentRef, DAE.Exp> inTpl;
1049 protected
1050 DAE.ComponentRef cr;
1051 DAE.Exp exp;
1052 algorithm
1053 ✗ (cr,exp) := inTpl;
1054 ✗ print(ComponentReferenceBasics.printComponentRefStr(cr) + " -> " + ExpressionBasics.printExpStr(exp) + "\n");
1055 end dumpArgmap;
1056
1057 public function forceInlineCall
1058 "replaces an inline call with the expression from the function"
1059 input output DAE.Exp exp;
1060 input output list<DAE.Statement> assrtLst;
1061 input Functiontuple fns;
1062 input AvlSetPath.Tree visitedPaths = AvlSetPath.EMPTY();
1063 algorithm
1064 (exp,assrtLst) := matchcontinue exp
1065 local
1066 list<DAE.Element> fn;
1067 Absyn.Path p;
1068 list<DAE.Exp> args;
1069 list<DAE.ComponentRef> lst_cr;
1070 list<DAE.ComponentRef> crefs;
1071 list<tuple<DAE.ComponentRef, DAE.Exp>> argmap;
1072 DAE.Exp newExp,newExp1, e1;
1073 DAE.InlineType inlineType;
1074 HashTableCG.HashTable checkcr;
1075 list<DAE.Statement> stmts;
1076 VarTransform.VariableReplacements repl;
1077 Boolean generateEvents;
1078 Option<SCode.Comment> comment;
1079
1080 case e1 as DAE.CALL(p,args,DAE.CALL_ATTR(inlineType=inlineType)) guard not AvlSetPath.hasKey(visitedPaths, p)
1081 algorithm
1082
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 172487 times.
172499 false := Config.acceptMetaModelicaGrammar();
1083
2/2
✓ Branch 1 taken 58409 times.
✓ Branch 2 taken 114078 times.
172487 true := checkInlineType(inlineType,fns);
1084 114078 (fn,comment) := getFunctionBody(p,fns);
1085 37077 (checkcr,repl) := getInlineHashTableVarTransform();
1086 // get inputs, body and output
1087 37077 (crefs,lst_cr,stmts,repl) := getFunctionInputsOutputBody(fn,repl);
1088 // merge statements to one line
1089 25224 (repl,_) := mergeFunctionBody(stmts,repl,{});
1090 //newExp = VarTransform.getReplacement(repl,cr);
1091
4/4
✓ Branch 0 taken 20183 times.
✓ Branch 1 taken 20146 times.
✓ Branch 2 taken 20183 times.
✓ Branch 3 taken 20146 times.
40329 newExp := Expression.makeTuple(list( VarTransform.getReplacement(repl,cr) for cr in lst_cr));
1092 // compare types
1093
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 20146 times.
20146 true := checkExpsTypeEquiv(e1, newExp);
1094 20146 argmap := List.zip(crefs,args);
1095 20146 (argmap,checkcr) := extendCrefRecords(argmap,checkcr);
1096 // add noEvent to avoid events as usually for functions
1097 // MSL 3.2.1 need GenerateEvents to disable this
1098 20146 generateEvents := hasGenerateEventsAnnotation(comment);
1099
2/2
✓ Branch 0 taken 20145 times.
✓ Branch 1 taken 1 time.
20146 newExp := if not generateEvents then Expression.addNoEventToRelationsAndConds(newExp) else newExp;
1100 20146 newExp := replaceArgsInExp(newExp,argmap,checkcr);
1101 // for inlinecalls in functions
1102 19986 (newExp1,assrtLst) := Expression.traverseExpBottomUp(newExp,function forceInlineCall(fns=fns,visitedPaths=AvlSetPath.add(visitedPaths, p)),assrtLst);
1103 then (newExp1,assrtLst);
1104
1105 1185469 else (exp,assrtLst);
1106 end matchcontinue;
1107 end forceInlineCall;
1108
1109 protected function mergeFunctionBody
1110 input list<DAE.Statement> iStmts;
1111 input VarTransform.VariableReplacements iRepl;
1112 input list<DAE.Statement> assertStmtsIn;
1113 output VarTransform.VariableReplacements oRepl;
1114 output list<DAE.Statement> assertStmtsOut;
1115 algorithm
1116 (oRepl,assertStmtsOut) := match iStmts
1117 local
1118 list<DAE.Statement> stmts;
1119 VarTransform.VariableReplacements repl;
1120 DAE.ComponentRef cr, cr1, cr2;
1121 DAE.ElementSource source;
1122 DAE.Exp exp, exp1, exp2;
1123 DAE.Statement stmt;
1124 list<DAE.Exp> explst;
1125 list<DAE.Statement> assertStmts;
1126 case {} then (iRepl,assertStmtsIn);
1127 case DAE.STMT_ASSIGN(exp1 = DAE.CREF(componentRef = cr), exp = exp)::stmts
1128 algorithm
1129 35387 (exp,_) := VarTransform.replaceExp(exp,iRepl,NONE());
1130 35387 repl := VarTransform.addReplacementNoTransitive(iRepl,cr,exp);
1131 35387 (repl,assertStmts) := mergeFunctionBody(stmts,repl,assertStmtsIn);
1132 then
1133 (repl,assertStmts);
1134 case DAE.STMT_ASSIGN_ARR(lhs = DAE.CREF(componentRef = cr), exp = exp)::stmts
1135 algorithm
1136 30083 (exp,_) := VarTransform.replaceExp(exp,iRepl,NONE());
1137 30083 repl := VarTransform.addReplacementNoTransitive(iRepl,cr,exp);
1138 30083 (repl,assertStmts) := mergeFunctionBody(stmts,repl,assertStmtsIn);
1139 then
1140 (repl,assertStmts);
1141 case DAE.STMT_TUPLE_ASSIGN(expExpLst = explst, exp = exp)::stmts
1142 algorithm
1143 77 (exp,_) := VarTransform.replaceExp(exp,iRepl,NONE());
1144 77 repl := addTplAssignToRepl(explst,1,exp,iRepl);
1145 77 (repl,assertStmts) := mergeFunctionBody(stmts,repl,assertStmtsIn);
1146 then
1147 (repl,assertStmts);
1148 case DAE.STMT_ASSERT(cond = exp, msg = exp1, level = exp2, source = source)::stmts
1149 algorithm
1150 52 (exp,_) := VarTransform.replaceExp(exp,iRepl,NONE());
1151 52 (exp1,_) := VarTransform.replaceExp(exp1,iRepl,NONE());
1152 52 (exp2,_) := VarTransform.replaceExp(exp2,iRepl,NONE());
1153 52 stmt := DAE.STMT_ASSERT(exp,exp1,exp2,source);
1154 52 (repl,assertStmts) := mergeFunctionBody(stmts,iRepl,stmt::assertStmtsIn);
1155 then
1156 (repl,assertStmts);
1157 // if a then x := b; else x := c; end if; => x := if a then b else c;
1158 case DAE.STMT_IF(exp = exp,
1159 statementLst = {DAE.STMT_ASSIGN(exp1 = DAE.CREF(componentRef = cr1), exp = exp1)},
1160 else_=DAE.ELSE(statementLst={DAE.STMT_ASSIGN(exp1 = DAE.CREF(componentRef = cr2), exp = exp2)}))::stmts
1161 guard ComponentReferenceBasics.crefEqual(cr1, cr2)
1162 algorithm
1163 712 (exp,_) := VarTransform.replaceExp(exp,iRepl,NONE());
1164 712 (exp1,_) := VarTransform.replaceExp(exp1,iRepl,NONE());
1165 712 (exp2,_) := VarTransform.replaceExp(exp2,iRepl,NONE());
1166 712 repl := VarTransform.addReplacementNoTransitive(iRepl,cr1,DAE.IFEXP(exp,exp1,exp2));
1167 712 (repl,assertStmts) := mergeFunctionBody(stmts,repl,assertStmtsIn);
1168 then (repl,assertStmts);
1169
1170 case DAE.STMT_IF(exp = exp,
1171 statementLst = {DAE.STMT_ASSIGN_ARR(lhs = DAE.CREF(componentRef = cr1), exp = exp1)},
1172 else_=DAE.ELSE(statementLst={DAE.STMT_ASSIGN_ARR(lhs = DAE.CREF(componentRef = cr2), exp = exp2)}))::stmts
1173 guard ComponentReferenceBasics.crefEqual(cr1, cr2)
1174 algorithm
1175 ✗ (exp,_) := VarTransform.replaceExp(exp,iRepl,NONE());
1176 ✗ (exp1,_) := VarTransform.replaceExp(exp1,iRepl,NONE());
1177 ✗ (exp2,_) := VarTransform.replaceExp(exp2,iRepl,NONE());
1178 ✗ repl := VarTransform.addReplacementNoTransitive(iRepl,cr1,DAE.IFEXP(exp,exp1,exp2));
1179 ✗ (repl,assertStmts) := mergeFunctionBody(stmts,repl,assertStmtsIn);
1180 then (repl,assertStmts);
1181
1182 end match;
1183 end mergeFunctionBody;
1184
1185 protected function addTplAssignToRepl
1186 input list<DAE.Exp> explst;
1187 input Integer indx;
1188 input DAE.Exp iExp;
1189 input VarTransform.VariableReplacements iRepl;
1190 output VarTransform.VariableReplacements oRepl;
1191 algorithm
1192 oRepl := match explst
1193 local
1194 VarTransform.VariableReplacements repl;
1195 DAE.ComponentRef cr;
1196 DAE.Exp exp;
1197 list<DAE.Exp> rest;
1198 DAE.Type tp;
1199 case {} then iRepl;
1200 case DAE.CREF(componentRef = cr,ty=tp)::rest
1201 algorithm
1202 159 exp := DAE.TSUB(iExp,indx,tp);
1203 159 repl := VarTransform.addReplacementNoTransitive(iRepl,cr,exp);
1204 159 then
1205 addTplAssignToRepl(rest,indx+1,iExp,repl);
1206 end match;
1207 end addTplAssignToRepl;
1208
1209 protected function getFunctionInputsOutputBody
1210 input list<DAE.Element> fn;
1211 input VarTransform.VariableReplacements iRepl;
1212 output list<DAE.ComponentRef> oInputs = {};
1213 output list<DAE.ComponentRef> oOutputs = {};
1214 output list<DAE.Statement> oBody = {};
1215 output VarTransform.VariableReplacements oRepl = iRepl;
1216 protected
1217 DAE.Element elt;
1218 DAE.ComponentRef cr;
1219 Option<DAE.Exp> binding;
1220 DAE.Type tp;
1221 list<DAE.Statement> st;
1222
1223 algorithm
1224
2/2
✓ Branch 0 taken 398657 times.
✓ Branch 1 taken 67407 times.
466064 for elt in fn loop
1225 () := match elt
1226
1227 case DAE.VAR(componentRef=cr,direction=DAE.INPUT())
1228 algorithm
1229 oInputs := cr::oInputs;
1230 then ();
1231
1232 case DAE.VAR(componentRef=cr,direction=DAE.OUTPUT(), binding=binding)
1233 algorithm
1234 80059 binding := makeComplexBinding(binding, elt.ty);
1235 80059 oRepl := addOptBindingReplacements(cr,binding,oRepl);
1236 oOutputs := cr :: oOutputs;
1237 then ();
1238
1239 case DAE.VAR(componentRef=cr,protection=DAE.PROTECTED(),binding=binding)
1240 algorithm
1241 // use type of cref, since var type is different
1242 // and has no hint on array or record type
1243 58128 tp := ComponentReference.crefTypeFull(cr);
1244
2/2
✓ Branch 1 taken 1714 times.
✓ Branch 2 taken 56414 times.
58128 false := Expression.isArrayType(tp);
1245
2/2
✓ Branch 1 taken 10675 times.
✓ Branch 2 taken 45739 times.
56414 false := Expression.isRecordType(tp);
1246 45739 oRepl := addOptBindingReplacements(cr,binding,oRepl);
1247 then
1248 ();
1249
1250 case DAE.ALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS(st))
1251 algorithm
1252 67369 oBody := List.append_reverse(st, oBody);
1253 then
1254 ();
1255
1256 case _
1257 algorithm
1258 ✗ Error.addInternalError("Unknown element: " + DAEDump.dumpElementsStr({elt}), sourceInfo());
1259 ✗ then fail();
1260 end match;
1261
1262
1263 end for;
1264
1265 67407 oInputs := listReverse(oInputs);
1266 67407 oOutputs := listReverse(oOutputs);
1267 67407 oBody := listReverse(oBody);
1268
1269 end getFunctionInputsOutputBody;
1270
1271 function makeComplexBinding
1272 "Creates a record binding from the given type if the given binding is empty."
1273 input output Option<DAE.Exp> binding;
1274 input DAE.Type ty;
1275 algorithm
1276 binding := match (binding, ty)
1277 local
1278 list<DAE.Exp> expl;
1279 list<String> strl;
1280 DAE.Exp exp;
1281
1282 case (NONE(), DAE.Type.T_COMPLEX())
1283 algorithm
1284 expl := {};
1285 strl := {};
1286
1287
2/2
✓ Branch 1 taken 17408 times.
✓ Branch 2 taken 2020 times.
19428 for var in listReverse(ty.varLst) loop
1288 () := match var
1289 case DAE.Var.TYPES_VAR(binding = DAE.Binding.EQBOUND(exp = exp))
1290 algorithm
1291 expl := exp :: expl;
1292 4040 strl := var.name :: strl;
1293 then
1294 ();
1295
1296 else
1297 algorithm
1298 13368 return;
1299 then
1300 ();
1301 end match;
1302 end for;
1303
1304 2020 then
1305 SOME(DAE.Exp.RECORD(ClassInfUtil.getStateName(ty.complexClassType), expl, strl, ty));
1306
1307 else binding;
1308 end match;
1309 end makeComplexBinding;
1310
1311 protected function addOptBindingReplacements
1312 input DAE.ComponentRef cr;
1313 input Option<DAE.Exp> binding;
1314 input VarTransform.VariableReplacements iRepl;
1315 output VarTransform.VariableReplacements oRepl;
1316 algorithm
1317 oRepl := match binding
1318 local
1319 DAE.Exp e;
1320 17944 case SOME(e) then addReplacement(cr, e, iRepl);
1321 case NONE() then iRepl;
1322 end match;
1323 end addOptBindingReplacements;
1324
1325 protected function addReplacement
1326 input DAE.ComponentRef iCr;
1327 input DAE.Exp iExp;
1328 input VarTransform.VariableReplacements iRepl;
1329 output VarTransform.VariableReplacements oRepl;
1330 algorithm
1331 oRepl := match iCr
1332 local
1333 case DAE.CREF_IDENT()
1334 17944 then VarTransform.addReplacement(iRepl, iCr, iExp);
1335 else fail();
1336 end match;
1337 end addReplacement;
1338
1339 public function checkInlineType "
1340 Author: Frenkel TUD, 2010-05"
1341 input DAE.InlineType inIT;
1342 input Functiontuple fns;
1343 output Boolean outb;
1344 algorithm
1345 outb := match(inIT,fns)
1346 local
1347 DAE.InlineType it;
1348 list<DAE.InlineType> itlst;
1349 Boolean b;
1350 case (it,(_,itlst))
1351 algorithm
1352 1834860 b := listMember(it,itlst);
1353 then b;
1354 else false;
1355 end match;
1356 end checkInlineType;
1357
1358 // TODO: mahge: This needs to be rewritten completely.
1359 public function extendCrefRecords
1360 "extends crefs from records"
1361 input list<tuple<DAE.ComponentRef, DAE.Exp>> inArgmap;
1362 input HashTableCG.HashTable inCheckCr;
1363 output list<tuple<DAE.ComponentRef, DAE.Exp>> outArgmap;
1364 output HashTableCG.HashTable outCheckCr;
1365 algorithm
1366 (outArgmap,outCheckCr) := matchcontinue(inArgmap,inCheckCr)
1367 local
1368 HashTableCG.HashTable ht,ht1,ht2,ht3;
1369 list<tuple<DAE.ComponentRef, DAE.Exp>> res,res1,res2,new,new1;
1370 DAE.ComponentRef c,cref;
1371 DAE.Exp e;
1372 list<DAE.Var> varLst;
1373 list<DAE.Exp> expl;
1374 list<DAE.ComponentRef> crlst;
1375 list<tuple<DAE.ComponentRef,DAE.ComponentRef>> creftpllst;
1376 Absyn.Path rpath;
1377 105099 case ({},ht) then ({},ht);
1378 /* All elements of the record have correct type already. No cast needed. */
1379 case((c,(DAE.CAST(exp=e,ty=DAE.T_COMPLEX())))::res,ht)
1380 algorithm
1381 4 (new1,ht1) := extendCrefRecords((c,e)::res,ht);
1382 then (new1,ht1);
1383 case((c,e as (DAE.CREF(componentRef = cref,ty=DAE.T_COMPLEX(varLst=varLst))))::res,ht)
1384 algorithm
1385 14804 (res1,ht1) := extendCrefRecords(res,ht);
1386 14804 new := List.map2(varLst,extendCrefRecords1,c,cref);
1387 14804 (new1,ht2) := extendCrefRecords(new,ht1);
1388 14804 res2 := listAppend(new1,res1);
1389 29608 then ((c,e)::res2,ht2);
1390 /* cause of an error somewhere the type of the expression CREF is not equal to the componentreference type
1391 this case is needed. */
1392 case((c,e as (DAE.CREF(componentRef = cref)))::res,ht)
1393 algorithm
1394
1/2
✓ Branch 1 taken 84887 times.
✗ Branch 2 not taken.
84887 DAE.T_COMPLEX(varLst=varLst) := ComponentReference.crefLastType(cref);
1395 ✗ (res1,ht1) := extendCrefRecords(res,ht);
1396 ✗ new := List.map2(varLst,extendCrefRecords1,c,cref);
1397 ✗ (new1,ht2) := extendCrefRecords(new,ht1);
1398 ✗ res2 := listAppend(new1,res1);
1399 ✗ then ((c,e)::res2,ht2);
1400 // If the call is to a record constructor then "extend the cref and inline" them
1401 case((c,e as (DAE.CALL(expLst = expl,attr=DAE.CALL_ATTR(ty=DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(rpath), varLst=varLst)))))::res,ht)
1402 guard AbsynUtil.pathEqual(e.path,rpath)
1403 algorithm
1404 305 (res1,ht1) := extendCrefRecords(res,ht);
1405 305 crlst := List.map1(varLst,extendCrefRecords2,c);
1406 305 new := List.zip(crlst,expl);
1407 305 (new1,ht2) := extendCrefRecords(new,ht1);
1408 305 res2 := listAppend(new1,res1);
1409 610 then ((c,e)::res2,ht2);
1410 case((c,e as (DAE.RECORD(exps = expl,ty=DAE.T_COMPLEX(varLst=varLst))))::res,ht)
1411 algorithm
1412 27719 (res1,ht1) := extendCrefRecords(res,ht);
1413 27719 crlst := List.map1(varLst,extendCrefRecords2,c);
1414 27719 new := List.zip(crlst,expl);
1415 27719 (new1,ht2) := extendCrefRecords(new,ht1);
1416 27719 res2 := listAppend(new1,res1);
1417 55438 then ((c,e)::res2,ht2);
1418 case((c,e)::res,ht)
1419 algorithm
1420
2/2
✓ Branch 1 taken 179279 times.
✓ Branch 2 taken 5158 times.
184437 DAE.T_COMPLEX(varLst=varLst) := Expression.typeof(e);
1421 5158 crlst := List.map1(varLst,extendCrefRecords2,c);
1422 5158 creftpllst := List.map1(crlst,Util.makeTuple,c);
1423 5158 ht1 := List.fold(creftpllst,BaseHashTable.add,ht);
1424 5158 ht2 := getCheckCref(crlst,ht1);
1425 5158 (res1,ht3) := extendCrefRecords(res,ht2);
1426 10316 then ((c,e)::res1,ht3);
1427 case((c,e)::res,ht)
1428 algorithm
1429 179279 (res1,ht1) := extendCrefRecords(res,ht);
1430 358558 then ((c,e)::res1,ht1);
1431 end matchcontinue;
1432 end extendCrefRecords;
1433
1434 protected function getCheckCref
1435 input list<DAE.ComponentRef> inCrefs;
1436 input HashTableCG.HashTable inCheckCr;
1437 output HashTableCG.HashTable outCheckCr;
1438 algorithm
1439 outCheckCr := matchcontinue(inCrefs,inCheckCr)
1440 local
1441 HashTableCG.HashTable ht,ht1,ht2,ht3;
1442 list<DAE.ComponentRef> rest,crlst;
1443 DAE.ComponentRef cr;
1444 list<DAE.Var> varLst;
1445 list<tuple<DAE.ComponentRef,DAE.ComponentRef>> creftpllst;
1446 case ({},ht)
1447 then ht;
1448 case (cr::rest,ht)
1449 algorithm
1450
1/2
✓ Branch 1 taken 70927 times.
✗ Branch 2 not taken.
70927 DAE.T_COMPLEX(varLst=varLst) := ComponentReference.crefLastType(cr);
1451 ✗ crlst := List.map1(varLst,extendCrefRecords2,cr);
1452 ✗ ht1 := getCheckCref(crlst,ht);
1453 ✗ creftpllst := List.map1(crlst,Util.makeTuple,cr);
1454 ✗ ht2 := List.fold(creftpllst,BaseHashTable.add,ht1);
1455 ✗ ht3 := getCheckCref(rest,ht2);
1456 then
1457 ht3;
1458 case (_::rest,ht)
1459 algorithm
1460 70927 ht1 := getCheckCref(rest,ht);
1461 then
1462 ht1;
1463 end matchcontinue;
1464 end getCheckCref;
1465
1466 protected function extendCrefRecords1
1467 "helper for extendCrefRecords"
1468 input DAE.Var ev;
1469 input DAE.ComponentRef c;
1470 input DAE.ComponentRef e;
1471 output tuple<DAE.ComponentRef, DAE.Exp> outArg;
1472 algorithm
1473 outArg := matchcontinue ev
1474 local
1475 DAE.Type tp;
1476 String name;
1477 DAE.ComponentRef c1,e1;
1478 DAE.Exp exp;
1479
1480 case DAE.TYPES_VAR(name=name,ty=tp)
1481 algorithm
1482 37484 c1 := ComponentReference.crefPrependIdent(c,name,{},tp);
1483 37484 e1 := ComponentReference.crefPrependIdent(e,name,{},tp);
1484 37484 exp := Expression.makeCrefExp(e1,tp);
1485 37484 then ((c1,exp));
1486 else
1487 algorithm
1488 ✗ true := Flags.isSet(Flags.FAILTRACE);
1489 ✗ Debug.trace("Inline.extendCrefRecords1 failed\n");
1490 ✗ then
1491 fail();
1492 end matchcontinue;
1493 end extendCrefRecords1;
1494
1495 protected function extendCrefRecords2
1496 "helper for extendCrefRecords"
1497 input DAE.Var ev;
1498 input DAE.ComponentRef c;
1499 output DAE.ComponentRef outArg;
1500 algorithm
1501 outArg := matchcontinue ev
1502 local
1503 DAE.Type tp;
1504 String name;
1505 DAE.ComponentRef c1;
1506
1507 case DAE.TYPES_VAR(name=name,ty=tp)
1508 algorithm
1509 137532 c1 := ComponentReference.crefPrependIdent(c,name,{},tp);
1510 then c1;
1511 else
1512 algorithm
1513 ✗ true := Flags.isSet(Flags.FAILTRACE);
1514 ✗ Debug.trace("Inline.extendCrefRecords2 failed\n");
1515 ✗ then
1516 fail();
1517 end matchcontinue;
1518 end extendCrefRecords2;
1519
1520 public function getFunctionBody
1521 "returns the body of a function"
1522 input Absyn.Path p;
1523 input Functiontuple fns;
1524 output list<DAE.Element> outfn;
1525 output Option<SCode.Comment> oComment;
1526 algorithm
1527 (outfn,oComment) := matchcontinue fns
1528 local
1529 list<DAE.Element> body;
1530 AvlTreePathFunction.Tree ftree;
1531 Option<SCode.Comment> comment;
1532 case (SOME(ftree),_)
1533 algorithm
1534
8/12
✗ Branch 1 not taken.
✓ Branch 2 taken 102129 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102129 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 102126 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 102126 times.
✓ Branch 9 taken 21919 times.
✓ Branch 10 taken 80207 times.
✓ Branch 11 taken 80207 times.
✗ Branch 12 not taken.
158912 SOME(DAE.FUNCTION( functions = DAE.FUNCTION_DEF(body = body)::_,comment=comment)) := AvlTreePathFunction.get(ftree,p);
1535 then (body,comment);
1536 else
1537 algorithm
1538
2/2
✓ Branch 1 taken 93232 times.
✓ Branch 2 taken 16 times.
93248 true := Flags.isSet(Flags.FAILTRACE);
1539 16 Debug.traceln("Inline.getFunctionBody failed for function: " + AbsynUtil.pathString(p));
1540 // Error.addMessage(Error.INTERNAL_ERROR, {"Inline.getFunctionBody failed"});
1541 16 then
1542 fail();
1543 end matchcontinue;
1544 end getFunctionBody;
1545
1546
1547 public function getFunction
1548 "returns the function"
1549 input Absyn.Path p;
1550 input Functiontuple fns;
1551 output DAE.Function func;
1552 algorithm
1553 func := matchcontinue fns
1554 local
1555 AvlTreePathFunction.Tree ftree;
1556 case (SOME(ftree),_)
1557 algorithm
1558
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 15530 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15530 times.
15614 SOME(func) := AvlTreePathFunction.get(ftree,p);
1559 then func;
1560 else
1561 algorithm
1562
1/2
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
84 true := Flags.isSet(Flags.FAILTRACE);
1563 ✗ Debug.traceln("Inline.getFunction failed for function: " + AbsynUtil.pathString(p));
1564 ✗ then
1565 fail();
1566 end matchcontinue;
1567 end getFunction;
1568
1569 protected function getRhsExp
1570 "returns the right hand side of an assignment from a function"
1571 input list<DAE.Element> inElementList;
1572 output DAE.Exp outExp;
1573 algorithm
1574 outExp := match inElementList
1575 local
1576 list<DAE.Element> cdr;
1577 DAE.Exp res;
1578 case {}
1579 algorithm
1580 ✗ true := Flags.isSet(Flags.FAILTRACE);
1581 ✗ Debug.trace("Inline.getRhsExp failed - cannot inline such a function\n");
1582 ✗ then
1583 fail();
1584 case DAE.ALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS({DAE.STMT_ASSIGN(exp=res)})) :: _ then res;
1585 case DAE.ALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS({DAE.STMT_TUPLE_ASSIGN(exp=res)})):: _ then res;
1586 case DAE.ALGORITHM(algorithm_ = DAE.ALGORITHM_STMTS({DAE.STMT_ASSIGN_ARR(exp=res)})) :: _ then res;
1587 case _ :: cdr
1588 algorithm
1589 1180 res := getRhsExp(cdr);
1590 then
1591 res;
1592 end match;
1593 end getRhsExp;
1594
1595 protected function replaceArgsInExp
1596 "Replaces the function inputs in exp by the call's arguments, failing if
1597 that is not possible."
1598 input output DAE.Exp exp;
1599 input list<tuple<DAE.ComponentRef,DAE.Exp>> argmap;
1600 input HashTableCG.HashTable checkcr;
1601 algorithm
1602
2/2
✓ Branch 3 taken 171 times.
✓ Branch 4 taken 62082 times.
62253 (exp,(_,_,true,_)) := Expression.traverseExpBottomUp(exp,replaceArgs,(argmap,checkcr,true,newArgMemo()));
1603 end replaceArgsInExp;
1604
1605 public function newArgMemo
1606 output ArgMemo memo = UnorderedMap.new<DAE.Exp>(ComponentReferenceBasics.hashComponentRef, ComponentReferenceBasics.crefEqual);
1607 end newArgMemo;
1608
1609 protected function getArgReplacement
1610 "The simplified argument expression for cref. Crefs without subscripts or
1611 with constant indices give the same result each time, so it is memoized."
1612 input list<tuple<DAE.ComponentRef,DAE.Exp>> argmap;
1613 input DAE.ComponentRef cref;
1614 input ArgMemo memo;
1615 output DAE.Exp exp;
1616 protected
1617 Boolean cache = hasOnlyConstantIndices(cref);
1618 Option<DAE.Exp> oexp;
1619 algorithm
1620
2/2
✓ Branch 0 taken 853085 times.
✓ Branch 1 taken 56 times.
853141 if cache then
1621 853085 oexp := UnorderedMap.get(cref, memo);
1622
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 853085 times.
✓ Branch 2 taken 412702 times.
✓ Branch 3 taken 440383 times.
853085 if isSome(oexp) then
1623 412702 SOME(exp) := oexp;
1624 412702 return;
1625 end if;
1626 end if;
1627 440439 exp := getExpFromArgMap(argmap, cref);
1628 416067 (exp, _) := ExpressionSimplify.simplify(exp);
1629
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 416011 times.
416067 if cache then
1630 416011 UnorderedMap.add(cref, exp, memo);
1631 end if;
1632 end getArgReplacement;
1633
1634 protected function hasOnlyConstantIndices
1635 input DAE.ComponentRef cref;
1636 output Boolean b;
1637 algorithm
1638 b := match cref
1639 853141 case DAE.CREF_IDENT() then List.all(cref.subscriptLst, isConstantIndex);
1640
3/4
✓ Branch 1 taken 430736 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 430734 times.
430736 case DAE.CREF_QUAL() then List.all(cref.subscriptLst, isConstantIndex) and hasOnlyConstantIndices(cref.componentRef);
1641 else false;
1642 end match;
1643 end hasOnlyConstantIndices;
1644
1645 protected function isConstantIndex
1646 input DAE.Subscript sub;
1647 output Boolean b;
1648 algorithm
1649 b := match sub
1650 case DAE.INDEX(exp = DAE.ICONST()) then true;
1651 else false;
1652 end match;
1653 end isConstantIndex;
1654
1655 public function replaceArgs
1656 "finds DAE.CREF and replaces them with new exps if the cref is in the argmap"
1657 input DAE.Exp inExp;
1658 input ReplaceArgsTuple inTuple;
1659 output DAE.Exp outExp;
1660 output ReplaceArgsTuple outTuple;
1661 algorithm
1662 (outExp,outTuple) := matchcontinue (inExp,inTuple)
1663 local
1664 DAE.ComponentRef cref, firstCref;
1665 list<tuple<DAE.ComponentRef, DAE.Exp>> argmap;
1666 DAE.Exp e;
1667 Absyn.Path path;
1668 list<DAE.Exp> expLst;
1669 Boolean tuple_,b, isImpure, isFunctionPointerCall;
1670 DAE.Type ty,ty2;
1671 DAE.InlineType inlineType;
1672 DAE.TailCall tc;
1673 HashTableCG.HashTable checkcr;
1674 ArgMemo memo;
1675
1676 case (DAE.CREF(componentRef = cref),(argmap,_,true,memo))
1677 853141 then (getArgReplacement(argmap,cref,memo),inTuple);
1678
1679 case (DAE.CREF(componentRef = cref),(argmap,checkcr,true,memo))
1680 guard
1681 BaseHashTable.hasKey(ComponentReferenceBasics.crefFirstCref(cref),checkcr)
1682 ✗ then (inExp,(argmap,checkcr,false,memo));
1683
1684 case (DAE.CREF(componentRef = cref),(argmap,_,true,_))
1685 algorithm
1686 24372 firstCref := ComponentReferenceBasics.crefFirstCref(cref);
1687
2/2
✓ Branch 1 taken 192 times.
✓ Branch 2 taken 24180 times.
24372 {} := ComponentReferenceBasics.crefSubs(firstCref);
1688 24180 e := getExpFromArgMap(argmap,firstCref);
1689
2/2
✓ Branch 1 taken 23941 times.
✓ Branch 2 taken 23770 times.
47711 while not ComponentReference.crefIsIdent(cref) loop
1690 23941 cref := ComponentReference.crefRest(cref);
1691
2/2
✓ Branch 1 taken 171 times.
✓ Branch 2 taken 23770 times.
23941 {} := ComponentReferenceBasics.crefSubs(cref);
1692 23770 e := DAE.RSUB(e, -1, ComponentReferenceBasics.crefFirstIdent(cref), ComponentReference.crefType(cref));
1693 end while;
1694 then (e,inTuple);
1695
1696 case (DAE.CREF(componentRef = cref),(argmap,checkcr,true,memo))
1697 algorithm
1698 602 getExpFromArgMap(argmap,ComponentReference.crefStripSubs(ComponentReferenceBasics.crefFirstCref(cref)));
1699 // We have something like v[i].re and v is in the inputs... So we fail to inline.
1700 171 then (inExp,(argmap,checkcr,false,memo));
1701
1702 case (DAE.UNBOX(DAE.CALL(path,expLst,DAE.CALL_ATTR(_,tuple_,false,isImpure,_,inlineType,tc,_)),ty),(argmap,_,true,_))
1703 algorithm
1704 ✗ cref := ComponentReference.pathToCref(path);
1705 ✗ e as DAE.CREF(componentRef=cref,ty=ty2) := getExpFromArgMap(argmap,cref);
1706 ✗ path := ComponentReference.crefToPath(cref);
1707 ✗ expLst := List.map(expLst,Expression.unboxExp);
1708 ✗ b := Expression.isBuiltinFunctionReference(e);
1709 ✗ isFunctionPointerCall := Types.isFunctionReferenceVar(ty2);
1710 ✗ e := DAE.CALL(path,expLst,DAE.CALL_ATTR(ty,tuple_,b,isImpure,isFunctionPointerCall,inlineType,tc,DAE.NoReturn.RETURNS));
1711 ✗ (e,_) := ExpressionSimplify.simplify(e);
1712 then (e,inTuple);
1713
1714 case (e as DAE.UNBOX(DAE.CALL(path,_,DAE.CALL_ATTR(builtin=false)),_),(argmap,checkcr,true,memo))
1715 algorithm
1716 ✗ cref := ComponentReference.pathToCref(path);
1717 ✗ true := BaseHashTable.hasKey(cref,checkcr);
1718 ✗ then (e,(argmap,checkcr,false,memo));
1719
1720 // TODO: Use the inlineType of the function reference!
1721 case (DAE.CALL(path,expLst,DAE.CALL_ATTR(DAE.T_METATYPE(),tuple_,false,isImpure,_,_,tc,_)),(argmap,_,true,_))
1722 algorithm
1723 3 cref := ComponentReference.pathToCref(path);
1724
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 e as DAE.CREF(componentRef=cref,ty=ty) := getExpFromArgMap(argmap,cref);
1725 3 path := ComponentReference.crefToPath(cref);
1726 3 expLst := List.map(expLst,Expression.unboxExp);
1727 3 b := Expression.isBuiltinFunctionReference(e);
1728 3 (ty2,inlineType) := functionReferenceType(ty);
1729 3 isFunctionPointerCall := Types.isFunctionReferenceVar(ty2);
1730
4/8
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
12 e := DAE.CALL(path,expLst,DAE.CALL_ATTR(ty2,tuple_,b,isImpure,isFunctionPointerCall,inlineType,tc,DAE.NoReturn.RETURNS));
1731 3 e := boxIfUnboxedFunRef(e,ty);
1732 3 (e,_) := ExpressionSimplify.simplify(e);
1733 then (e,inTuple);
1734
1735 case (e as DAE.CALL(path,_,DAE.CALL_ATTR(ty=DAE.T_METATYPE(),builtin=false)),(argmap,checkcr,true,memo))
1736 algorithm
1737 ✗ cref := ComponentReference.pathToCref(path);
1738 ✗ true := BaseHashTable.hasKey(cref,checkcr);
1739 ✗ then (e,(argmap,checkcr,false,memo));
1740
1741 else (inExp,inTuple);
1742 end matchcontinue;
1743 end replaceArgs;
1744
1745 protected function boxIfUnboxedFunRef
1746 "Replacing a function pointer with a regular function means that you:
1747 (1) Need to unbox all inputs
1748 (2) Need to box the output if it was not done before
1749 This function handles (2)
1750 "
1751 input DAE.Exp iexp;
1752 input DAE.Type ty;
1753 output DAE.Exp outExp;
1754 algorithm
1755 outExp := match (iexp,ty)
1756 local
1757 DAE.Type t;
1758 DAE.Exp exp;
1759 case (exp,DAE.T_FUNCTION_REFERENCE_FUNC(functionType=DAE.T_FUNCTION(funcResultType=t)))
1760 algorithm
1761
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 exp := if Types.isBoxedType(t) then exp else DAE.BOX(exp);
1762 then exp;
1763 else iexp;
1764 end match;
1765 end boxIfUnboxedFunRef;
1766
1767 protected function functionReferenceType
1768 "Retrieves the ExpType that the call should have (this changes if the replacing
1769 function does not return a boxed value).
1770 We also return the inline type of the new call."
1771 input DAE.Type ty1;
1772 output DAE.Type ty2;
1773 output DAE.InlineType inlineType;
1774 algorithm
1775 (ty2,inlineType) := match ty1
1776 local
1777 DAE.Type ty;
1778 case DAE.T_FUNCTION_REFERENCE_FUNC(functionType=DAE.T_FUNCTION(functionAttributes=DAE.FUNCTION_ATTRIBUTES(inline=inlineType),funcResultType=ty))
1779 3 then (Types.simplifyType(ty),inlineType);
1780 else (ty1,DAE.NO_INLINE());
1781 end match;
1782 end functionReferenceType;
1783
1784 protected function getExpFromArgMap
1785 "returns the exp from the given argmap with the given key"
1786 input list<tuple<DAE.ComponentRef, DAE.Exp>> inArgMap;
1787 input DAE.ComponentRef inComponentRef;
1788 output DAE.Exp outExp;
1789 protected
1790 tuple<DAE.ComponentRef, DAE.Exp> arg;
1791 list<DAE.Subscript> subs;
1792 DAE.ComponentRef key,cref;
1793 DAE.Exp exp;
1794 algorithm
1795 465224 subs := ComponentReferenceBasics.crefSubs(inComponentRef);
1796 465224 key := ComponentReference.crefStripSubs(inComponentRef);
1797
1798
2/2
✓ Branch 0 taken 1264597 times.
✓ Branch 1 taken 25042 times.
1289639 for arg in inArgMap loop
1799 1264597 (cref, exp) := arg;
1800
2/2
✓ Branch 1 taken 440182 times.
✓ Branch 2 taken 824415 times.
1264597 if ComponentReferenceBasics.crefEqual(cref,key) then
1801 try
1802 440182 outExp := Expression.applyExpSubscripts(exp,subs);
1803 else
1804 ✗ continue;
1805 end try;
1806 440182 return ;
1807 end if;
1808 end for;
1809
1810
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25042 times.
25042 if Flags.isSet(Flags.FAILTRACE) then
1811 ✗ Debug.traceln("Inline.getExpFromArgMap failed with empty argmap and cref: " + ComponentReferenceBasics.printComponentRefStr(inComponentRef));
1812 end if;
1813 25042 fail();
1814
1815 end getExpFromArgMap;
1816
1817 protected function getInputCrefs
1818 "returns the crefs of vars that are inputs, wild if not input"
1819 input DAE.Element inElement;
1820 output DAE.ComponentRef outComponentRef;
1821 algorithm
1822 outComponentRef := match inElement
1823 local
1824 DAE.ComponentRef cref;
1825 case DAE.VAR(componentRef=cref,direction=DAE.INPUT()) then cref;
1826 else DAE.WILD();
1827 end match;
1828 end getInputCrefs;
1829
1830 protected function removeWilds
1831 "returns false if the given cref is a wild"
1832 input DAE.ComponentRef inComponentRef;
1833 output Boolean outBoolean;
1834 algorithm
1835 outBoolean := match inComponentRef
1836 case DAE.WILD() then false;
1837 else true;
1838 end match;
1839 end removeWilds;
1840
1841 public function printInlineTypeStr
1842 "Print what kind of inline we have"
1843 input DAE.InlineType it;
1844 output String str;
1845 algorithm
1846 str := match it
1847 case DAE.NO_INLINE() then "No inline";
1848 case DAE.AFTER_INDEX_RED_INLINE() then "Inline after index reduction";
1849 case DAE.EARLY_INLINE() then "Inline as soon as possible";
1850 case DAE.BUILTIN_EARLY_INLINE() then "Inline as soon as possible, even if inlining is globally disabled";
1851 case DAE.NORM_INLINE() then "Inline before index reduction";
1852 case DAE.DEFAULT_INLINE() then "Inline if necessary";
1853 end match;
1854 end printInlineTypeStr;
1855
1856 public function simplifyAndInlineEquationExp "
1857 Takes a residual or equality equation, then
1858 simplifies, inlines and simplifies again
1859 "
1860 input DAE.EquationExp inExp;
1861 input Functiontuple fns;
1862 input DAE.ElementSource inSource;
1863 output DAE.EquationExp exp;
1864 output DAE.ElementSource source;
1865 algorithm
1866 ✗ (exp,source) := ExpressionSimplify.simplifyAddSymbolicOperation(inExp,inSource);
1867 ✗ (exp,source) := inlineEquationExp(exp,function inlineCall(fns=fns),source);
1868 end simplifyAndInlineEquationExp;
1869
1870 public function simplifyAndForceInlineEquationExp "
1871 Takes a residual or equality equation, then
1872 simplifies, inlines and simplifies again
1873 "
1874 input DAE.EquationExp inExp;
1875 input Functiontuple fns;
1876 input DAE.ElementSource inSource;
1877 output DAE.EquationExp exp;
1878 output DAE.ElementSource source;
1879 algorithm
1880 3050 (exp,source) := ExpressionSimplify.simplifyAddSymbolicOperation(inExp,inSource);
1881 3050 (exp,source) := inlineEquationExp(exp,function forceInlineCall(fns=fns, visitedPaths=AvlSetPath.Tree.EMPTY()),source);
1882 end simplifyAndForceInlineEquationExp;
1883
1884 public function inlineEquationExp "
1885 Takes a residual or equality equation, then
1886 simplifies, inlines and simplifies again
1887 "
1888 input DAE.EquationExp inExp;
1889 input Func fn;
1890 input DAE.ElementSource inSource;
1891 output DAE.EquationExp outExp;
1892 output DAE.ElementSource source;
1893 partial function Func
1894 input DAE.Exp inExp;
1895 input list<DAE.Statement> inTuple;
1896 output DAE.Exp outExp;
1897 output list<DAE.Statement> outTuple;
1898 end Func;
1899 type Functiontuple = tuple<Option<AvlTreePathFunction.Tree>,list<DAE.InlineType>>;
1900 algorithm
1901 (outExp,source) := match inExp
1902 local
1903 Boolean changed;
1904 DAE.Exp e,e_1,e1,e1_1,e2,e2_1;
1905 DAE.EquationExp eq2;
1906 case DAE.PARTIAL_EQUATION(e)
1907 algorithm
1908 ✗ (e_1,_) := Expression.traverseExpBottomUp(e,fn,{});
1909 ✗ changed := not referenceEq(e, e_1);
1910 ✗ eq2 := DAE.PARTIAL_EQUATION(e_1);
1911 ✗ source := ElementSource.condAddSymbolicTransformation(changed,inSource,DAE.OP_INLINE(inExp,eq2));
1912 ✗ (eq2,source) := ExpressionSimplify.condSimplifyAddSymbolicOperation(changed, eq2, source);
1913 then (eq2,source);
1914 case DAE.RESIDUAL_EXP(e)
1915 algorithm
1916 ✗ (e_1,_) := Expression.traverseExpBottomUp(e,fn,{});
1917 ✗ changed := not referenceEq(e, e_1);
1918 ✗ eq2 := DAE.RESIDUAL_EXP(e_1);
1919 ✗ source := ElementSource.condAddSymbolicTransformation(changed,inSource,DAE.OP_INLINE(inExp,eq2));
1920 ✗ (eq2,source) := ExpressionSimplify.condSimplifyAddSymbolicOperation(changed, eq2, source);
1921 then (eq2,source);
1922 case DAE.EQUALITY_EXPS(e1,e2)
1923 algorithm
1924 3050 (e1_1,_) := Expression.traverseExpBottomUp(e1,fn,{});
1925 3050 (e2_1,_) := Expression.traverseExpBottomUp(e2,fn,{});
1926 3050 changed := not (referenceEq(e1, e1_1) and referenceEq(e2, e2_1));
1927 3050 eq2 := DAE.EQUALITY_EXPS(e1_1,e2_1);
1928 3050 source := ElementSource.condAddSymbolicTransformation(changed,inSource,DAE.OP_INLINE(inExp,eq2));
1929 3050 (eq2,source) := ExpressionSimplify.condSimplifyAddSymbolicOperation(changed, eq2, source);
1930 then (eq2,source);
1931 else
1932 algorithm
1933 ✗ Error.addMessage(Error.INTERNAL_ERROR, {"Inline.inlineEquationExp failed"});
1934 ✗ then fail();
1935 end match;
1936 end inlineEquationExp;
1937
1938 protected function getReplacementCheckComplex
1939 input VarTransform.VariableReplacements repl;
1940 input DAE.ComponentRef cr;
1941 input DAE.Type ty;
1942 output DAE.Exp exp;
1943 algorithm
1944 exp := matchcontinue ty
1945 local
1946 list<DAE.Var> vars;
1947 list<DAE.ComponentRef> crs;
1948 list<DAE.Exp> exps;
1949 Absyn.Path path;
1950 41790 case _ then VarTransform.getReplacement(repl,cr);
1951 case DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(path),varLst=vars)
1952 algorithm
1953 ✗ crs := List.map1(List.map(vars,TypesDump.getVarName),ComponentReference.appendStringCref,cr);
1954 ✗ exps := List.map1r(crs, VarTransform.getReplacement, repl);
1955 ✗ then DAE.CALL(path,exps,DAE.CALL_ATTR(ty,false,false,false,false,DAE.NO_INLINE(),DAE.NO_TAIL(),DAE.NoReturn.RETURNS));
1956 end matchcontinue;
1957
1958 end getReplacementCheckComplex;
1959
1960 protected function getInlineHashTableVarTransform
1961 output HashTableCG.HashTable ht;
1962 output VarTransform.VariableReplacements repl;
1963 protected
1964 Option<tuple<HashTableCG.HashTable,VarTransform.VariableReplacements>> opt;
1965 HashTable2.HashTable regRepl;
1966 HashTable3.HashTable invRepl;
1967 algorithm
1968 121885 opt := getGlobalRoot(Global.inlineHashTable);
1969 (ht,repl) := match opt
1970 case SOME((ht,repl as VarTransform.REPLACEMENTS(regRepl,invRepl)))
1971 algorithm
1972 // Always stored with n=0, etc with the first global root
1973 121530 BaseHashTable.clearAssumeNoDelete(ht);
1974 121530 BaseHashTable.clearAssumeNoDelete(regRepl);
1975 121530 BaseHashTable.clearAssumeNoDelete(invRepl);
1976 then (ht,repl);
1977 else
1978 algorithm
1979 355 ht := HashTableCG.emptyHashTable();
1980 355 repl := VarTransform.emptyReplacements();
1981 710 setGlobalRoot(Global.inlineHashTable, SOME((ht,repl)));
1982 then (ht,repl);
1983 end match;
1984 end getInlineHashTableVarTransform;
1985
1986 annotation(__OpenModelica_Interface="frontend_base");
1987 end Inline;
1988