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

Commit 926d8af

Browse files
hkielOpenModelica-Hudson
authored andcommitted
avoid excessive longjmp (matchcontinue)
avoid recursion (stack overflow) when processing lists Belonging to [master]: - #2084
1 parent 55a1b63 commit 926d8af

File tree

2 files changed

+81
-58
lines changed

2 files changed

+81
-58
lines changed

Compiler/FrontEnd/Expression.mo

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,17 +1525,18 @@ public function realExpIntLit "returns the int value if expression is constant R
15251525
input DAE.Exp exp;
15261526
output Option<Integer> oi;
15271527
algorithm
1528-
oi := matchcontinue exp
1528+
oi := match exp
15291529
local
15301530
Real r;
15311531
Integer i;
1532+
Option<Integer> op;
15321533
case (DAE.RCONST(real = r))
15331534
equation
15341535
i = realInt(r);
1535-
true = realEq(r,intReal(i));
1536-
then SOME(i);
1536+
op = if realEq(r,intReal(i)) then SOME(i) else NONE();
1537+
then op;
15371538
else NONE();
1538-
end matchcontinue;
1539+
end match;
15391540
end realExpIntLit;
15401541

15411542
public function expInt "returns the int value if expression is constant Integer"
@@ -5415,32 +5416,28 @@ protected function traverseExpMatrix
54155416
input list<list<DAE.Exp>> inMatrix;
54165417
input FuncExpType func;
54175418
input Type_a inTypeA;
5418-
output list<list<DAE.Exp>> outMatrix;
5419-
output Type_a outTypeA;
5419+
output list<list<DAE.Exp>> outMatrix = {};
5420+
output Type_a outTypeA = inTypeA;
54205421
partial function FuncExpType
54215422
input DAE.Exp inExp;
54225423
input Type_a inTypeA;
54235424
output DAE.Exp outExp;
54245425
output Type_a outA;
54255426
end FuncExpType;
5427+
protected
5428+
list<DAE.Exp> row_1;
5429+
Boolean same = true;
54265430
algorithm
5427-
(outMatrix,outTypeA) := match (inMatrix,func,inTypeA)
5428-
local
5429-
FuncExpType rel;
5430-
Type_a e_arg,e_arg_1,e_arg_2;
5431-
list<DAE.Exp> row_1,row;
5432-
list<list<DAE.Exp>> rows_1,rows;
5433-
5434-
case ({},_,e_arg) then ({},e_arg);
5435-
5436-
case ((row :: rows),rel,e_arg)
5437-
equation
5438-
(row_1,e_arg_1) = traverseExpList(row, rel, e_arg);
5439-
(rows_1,e_arg_2) = traverseExpMatrix(rows, rel, e_arg_1);
5440-
rows_1 = if referenceEq(row,row_1) and referenceEq(rows,rows_1) then inMatrix else (row_1::rows_1);
5441-
then
5442-
(rows_1,e_arg_2);
5443-
end match;
5431+
for row in inMatrix loop
5432+
(row_1,outTypeA) := traverseExpList(row, func, outTypeA);
5433+
same := if referenceEq(row,row_1) then same else false;
5434+
outMatrix := row_1::outMatrix;
5435+
end for;
5436+
if same then
5437+
outMatrix := inMatrix;
5438+
else
5439+
outMatrix := MetaModelica.Dangerous.listReverseInPlace(outMatrix);
5440+
end if;
54445441
end traverseExpMatrix;
54455442

54465443
public function traverseExpList<ArgT> "Calls traverseExpBottomUp for each element of list."
@@ -5874,31 +5871,29 @@ protected function traverseExpMatrixTopDown
58745871
input list<list<DAE.Exp>> inMatrix;
58755872
input FuncExpType func;
58765873
input Type_a inTypeA;
5877-
output list<list<DAE.Exp>> outMatrix;
5878-
output Type_a outTypeA;
5874+
output list<list<DAE.Exp>> outMatrix = {};
5875+
output Type_a outTypeA = inTypeA;
58795876
partial function FuncExpType
58805877
input DAE.Exp exp;
58815878
input Type_a arg;
58825879
output DAE.Exp outExp;
58835880
output Boolean cont;
58845881
output Type_a outArg;
58855882
end FuncExpType;
5883+
protected
5884+
list<DAE.Exp> row_1;
5885+
Boolean same = true;
58865886
algorithm
5887-
(outMatrix,outTypeA) := match (inMatrix,func,inTypeA)
5888-
local
5889-
FuncExpType rel;
5890-
Type_a e_arg,e_arg_1,e_arg_2;
5891-
list<DAE.Exp> row_1,row;
5892-
list<list<DAE.Exp>> rows_1,rows;
5893-
5894-
case ({},_,e_arg) then ({},e_arg);
5895-
5896-
case ((row :: rows),rel,e_arg)
5897-
equation
5898-
(row_1,e_arg_1) = traverseExpListTopDown(row, rel, e_arg);
5899-
(rows_1,e_arg_2) = traverseExpMatrixTopDown(rows, rel, e_arg_1);
5900-
then (row_1 :: rows_1,e_arg_2);
5901-
end match;
5887+
for row in inMatrix loop
5888+
(row_1,outTypeA) := traverseExpListTopDown(row, func, outTypeA);
5889+
same := if referenceEq(row,row_1) then same else false;
5890+
outMatrix := row_1::outMatrix;
5891+
end for;
5892+
if same then
5893+
outMatrix := inMatrix;
5894+
else
5895+
outMatrix := MetaModelica.Dangerous.listReverseInPlace(outMatrix);
5896+
end if;
59025897
end traverseExpMatrixTopDown;
59035898

59045899
public function traverseExpListTopDown
@@ -5908,25 +5903,29 @@ public function traverseExpListTopDown
59085903
input list<DAE.Exp> inExpl;
59095904
input FuncExpType rel;
59105905
input Type_a inExt_arg;
5911-
output list<DAE.Exp> outExpl;
5912-
output Type_a outA;
5906+
output list<DAE.Exp> outExpl = {};
5907+
output Type_a outA = inExt_arg;
59135908
partial function FuncExpType
59145909
input DAE.Exp exp;
59155910
input Type_a arg;
59165911
output DAE.Exp outExp;
59175912
output Boolean cont;
59185913
output Type_a outArg;
59195914
end FuncExpType;
5915+
protected
5916+
DAE.Exp e_1;
5917+
Boolean same = true;
59205918
algorithm
5921-
(outExpl,outA) := match(inExpl,rel,inExt_arg)
5922-
local DAE.Exp e,e1; list<DAE.Exp> expl1, expl; Type_a ext_arg;
5923-
case ({},_,ext_arg) then ({},ext_arg);
5924-
case (e::expl,_,ext_arg)
5925-
equation
5926-
(e1,ext_arg) = traverseExpTopDown(e, rel, ext_arg);
5927-
(expl1,ext_arg) = traverseExpListTopDown(expl,rel,ext_arg);
5928-
then (e1::expl1,ext_arg);
5929-
end match;
5919+
for e in inExpl loop
5920+
(e_1,outA) := traverseExpTopDown(e, rel, outA);
5921+
same := if referenceEq(e,e_1) then same else false;
5922+
outExpl := e_1::outExpl;
5923+
end for;
5924+
if same then
5925+
outExpl := inExpl;
5926+
else
5927+
outExpl := MetaModelica.Dangerous.listReverseInPlace(outExpl);
5928+
end if;
59305929
end traverseExpListTopDown;
59315930

59325931
public function traverseExpOpt "Calls traverseExpBottomUp for SOME(exp) and does nothing for NONE"
@@ -5972,12 +5971,12 @@ public function traverseExpOptTopDown "Calls traverseExpTopDown for SOME(exp) an
59725971
replaceable type Type_a subtypeof Any;
59735972
algorithm
59745973
(outExp,outA) := match (inExp,func,inTypeA)
5975-
local DAE.Exp e; Type_a a;
5974+
local DAE.Exp e,e1; Type_a a;
59765975
case(NONE(),_,a) then (NONE(),a);
59775976
case(SOME(e),_,a)
59785977
equation
5979-
(e,a) = traverseExpTopDown(e,func,a);
5980-
then (SOME(e),a);
5978+
(e1,a) = traverseExpTopDown(e,func,a);
5979+
then (if referenceEq(e,e1) then inExp else SOME(e1),a);
59815980
end match;
59825981
end traverseExpOptTopDown;
59835982

@@ -6951,14 +6950,14 @@ public function traverseExpOptBidir<ArgT>
69516950
algorithm
69526951
(outExp, outArg) := match(inExp)
69536952
local
6954-
DAE.Exp e;
6953+
DAE.Exp e,e1;
69556954
ArgT arg;
69566955

69576956
case SOME(e)
69586957
equation
6959-
(e, arg) = traverseExpBidir(e, inEnterFunc, inExitFunc, inArg);
6958+
(e1, arg) = traverseExpBidir(e, inEnterFunc, inExitFunc, inArg);
69606959
then
6961-
(SOME(e), arg);
6960+
(if referenceEq(e,e1) then inExp else SOME(e1), arg);
69626961

69636962
else (inExp, inArg);
69646963
end match;

Compiler/FrontEnd/ExpressionSimplify.mo

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2035,6 +2035,30 @@ algorithm
20352035
end match;
20362036
end simplify2;
20372037

2038+
protected function simplifyBinaryArrayOp
2039+
input Operator inOperator;
2040+
output Boolean found;
2041+
algorithm
2042+
found := match (inOperator)
2043+
case DAE.MUL_MATRIX_PRODUCT() then true;
2044+
case DAE.ADD_ARR() then true;
2045+
case DAE.SUB_ARR() then true;
2046+
case DAE.MUL_ARR() then true;
2047+
case DAE.DIV_ARR() then true;
2048+
case DAE.POW_ARR() then true;
2049+
case DAE.POW_ARR2() then true;
2050+
case DAE.MUL_ARRAY_SCALAR() then true;
2051+
case DAE.ADD_ARRAY_SCALAR() then true;
2052+
case DAE.DIV_ARRAY_SCALAR() then true;
2053+
case DAE.POW_ARRAY_SCALAR() then true;
2054+
case DAE.SUB_SCALAR_ARRAY() then true;
2055+
case DAE.DIV_SCALAR_ARRAY() then true;
2056+
case DAE.POW_SCALAR_ARRAY() then true;
2057+
case DAE.MUL_SCALAR_PRODUCT() then true;
2058+
else false;
2059+
end match;
2060+
end simplifyBinaryArrayOp;
2061+
20382062
protected function simplifyBinaryArray "Simplifies binary array expressions,
20392063
e.g. matrix multiplication, etc."
20402064
input DAE.Exp inExp1;
@@ -3967,7 +3991,7 @@ algorithm
39673991

39683992

39693993
// binary operations on arrays
3970-
case (_,op,e1,e2,_,_)
3994+
case (_,op,e1,e2,_,_) guard simplifyBinaryArrayOp(op)
39713995
then simplifyBinaryArray(e1, op, e2);
39723996

39733997
// binary scalar simplifications

0 commit comments

Comments
 (0)