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 |