Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit 15276ce

Browse files
hkielOpenModelica-Hudson
authored andcommitted
avoid stack overflow (ticket:4534)
1 parent 0371e97 commit 15276ce

File tree

1 file changed

+102
-109
lines changed

1 file changed

+102
-109
lines changed

Compiler/SimCode/SimCodeUtil.mo

Lines changed: 102 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -3248,125 +3248,118 @@ algorithm
32483248
end match;
32493249
end createTempVars;
32503250

3251+
// no matchcontinue needed -> try/catch around whole
3252+
// loops the eqs list -> no recursion needed
32513253
protected function createNonlinearResidualEquations
32523254
input list<BackendDAE.Equation> eqs;
32533255
input Integer iuniqueEqIndex;
32543256
input list<SimCodeVar.SimVar> itempvars;
3255-
output list<SimCode.SimEqSystem> eqSystems;
3256-
output Integer ouniqueEqIndex;
3257-
output list<SimCodeVar.SimVar> otempvars;
3257+
output list<SimCode.SimEqSystem> eqSystems = {};
3258+
output Integer ouniqueEqIndex = iuniqueEqIndex;
3259+
output list<SimCodeVar.SimVar> otempvars = itempvars;
32583260
algorithm
3259-
(eqSystems, ouniqueEqIndex, otempvars) := matchcontinue (eqs)
3260-
local
3261-
Integer size, uniqueEqIndex;
3262-
DAE.Exp res_exp, e1, e2, e, lhse;
3263-
list<DAE.Exp> explst, explst1;
3264-
list<BackendDAE.Equation> rest;
3265-
BackendDAE.Equation eq;
3266-
list<SimCode.SimEqSystem> eqSystemsRest, eqSystlst;
3267-
list<Integer> ds;
3268-
DAE.ComponentRef left;
3269-
list<DAE.Statement> algStatements;
3270-
DAE.ElementSource source;
3271-
list<tuple<DAE.Exp, DAE.Exp>> exptl;
3272-
list<DAE.ComponentRef> crefs, crefstmp;
3273-
list<SimCodeVar.SimVar> tempvars;
3274-
BackendVarTransform.VariableReplacements repl;
3275-
DAE.Type ty;
3276-
String errorMessage;
3277-
DAE.Expand crefExpand;
3278-
3279-
case ({})
3280-
then ({}, iuniqueEqIndex, itempvars);
3281-
3282-
case (BackendDAE.EQUATION(exp=e1, scalar=e2, source=source)::rest) equation
3283-
res_exp = Expression.createResidualExp(e1, e2);
3284-
res_exp = Expression.replaceDerOpInExp(res_exp);
3285-
(eqSystemsRest, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(rest, iuniqueEqIndex, itempvars);
3286-
then (SimCode.SES_RESIDUAL(uniqueEqIndex, res_exp, source)::eqSystemsRest, uniqueEqIndex+1, tempvars);
3287-
3288-
case (BackendDAE.RESIDUAL_EQUATION(exp=e, source=source)::rest) equation
3289-
(res_exp, _) = ExpressionSimplify.simplify(e);
3290-
res_exp = Expression.replaceDerOpInExp(res_exp);
3291-
(eqSystemsRest, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(rest, iuniqueEqIndex, itempvars);
3292-
then (SimCode.SES_RESIDUAL(uniqueEqIndex, res_exp, source) :: eqSystemsRest, uniqueEqIndex+1, tempvars);
3293-
3294-
// An array equation
3295-
case (BackendDAE.ARRAY_EQUATION(dimSize=ds, left=e1, right=e2, source=source)::rest) equation
3296-
ty = Expression.typeof(e1);
3297-
left = ComponentReference.makeCrefIdent("$TMP_" + intString(iuniqueEqIndex), ty, {});
3298-
lhse = DAE.CREF(left,ty);
3299-
3300-
res_exp = Expression.createResidualExp(e1, e2);
3301-
res_exp = Expression.replaceDerOpInExp(res_exp);
3302-
crefstmp = ComponentReference.expandCref(left, false);
3303-
explst1 = List.map(crefstmp, Expression.crefExp);
3304-
(eqSystlst, uniqueEqIndex) = List.map1Fold(explst1, makeSES_RESIDUAL, source, iuniqueEqIndex);
3305-
eqSystlst = SimCode.SES_ARRAY_CALL_ASSIGN(uniqueEqIndex, lhse, res_exp, source)::eqSystlst;
3306-
tempvars = createArrayTempVar(left, ds, explst1, itempvars);
3307-
(eqSystemsRest, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(rest, uniqueEqIndex+1, tempvars);
3308-
eqSystemsRest = listAppend(eqSystlst, eqSystemsRest);
3309-
then (eqSystemsRest, uniqueEqIndex, tempvars);
3310-
3311-
// A complex equation
3312-
case (BackendDAE.COMPLEX_EQUATION(left=e1, right=e2, source=source)::rest) equation
3313-
(e1, _) = ExpressionSimplify.simplify(e1);
3314-
e1 = Expression.replaceDerOpInExp(e1);
3315-
(e2, _) = ExpressionSimplify.simplify(e2);
3316-
e2 = Expression.replaceDerOpInExp(e2);
3317-
(eqSystlst, uniqueEqIndex, tempvars) = createNonlinearResidualEquationsComplex(e1, e2, source, iuniqueEqIndex, itempvars);
3318-
(eqSystemsRest, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(rest, uniqueEqIndex, tempvars);
3319-
eqSystemsRest = listAppend(eqSystlst, eqSystemsRest);
3320-
then (eqSystemsRest, uniqueEqIndex, tempvars);
3321-
3322-
case ((eq as BackendDAE.WHEN_EQUATION(whenEquation=BackendDAE.WHEN_STMTS()))::_) equation
3323-
// This following does not work. It does not take index or elseWhen into account.
3324-
// The generated code for the when-equation also does not solve a linear system; it uses the variables directly.
3325-
/*
3326-
tp = Expression.typeof(e2);
3327-
e1 = Expression.makeCrefExp(left, tp);
3328-
res_exp = DAE.BINARY(e1, DAE.SUB(tp), e2);
3329-
res_exp = ExpressionSimplify.simplify(res_exp);
3330-
res_exp = Expression.replaceDerOpInExp(res_exp);
3331-
(eqSystemsRest) = createNonlinearResidualEquations(rest, repl, uniqueEqIndex );
3332-
then
3333-
(SimCode.SES_RESIDUAL(0, res_exp) :: eqSystemsRest, entrylst1);
3334-
*/
3335-
Error.addSourceMessage(Error.UNSUPPORTED_LANGUAGE_FEATURE, {"non-linear equations within when-equations", "Perform non-linear operations outside the when-equation (this is slower, but works)"}, BackendEquation.equationInfo(eq));
3336-
then fail();
3337-
3338-
case (BackendDAE.ALGORITHM(alg=DAE.ALGORITHM_STMTS(algStatements), source=source, expand=crefExpand)::rest) equation
3339-
crefs = CheckModel.checkAndGetAlgorithmOutputs(DAE.ALGORITHM_STMTS(algStatements), source, crefExpand);
3340-
// BackendDump.debugStrCrefLstStr(("Crefs : ", crefs, ", ", "\n"));
3341-
(crefstmp, repl) = createTmpCrefs(crefs, iuniqueEqIndex, {}, BackendVarTransform.emptyReplacements());
3342-
// BackendDump.debugStrCrefLstStr(("Crefs : ", crefstmp, ", ", "\n"));
3343-
explst = List.map(crefs, Expression.crefExp);
3344-
explst = List.map(explst, Expression.replaceDerOpInExp);
3261+
try
3262+
for eq in listReverse(eqs) loop
3263+
eqSystems := match (eq, ouniqueEqIndex)
3264+
local
3265+
DAE.Exp res_exp, e1, e2, e, lhse;
3266+
list<DAE.Exp> explst, explst1;
3267+
list<SimCode.SimEqSystem> eqSystlst;
3268+
list<Integer> ds;
3269+
DAE.ComponentRef left;
3270+
list<DAE.Statement> algStatements;
3271+
DAE.ElementSource source;
3272+
list<tuple<DAE.Exp, DAE.Exp>> exptl;
3273+
list<DAE.ComponentRef> crefs, crefstmp;
3274+
BackendVarTransform.VariableReplacements repl;
3275+
DAE.Type ty;
3276+
DAE.Expand crefExpand;
3277+
Integer uniqueEqIndex;
3278+
3279+
case (BackendDAE.EQUATION(exp=e1, scalar=e2, source=source), uniqueEqIndex) equation
3280+
res_exp = Expression.createResidualExp(e1, e2);
3281+
res_exp = Expression.replaceDerOpInExp(res_exp);
3282+
ouniqueEqIndex = uniqueEqIndex + 1;
3283+
then SimCode.SES_RESIDUAL(uniqueEqIndex, res_exp, source)::eqSystems;
3284+
3285+
case (BackendDAE.RESIDUAL_EQUATION(exp=e, source=source), uniqueEqIndex) equation
3286+
(res_exp, _) = ExpressionSimplify.simplify(e);
3287+
res_exp = Expression.replaceDerOpInExp(res_exp);
3288+
ouniqueEqIndex = uniqueEqIndex + 1;
3289+
then SimCode.SES_RESIDUAL(uniqueEqIndex, res_exp, source) :: eqSystems;
3290+
3291+
// An array equation
3292+
case (BackendDAE.ARRAY_EQUATION(dimSize=ds, left=e1, right=e2, source=source), uniqueEqIndex) equation
3293+
ty = Expression.typeof(e1);
3294+
left = ComponentReference.makeCrefIdent("$TMP_" + intString(uniqueEqIndex), ty, {});
3295+
lhse = DAE.CREF(left,ty);
3296+
3297+
res_exp = Expression.createResidualExp(e1, e2);
3298+
res_exp = Expression.replaceDerOpInExp(res_exp);
3299+
crefstmp = ComponentReference.expandCref(left, false);
3300+
explst1 = List.map(crefstmp, Expression.crefExp);
3301+
(eqSystlst, uniqueEqIndex) = List.map1Fold(explst1, makeSES_RESIDUAL, source, uniqueEqIndex);
3302+
eqSystlst = SimCode.SES_ARRAY_CALL_ASSIGN(uniqueEqIndex, lhse, res_exp, source)::eqSystlst;
3303+
otempvars = createArrayTempVar(left, ds, explst1, otempvars);
3304+
ouniqueEqIndex = uniqueEqIndex + 1;
3305+
then listAppend(eqSystlst, eqSystems);
3306+
3307+
// A complex equation
3308+
case (BackendDAE.COMPLEX_EQUATION(left=e1, right=e2, source=source), uniqueEqIndex) equation
3309+
(e1, _) = ExpressionSimplify.simplify(e1);
3310+
e1 = Expression.replaceDerOpInExp(e1);
3311+
(e2, _) = ExpressionSimplify.simplify(e2);
3312+
e2 = Expression.replaceDerOpInExp(e2);
3313+
(eqSystlst, ouniqueEqIndex, otempvars) = createNonlinearResidualEquationsComplex(e1, e2, source, uniqueEqIndex, otempvars);
3314+
then listAppend(eqSystlst, eqSystems);
3315+
3316+
case (BackendDAE.WHEN_EQUATION(whenEquation=BackendDAE.WHEN_STMTS()), _) equation
3317+
// This following does not work. It does not take index or elseWhen into account.
3318+
// The generated code for the when-equation also does not solve a linear system; it uses the variables directly.
3319+
/*
3320+
tp = Expression.typeof(e2);
3321+
e1 = Expression.makeCrefExp(left, tp);
3322+
res_exp = DAE.BINARY(e1, DAE.SUB(tp), e2);
3323+
res_exp = ExpressionSimplify.simplify(res_exp);
3324+
res_exp = Expression.replaceDerOpInExp(res_exp);
3325+
(eqSystemsRest) = createNonlinearResidualEquations(rest, repl, uniqueEqIndex );
3326+
then
3327+
(SimCode.SES_RESIDUAL(0, res_exp) :: eqSystemsRest, entrylst1);
3328+
*/
3329+
Error.addSourceMessage(Error.UNSUPPORTED_LANGUAGE_FEATURE, {"non-linear equations within when-equations", "Perform non-linear operations outside the when-equation (this is slower, but works)"}, BackendEquation.equationInfo(eq));
3330+
then fail();
33453331

3346-
// BackendDump.dumpAlgorithms({DAE.ALGORITHM_STMTS(algStatements)}, 0);
3347-
(algStatements, _) = BackendVarTransform.replaceStatementLst(algStatements, repl, SOME(BackendVarTransform.skipPreOperator), {}, false);
3348-
// BackendDump.dumpAlgorithms({DAE.ALGORITHM_STMTS(algStatements)}, 0);
3332+
case (BackendDAE.ALGORITHM(alg=DAE.ALGORITHM_STMTS(algStatements), source=source, expand=crefExpand), uniqueEqIndex) equation
3333+
crefs = CheckModel.checkAndGetAlgorithmOutputs(DAE.ALGORITHM_STMTS(algStatements), source, crefExpand);
3334+
// BackendDump.debugStrCrefLstStr(("Crefs : ", crefs, ", ", "\n"));
3335+
(crefstmp, repl) = createTmpCrefs(crefs, uniqueEqIndex, {}, BackendVarTransform.emptyReplacements());
3336+
// BackendDump.debugStrCrefLstStr(("Crefs : ", crefstmp, ", ", "\n"));
3337+
explst = List.map(crefs, Expression.crefExp);
3338+
explst = List.map(explst, Expression.replaceDerOpInExp);
33493339

3350-
explst1 = List.map(crefstmp, Expression.crefExp);
3351-
explst1 = List.map(explst1, Expression.replaceDerOpInExp);
3352-
tempvars = createTempVarsforCrefs(explst1, itempvars);
3340+
// BackendDump.dumpAlgorithms({DAE.ALGORITHM_STMTS(algStatements)}, 0);
3341+
(algStatements, _) = BackendVarTransform.replaceStatementLst(algStatements, repl, SOME(BackendVarTransform.skipPreOperator), {}, false);
3342+
// BackendDump.dumpAlgorithms({DAE.ALGORITHM_STMTS(algStatements)}, 0);
33533343

3354-
// 0 = a - tmp
3355-
exptl = List.threadTuple(explst, explst1);
3356-
(eqSystlst, uniqueEqIndex) = List.map1Fold(exptl, makeSES_RESIDUAL1, source, iuniqueEqIndex);
3344+
explst1 = List.map(crefstmp, Expression.crefExp);
3345+
explst1 = List.map(explst1, Expression.replaceDerOpInExp);
3346+
otempvars = createTempVarsforCrefs(explst1, otempvars);
33573347

3358-
eqSystlst = SimCode.SES_ALGORITHM(uniqueEqIndex, algStatements)::eqSystlst;
3359-
// Tpl.tplPrint(SimCodeDump.dumpEqs, eqSystlst);
3348+
// 0 = a - tmp
3349+
exptl = List.threadTuple(explst, explst1);
3350+
(eqSystlst, uniqueEqIndex) = List.map1Fold(exptl, makeSES_RESIDUAL1, source, uniqueEqIndex);
33603351

3361-
(eqSystemsRest, uniqueEqIndex, tempvars) = createNonlinearResidualEquations(rest, uniqueEqIndex+1, tempvars);
3362-
eqSystemsRest = listAppend(eqSystlst, eqSystemsRest);
3363-
then (eqSystemsRest, uniqueEqIndex, tempvars);
3352+
eqSystlst = SimCode.SES_ALGORITHM(uniqueEqIndex, algStatements)::eqSystlst;
3353+
// Tpl.tplPrint(SimCodeDump.dumpEqs, eqSystlst);
33643354

3365-
case (eq::_) equation
3366-
errorMessage = "function createNonlinearResidualEquations failed for equation: " + BackendDump.equationString(eq);
3367-
Error.addSourceMessage(Error.INTERNAL_ERROR, {errorMessage}, BackendEquation.equationInfo(eq));
3368-
then fail();
3369-
end matchcontinue;
3355+
ouniqueEqIndex = uniqueEqIndex + 1;
3356+
then listAppend(eqSystlst, eqSystems);
3357+
end match;
3358+
end for;
3359+
else
3360+
Error.addMessage(Error.INTERNAL_ERROR, {"function createNonlinearResidualEquations failed"});
3361+
fail();
3362+
end try;
33703363
end createNonlinearResidualEquations;
33713364

33723365
public function dimsToAllIndexes
@@ -5865,7 +5858,7 @@ algorithm
58655858
// wbraun:
58665859
// TODO: Fix createNonlinearResidualEquations support cases where
58675860
// solved variables are on rhs and also lhs. This is not
5868-
// cosidered yet there.
5861+
// considered yet there.
58695862
(resEqs, uniqueEqIndex, tempvars) = createNonlinearResidualEquations({inEquation}, iuniqueEqIndex, itempvars);
58705863
(_, homotopySupport) = BackendEquation.traverseExpsOfEquation(inEquation, BackendDAEUtil.containsHomotopyCall, false);
58715864
then ({SimCode.SES_NONLINEAR(SimCode.NONLINEARSYSTEM(uniqueEqIndex, resEqs, crefs, 0, listLength(inVars)+listLength(tempvars)-listLength(itempvars), NONE(), homotopySupport, false, false), NONE())}, uniqueEqIndex+1, tempvars);

0 commit comments

Comments
 (0)