From 1bbb35e1cd95e220bb997f8e351cec0942564c4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Wed, 13 Dec 2017 15:28:26 +0100 Subject: [PATCH 1/5] Add support for inline of some if-statements If-statements that look like if-expressions can now be inlined. This fixes an issue reported in ticket:4423. --- Compiler/FrontEnd/DAEDump.mo | 2 +- Compiler/FrontEnd/Inline.mo | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Compiler/FrontEnd/DAEDump.mo b/Compiler/FrontEnd/DAEDump.mo index 1927fdddcb..e2c6887602 100644 --- a/Compiler/FrontEnd/DAEDump.mo +++ b/Compiler/FrontEnd/DAEDump.mo @@ -1790,7 +1790,7 @@ public function ppStmtListStr " Helper function to pp_stmt_str " input list inAlgorithmStatementLst; - input Integer inInteger; + input Integer inInteger=0; output String outString; algorithm outString:= diff --git a/Compiler/FrontEnd/Inline.mo b/Compiler/FrontEnd/Inline.mo index 06f9198f2c..05bda01c97 100644 --- a/Compiler/FrontEnd/Inline.mo +++ b/Compiler/FrontEnd/Inline.mo @@ -1016,7 +1016,7 @@ algorithm local list stmts; VarTransform.VariableReplacements repl; - DAE.ComponentRef cr; + DAE.ComponentRef cr, cr1, cr2; DAE.ElementSource source; DAE.Exp exp, exp1, exp2; DAE.Statement stmt; @@ -1053,6 +1053,31 @@ algorithm (repl,assertStmts) = mergeFunctionBody(stmts,iRepl,stmt::assertStmtsIn); then (repl,assertStmts); + // if a then x := b; else x := c; end if; => x := if a then b else c; + case (DAE.STMT_IF(exp = exp, + statementLst = {DAE.STMT_ASSIGN(exp1 = DAE.CREF(componentRef = cr1), exp = exp1)}, + else_=DAE.ELSE(statementLst={DAE.STMT_ASSIGN(exp1 = DAE.CREF(componentRef = cr2), exp = exp2)}))::stmts,_,_) + guard ComponentReference.crefEqual(cr1, cr2) + equation + (exp,_) = VarTransform.replaceExp(exp,iRepl,NONE()); + (exp1,_) = VarTransform.replaceExp(exp1,iRepl,NONE()); + (exp2,_) = VarTransform.replaceExp(exp2,iRepl,NONE()); + repl = VarTransform.addReplacementNoTransitive(iRepl,cr1,DAE.IFEXP(exp,exp1,exp2)); + (repl,assertStmts) = mergeFunctionBody(stmts,repl,assertStmtsIn); + then (repl,assertStmts); + + case (DAE.STMT_IF(exp = exp, + statementLst = {DAE.STMT_ASSIGN_ARR(lhs = DAE.CREF(componentRef = cr1), exp = exp1)}, + else_=DAE.ELSE(statementLst={DAE.STMT_ASSIGN_ARR(lhs = DAE.CREF(componentRef = cr2), exp = exp2)}))::stmts,_,_) + guard ComponentReference.crefEqual(cr1, cr2) + equation + (exp,_) = VarTransform.replaceExp(exp,iRepl,NONE()); + (exp1,_) = VarTransform.replaceExp(exp1,iRepl,NONE()); + (exp2,_) = VarTransform.replaceExp(exp2,iRepl,NONE()); + repl = VarTransform.addReplacementNoTransitive(iRepl,cr1,DAE.IFEXP(exp,exp1,exp2)); + (repl,assertStmts) = mergeFunctionBody(stmts,repl,assertStmtsIn); + then (repl,assertStmts); + end match; end mergeFunctionBody; From 72bbb4f813812b93bd1a4c088a5fda40a52918db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 15 Dec 2017 08:55:54 +0100 Subject: [PATCH 2/5] Handle inline where inputs are record fun-calls Use DAE.RSUB() to handle general expressions. When doing inline of a function call, we can use DAE.RSUB instead of failing; previously we only handled component references passed to the call. Also added code generation and simplifications for DAE.RSUB since it was only used for MetaModelica previously. This fixes some of the issues raised in ticket:4423. --- Compiler/FrontEnd/ExpressionSimplify.mo | 14 ++++++++++++++ Compiler/FrontEnd/Inline.mo | 14 +++++++++++++- Compiler/Template/CodegenCFunctions.tpl | 4 ++++ Compiler/Template/CodegenCppCommon.tpl | 12 ++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/Compiler/FrontEnd/ExpressionSimplify.mo b/Compiler/FrontEnd/ExpressionSimplify.mo index b3ec292dff..57a2bbf3d1 100644 --- a/Compiler/FrontEnd/ExpressionSimplify.mo +++ b/Compiler/FrontEnd/ExpressionSimplify.mo @@ -282,6 +282,8 @@ algorithm case (DAE.CALL(),_) then (simplifyCall(inExp),options); + case (DAE.RSUB(),_) then (simplifyRSub(inExp),options); + case (DAE.MATCHEXPRESSION(),_) then (simplifyMatch(inExp),options); case (DAE.UNBOX(),_) then (simplifyUnbox(inExp),options); case (DAE.BOX(),_) then (simplifyUnbox(inExp),options); @@ -302,6 +304,18 @@ algorithm end match; end simplifyWork; +protected function simplifyRSub + input output DAE.Exp e; +algorithm + e := match e + local + DAE.ComponentRef cr; + case (DAE.RSUB(exp=DAE.CREF(componentRef=cr), ix=-1)) + then DAE.CREF(ComponentReference.joinCrefs(cr, ComponentReference.makeCrefIdent(e.fieldName, e.ty, {})), e.ty); + else e; + end match; +end simplifyRSub; + protected function simplifyAsubExp input DAE.Exp origExp; input DAE.Exp inExp; diff --git a/Compiler/FrontEnd/Inline.mo b/Compiler/FrontEnd/Inline.mo index 05bda01c97..1bdb37e26c 100644 --- a/Compiler/FrontEnd/Inline.mo +++ b/Compiler/FrontEnd/Inline.mo @@ -1424,7 +1424,7 @@ public function replaceArgs algorithm (outExp,outTuple) := matchcontinue (inExp,inTuple) local - DAE.ComponentRef cref; + DAE.ComponentRef cref, firstCref; list> argmap; DAE.Exp e; Absyn.Path path; @@ -1447,6 +1447,18 @@ algorithm BaseHashTable.hasKey(ComponentReference.crefFirstCref(cref),checkcr) then (inExp,(argmap,checkcr,false)); + case (DAE.CREF(componentRef = cref),(argmap,checkcr,true)) + algorithm + firstCref := ComponentReference.crefFirstCref(cref); + {} := ComponentReference.crefSubs(firstCref); + e := getExpFromArgMap(argmap,firstCref); + while not ComponentReference.crefIsIdent(cref) loop + cref := ComponentReference.crefRest(cref); + {} := ComponentReference.crefSubs(cref); + e := DAE.RSUB(e, -1, ComponentReference.crefFirstIdent(cref), ComponentReference.crefType(cref)); + end while; + then (e,inTuple); + case (DAE.CREF(componentRef = cref),(argmap,checkcr,true)) equation getExpFromArgMap(argmap,ComponentReference.crefStripSubs(ComponentReference.crefFirstCref(cref))); diff --git a/Compiler/Template/CodegenCFunctions.tpl b/Compiler/Template/CodegenCFunctions.tpl index db313ebdfa..b36b18f44b 100644 --- a/Compiler/Template/CodegenCFunctions.tpl +++ b/Compiler/Template/CodegenCFunctions.tpl @@ -3699,6 +3699,7 @@ template expTypeFromExpFlag(Exp exp, Integer flag) case e as CONS(__) case e as LIST(__) case e as SIZE(__) then expTypeFlag(typeof(e), flag) + case c as RSUB(ix=-1) then expTypeFlag(c.ty, flag) case META_TUPLE(__) case META_OPTION(__) @@ -6246,6 +6247,9 @@ template daeExpRsub(Exp inExp, Context context, Text &preExp, "Generates code for an tsub expression." ::= match inExp + case RSUB(ix=-1) then + let res = daeExp(exp, context, &preExp, &varDecls, &auxFunction) + '<%res%>._<%fieldName%>' case RSUB(__) then let res = daeExp(exp, context, &preExp, &varDecls, &auxFunction) let offset = intAdd(ix,1) // 1-based diff --git a/Compiler/Template/CodegenCppCommon.tpl b/Compiler/Template/CodegenCppCommon.tpl index b7e83e63b1..f7e21c78c9 100644 --- a/Compiler/Template/CodegenCppCommon.tpl +++ b/Compiler/Template/CodegenCppCommon.tpl @@ -973,10 +973,22 @@ template daeExp(Exp exp, Context context, Text &preExp /*BUFP*/, Text &varDecls case e as PARTEVALFUNCTION(__)then daeExpPartEvalFunction(e, context, &preExp, &varDecls, simCode , &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation) case e as BOX(__) then daeExpBox(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation) case e as UNBOX(__) then daeExpUnbox(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation) + case e as RSUB(__) then daeExpRSub(e, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation) else error(sourceInfo(), 'Unknown exp:<%ExpressionDumpTpl.dumpExp(exp,"\"")%>') end daeExp; +template daeExpRSub(Exp exp, Context context, Text &preExp, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, + Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation) + "Generates code for an tsub expression." +::= + match exp + case RSUB(ix=-1) then + let res = daeExp(exp, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation) + '<%res%>.<%fieldName%>_' + case RSUB(__) then + error(sourceInfo(), '<%ExpressionDumpTpl.dumpExp(exp,"\"")%>: failed') +end daeExpRSub; template daeExpRange(Exp exp, Context context, Text &preExp, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation) From 50fb95bed541a4ce2fe1fee8a0a7a78b5495b319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 19 Dec 2017 06:32:13 +0100 Subject: [PATCH 3/5] Fix for DAE.RSUB with Expression.factorsWork --- Compiler/BackEnd/ExpressionSolve.mo | 6 +- Compiler/FrontEnd/Expression.mo | 174 +++++++--------------------- 2 files changed, 47 insertions(+), 133 deletions(-) diff --git a/Compiler/BackEnd/ExpressionSolve.mo b/Compiler/BackEnd/ExpressionSolve.mo index 137fa1b414..ada1de6322 100644 --- a/Compiler/BackEnd/ExpressionSolve.mo +++ b/Compiler/BackEnd/ExpressionSolve.mo @@ -129,7 +129,6 @@ algorithm varexp := Expression.expDer(varexp); cr := ComponentReference.crefPrefixDer(cr); end if; - if (Types.isIntegerOrRealOrSubTypeOfEither(Expression.typeof(e1)) and Types.isIntegerOrRealOrSubTypeOfEither(Expression.typeof(e2))) then (e1, e2) := preprocessingSolve(e1, e2, varexp, SOME(shared.functionTree), NONE(), 0, false); end if; @@ -915,7 +914,6 @@ algorithm (factorWithX1, factorWithoutX1) := List.split1OnTrue(f1, expHasCref, inExp3); pWithX1 := makeProductLstSort(factorWithX1); pWithoutX1 := makeProductLstSort(factorWithoutX1); - f2 := Expression.expandFactors(inExp2); (factorWithX2, factorWithoutX2) := List.split1OnTrue(f2, expHasCref, inExp3); (pWithX2,_) := ExpressionSimplify.simplify1(makeProductLstSort(factorWithX2)); @@ -989,7 +987,7 @@ algorithm if expand then (cr, b) := Expression.expOrDerCref(inExp3); if b then - (lhs, rhs) := Expression.allTermsForCref(inExp1, cr, Expression.Expression.expHasDerCref); + (lhs, rhs) := Expression.allTermsForCref(inExp1, cr, Expression.expHasDerCref); else (lhs, rhs) := Expression.allTermsForCref(inExp1, cr, Expression.expHasCrefNoPreOrStart); end if; @@ -1748,7 +1746,7 @@ algorithm false = hasOnlyFactors(inExp1,inExp2); e = Expression.makeDiff(inExp1,inExp2); (e,_) = ExpressionSimplify.simplify1(e); - //print("\n\ne: ");print(ExpressionDump.printExpStr(e)); + //print("\ne: ");print(ExpressionDump.printExpStr(e)); dere = Differentiate.differentiateExpSolve(e, cr, functions); //print("\nder(e): ");print(ExpressionDump.printExpStr(dere)); (dere,_) = ExpressionSimplify.simplify(dere); diff --git a/Compiler/FrontEnd/Expression.mo b/Compiler/FrontEnd/Expression.mo index 9a66029c87..48325089fc 100644 --- a/Compiler/FrontEnd/Expression.mo +++ b/Compiler/FrontEnd/Expression.mo @@ -2936,123 +2936,35 @@ public function factors algorithm // TODO: Remove this listReverse as it is pointless. // It transforms a*b to b*a, but the testsuite expects this :( - outExpLst := listReverse(factorsWork(inExp,{},false,false)); + outExpLst := listReverse(factorsWork(inExp,{},false)); end factors; protected function factorsWork "Returns the factors of the expression if any as a list of expressions" input DAE.Exp inExp; - input list inAcc; - input Boolean noFactors "Decides if the default is the empty list or not"; + input output list acc; input Boolean doInverseFactors "Decides if a factor e should be 1/e instead"; - output list outExpLst; algorithm - outExpLst := match (inExp,inAcc,noFactors,doInverseFactors) + acc := match inExp local DAE.Exp e1,e2,e; - ComponentRef cr; - Real r; - Boolean b; - list acc; - case (DAE.BINARY(exp1 = e1,operator = DAE.MUL(),exp2 = e2),acc,_,_) - equation - acc = factorsWork(e1,acc,true,doInverseFactors); - acc = factorsWork(e2,acc,true,doInverseFactors); - then acc; - case (DAE.BINARY(exp1 = e1,operator = DAE.DIV(ty = DAE.T_REAL()),exp2 = e2),acc,_,_) - equation - acc = factorsWork(e1,acc,true,doInverseFactors); - acc = factorsWork(e2,acc,true,not doInverseFactors); + case DAE.BINARY(exp1 = e1,operator = DAE.MUL(),exp2 = e2) + algorithm + acc := factorsWork(e1,acc,doInverseFactors); + acc := factorsWork(e2,acc,doInverseFactors); then acc; - case (DAE.CREF(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.BINARY(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.ICONST(integer = 1),acc,_,_) + case DAE.BINARY(exp1 = e1,operator = DAE.DIV(ty = DAE.T_REAL()),exp2 = e2) + algorithm + acc := factorsWork(e1,acc,doInverseFactors); + acc := factorsWork(e2,acc,not doInverseFactors); then acc; - case (DAE.ICONST(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.RCONST(real = r),acc,_,_) - equation - b = not realEq(r,1.0); - e = if b and doInverseFactors then inverseFactors(inExp) else inExp; - acc = List.consOnTrue(b, e, acc); + case DAE.ICONST(integer = 1) then acc; - case (DAE.SCONST(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.UNARY(),acc,_,_) // factor(-(x*y)) is -(x*y) ?? - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.LUNARY(),acc,_,_) - then inExp::acc; - case (DAE.IFEXP(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.CALL(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.RECORD(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.RECORD(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.PARTEVALFUNCTION(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.ARRAY(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.MATRIX(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.RANGE(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.CAST(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.ASUB(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.TSUB(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.SIZE(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (DAE.REDUCTION(),acc,_,_) - equation - e = if doInverseFactors then inverseFactors(inExp) else inExp; - then e::acc; - case (e,acc,true,_) - equation - e = if doInverseFactors then inverseFactors(e) else e; - then e::acc; - case (_,acc,false,_) + case DAE.RCONST(real = 1.0) then acc; + // case DAE.UNARY() // factor(-(x*y)) is -(x*y) ?? + else (if doInverseFactors then inverseFactors(inExp) else inExp) :: acc; end match; end factorsWork; @@ -3107,53 +3019,51 @@ algorithm // TODO: Remove this listReverse as it is pointless. // It transforms a*b to b*a, but the testsuite expects this :( // issue with expEqual(a*b,b*a) return false - outExpLst := listReverse(expandFactorsWork(inExp,{},false,false)); + outExpLst := listReverse(expandFactorsWork(inExp,{},false)); end expandFactors; protected function expandFactorsWork "Returns the factors of the expression if any as a list of expressions" input DAE.Exp inExp; - input list inAcc; - input Boolean noFactors "Decides if the default is the empty list or not"; + input output list acc; input Boolean doInverseFactors "Decides if a factor e should be 1/e instead"; - output list outExpLst; algorithm - outExpLst := match (inExp,inAcc,noFactors,doInverseFactors) + acc := match inExp local DAE.Exp e1,e2,e3,e; Type tp; - list acc, pow_acc, pow_acc2; + list pow_acc, pow_acc2; // (x*y)^n = x^n*y^n - case (DAE.BINARY(DAE.BINARY(e1,DAE.MUL(),e2), DAE.POW(), e3),acc,_,_) + case DAE.BINARY(DAE.BINARY(e1,DAE.MUL(),e2), DAE.POW(), e3) equation - pow_acc = expandFactorsWork(e1,{},noFactors,doInverseFactors); + pow_acc = expandFactorsWork(e1,{},doInverseFactors); pow_acc = expPowLst(pow_acc, e3); - pow_acc2 = expandFactorsWork(e2,{},noFactors,doInverseFactors); + pow_acc2 = expandFactorsWork(e2,{},doInverseFactors); pow_acc2 = expPowLst(pow_acc2, e3); acc = listAppend(pow_acc, acc); acc = listAppend(pow_acc2, acc); then acc; // (x/y)^n = x^n*y^(-n) - case (DAE.BINARY(DAE.BINARY(e1,DAE.DIV(),e2), DAE.POW(), e3),acc,_,_) + case DAE.BINARY(DAE.BINARY(e1,DAE.DIV(),e2), DAE.POW(), e3) equation - pow_acc = expandFactorsWork(e1,{},noFactors,doInverseFactors); + pow_acc = expandFactorsWork(e1,{},doInverseFactors); pow_acc = expPowLst(pow_acc, e3); - pow_acc2 = expandFactorsWork(e2,{},noFactors,doInverseFactors); + pow_acc2 = expandFactorsWork(e2,{},doInverseFactors); pow_acc2 = expPowLst(pow_acc2, negate(e3)); acc = listAppend(pow_acc, acc); acc = listAppend(pow_acc2, acc); then acc; // (x^n)^m = x^(n*m) - case (DAE.BINARY(DAE.BINARY(e1,DAE.POW(),e2), DAE.POW(), e3),acc,_,_) + case DAE.BINARY(DAE.BINARY(e1,DAE.POW(),e2), DAE.POW(), e3) equation e = expMul(e2,e3); - pow_acc = expandFactorsWork(e1,{},noFactors,doInverseFactors); + pow_acc = expandFactorsWork(e1,{},doInverseFactors); pow_acc = expPowLst(pow_acc, e); acc = listAppend(pow_acc, acc); @@ -3165,23 +3075,23 @@ algorithm // abs(x/y) = abs(x)/abs(y); // -(x) = -1*x - case(DAE.UNARY(DAE.UMINUS(tp),e1),acc,_,_) + case DAE.UNARY(DAE.UMINUS(tp),e1) equation e = makeConstOne(tp); - acc = expandFactorsWork(e1,acc,true,doInverseFactors); + acc = expandFactorsWork(e1,acc,doInverseFactors); e = negate(e); then e::acc; - case(DAE.UNARY(DAE.UMINUS_ARR(tp),e1),acc,_,_) + case DAE.UNARY(DAE.UMINUS_ARR(tp),e1) equation e = makeConstOne(tp); - acc = expandFactorsWork(e1,acc,true,doInverseFactors); + acc = expandFactorsWork(e1,acc,doInverseFactors); e = negate(e); then e::acc; else equation - acc = factorsWork(inExp,inAcc,noFactors,doInverseFactors); - then expandFactorsWork2(acc, noFactors, doInverseFactors); + acc = factorsWork(inExp,acc,doInverseFactors); + then expandFactorsWork2(acc,doInverseFactors); end match; @@ -3189,7 +3099,6 @@ end expandFactorsWork; protected function expandFactorsWork2 input list inAcc; - input Boolean noFactors "Decides if the default is the empty list or not"; input Boolean doInverseFactors "Decides if a factor e should be 1/e instead"; output list outExpLst = {}; protected @@ -3198,11 +3107,11 @@ algorithm for elem in inAcc loop tmpExpLst := match(elem) - case(DAE.BINARY(DAE.BINARY(_,DAE.DIV(),_), DAE.POW(), _)) then expandFactorsWork(elem,{},noFactors,doInverseFactors); - case(DAE.BINARY(DAE.BINARY(_,DAE.MUL(),_), DAE.POW(), _)) then expandFactorsWork(elem,{},noFactors,doInverseFactors); - case(DAE.BINARY(DAE.BINARY(_,DAE.POW(),_), DAE.POW(), _)) then expandFactorsWork(elem,{},noFactors,doInverseFactors); - case(DAE.UNARY(DAE.UMINUS(),_)) then expandFactorsWork(elem,{},noFactors,doInverseFactors); - case(DAE.UNARY(DAE.UMINUS_ARR(),_)) then expandFactorsWork(elem,{},noFactors,doInverseFactors); + case(DAE.BINARY(DAE.BINARY(_,DAE.DIV(),_), DAE.POW(), _)) then expandFactorsWork(elem,{},doInverseFactors); + case(DAE.BINARY(DAE.BINARY(_,DAE.MUL(),_), DAE.POW(), _)) then expandFactorsWork(elem,{},doInverseFactors); + case(DAE.BINARY(DAE.BINARY(_,DAE.POW(),_), DAE.POW(), _)) then expandFactorsWork(elem,{},doInverseFactors); + case(DAE.UNARY(DAE.UMINUS(),_)) then expandFactorsWork(elem,{},doInverseFactors); + case(DAE.UNARY(DAE.UMINUS_ARR(),_)) then expandFactorsWork(elem,{},doInverseFactors); else {elem}; end match; outExpLst := listAppend(tmpExpLst, outExpLst); @@ -7112,6 +7021,13 @@ algorithm then (DAE.ASUB(e1, expl), arg); + case e1 as DAE.RSUB() + equation + (e2, arg) = traverseExpBidir(e1.exp, inEnterFunc, inExitFunc, inArg); + e1.exp = e2; + then + (e1, arg); + case DAE.TSUB(e1, i, ty) equation (e1, arg) = traverseExpBidir(e1, inEnterFunc, inExitFunc, inArg); From 3825b2302c775a698c64ec6e57266d1a538e8e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 19 Dec 2017 08:58:27 +0100 Subject: [PATCH 4/5] Add differentiation of DAE.RSUB --- Compiler/BackEnd/Differentiate.mo | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Compiler/BackEnd/Differentiate.mo b/Compiler/BackEnd/Differentiate.mo index 6898fe1f53..03c6458ed1 100644 --- a/Compiler/BackEnd/Differentiate.mo +++ b/Compiler/BackEnd/Differentiate.mo @@ -685,21 +685,30 @@ algorithm then (res, functionTree); // differentiate tsub - case DAE.TSUB(exp=e1, ix=i, ty=tp) equation - //se1 = ExpressionDump.printExpStr(inExp); - //print("\nExp-TSUB\nDifferentiate exp: " + se1); + case DAE.TSUB(exp=e1, ix=i, ty=tp) + algorithm + (res1, functionTree) := differentiateExp(e1, inDiffwrtCref, inInputData, inDiffType, inFunctionTree, maxIter-1); - (res1, functionTree) = differentiateExp(e1, inDiffwrtCref, inInputData, inDiffType, inFunctionTree, maxIter-1); + if not referenceEq(e1, res1) then + res := DAE.TSUB(res1, i, tp); + (res,_) := ExpressionSimplify.simplify1(res); + else + res := inExp; + end if; + then (res, functionTree); - res = DAE.TSUB(res1, i, tp); - (res,_) = ExpressionSimplify.simplify1(res); - //(res,_) = ExpressionSimplify.simplify(res); - //se1 = ExpressionDump.printExpStr(res); - //print("\nresults to exp: " + se1); - then (res, functionTree); + // differentiate tsub + case e1 as DAE.RSUB() + algorithm + (res1, functionTree) := differentiateExp(e1.exp, inDiffwrtCref, inInputData, inDiffType, inFunctionTree, maxIter-1); + if not referenceEq(e1.exp, res1) then + e1.exp := res1; + (e1,_) := ExpressionSimplify.simplify1(e1); + end if; + then (e1, functionTree); - // differentiate tuple + // differentiate tuple case DAE.TUPLE(PR=expl) equation //se1 = ExpressionDump.printExpStr(inExp); //print("\nExp-TUPLE\nDifferentiate exp: " + se1); From e8232c58cce16fc7a0e557aad70bda592dbc03ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 2 Jan 2018 13:05:16 +0100 Subject: [PATCH 5/5] Warnings for aliases during codegen The code generator gave the wrong variable indexes for aliases that were not replaced in the backend. This prints some warnings or errors for these cases so we can either fix the code (or replace the code generator to handle aliases better). --- Compiler/SimCode/SimCodeMain.mo | 8 +++---- Compiler/SimCode/SimCodeUtil.mo | 39 ++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/Compiler/SimCode/SimCodeMain.mo b/Compiler/SimCode/SimCodeMain.mo index 1dbbd00ec6..27b7165f26 100644 --- a/Compiler/SimCode/SimCodeMain.mo +++ b/Compiler/SimCode/SimCodeMain.mo @@ -566,7 +566,6 @@ protected end if; res := (true,SimCodeUtil.getFunctionIndex()); else - ErrorExt.moveMessagesToParentThread(); end try; end runTplWriteFile; @@ -581,7 +580,6 @@ protected Tpl.tplCallWithFailErrorNoArg(func); res := (true,SimCodeUtil.getFunctionIndex()); else - ErrorExt.moveMessagesToParentThread(); end try; end runTpl; @@ -599,7 +597,6 @@ protected func(); res := (true,SimCodeUtil.getFunctionIndex()); else - ErrorExt.moveMessagesToParentThread(); end try; end runToStr; @@ -611,7 +608,10 @@ protected algorithm (res as (b,_)) := func(); if not b then - print(System.dladdr(func) + " failed\n"); + Error.addInternalError(System.dladdr(func) + " failed\n", sourceInfo()); + end if; + if ErrorExt.getNumMessages() > 0 then + ErrorExt.moveMessagesToParentThread(); end if; end runCodegenFunc; diff --git a/Compiler/SimCode/SimCodeUtil.mo b/Compiler/SimCode/SimCodeUtil.mo index a6bda936b6..6dd04612aa 100644 --- a/Compiler/SimCode/SimCodeUtil.mo +++ b/Compiler/SimCode/SimCodeUtil.mo @@ -399,29 +399,29 @@ algorithm if debug then execStat("simCode: createModelInfo and variables"); end if; //build labels - if(boolAnd(ifcpp,Flags.getConfigBool(Flags.LABELED_REDUCTION))) then - Flags.setConfigBool(Flags.GENERATE_LABELED_SIMCODE,true); + if(boolAnd(ifcpp,Flags.getConfigBool(Flags.LABELED_REDUCTION))) then + Flags.setConfigBool(Flags.GENERATE_LABELED_SIMCODE,true); end if; - if(ifcpp) then - if Flags.getConfigBool(Flags.GENERATE_LABELED_SIMCODE) then + if(ifcpp) then + if Flags.getConfigBool(Flags.GENERATE_LABELED_SIMCODE) then (allEquations,modelInfo) := ReduceDAE.buildLabels(allEquations,modelInfo,{},args); //Flags.set(Flags.REDUCE_DAE,true); - if debug then execStat("ReduceDAE: buildLabels"); end if; - end if; - end if; + if debug then execStat("ReduceDAE: buildLabels"); end if; + end if; + end if; tmpSimVars := modelInfo.vars; //reduce terms - if(ifcpp) then - if Flags.getConfigBool(Flags.REDUCE_TERMS) then + if(ifcpp) then + if Flags.getConfigBool(Flags.REDUCE_TERMS) then (allEquations,modelInfo) := ReduceDAE.reduceTerms(allEquations,modelInfo,args); Flags.setConfigBool(Flags.REDUCE_TERMS, false); - _:=Flags.disableDebug(Flags.REDUCE_DAE); - if debug then execStat("ReduceDAE: reduceTerms"); end if; - end if; - end if; + Flags.disableDebug(Flags.REDUCE_DAE); + if debug then execStat("ReduceDAE: reduceTerms"); end if; + end if; + end if; // external objects extObjInfo := createExtObjInfo(shared); @@ -13319,6 +13319,19 @@ algorithm case (cref, SimCode.SIMCODE(crefToSimVarHT = crefToSimVarHT) ) equation sv = BaseHashTable.get(cref, crefToSimVarHT); + sv = match sv.aliasvar + case SimCodeVar.NOALIAS() then sv; + /* The C++ runtime generates a different set of variables... */ + case _ guard Config.simCodeTarget() == "Cpp" then sv; + case SimCodeVar.ALIAS(varName=cref) + algorithm + Error.addSourceMessage(Error.COMPILER_WARNING, {getInstanceName() + " got an alias variable " + ComponentReference.printComponentRefStr(inCref) + " to " + ComponentReference.printComponentRefStr(cref) + ", but before code generation these should have been removed"}, sv.source.info); + then cref2simvar(cref, simCode); + case SimCodeVar.NEGATEDALIAS(varName=cref) + algorithm + Error.addSourceMessage(Error.INTERNAL_ERROR, {getInstanceName() + " got a negated alias variable " + ComponentReference.printComponentRefStr(inCref) + " to " + ComponentReference.printComponentRefStr(cref) + ", but before code generation these should have been removed"}, sv.source.info); + then fail(); + end match; then sv; case (_, _)