Skip to content

Commit bbbca3c

Browse files
authored
Fix #8120 (#8140)
- Replace crefs that refer to variables with 0-dimensions with appropriately subscripted array expressions. - Replace `size(exp, index)` of arrays with 0-dimensions with an array of the expression's dimensions subscripted with the index. - Revert #8117 since it doesn't work with PNlib for unknown reasons.
1 parent d8aa7d6 commit bbbca3c

File tree

9 files changed

+141
-10
lines changed

9 files changed

+141
-10
lines changed

OMCompiler/Compiler/NFFrontEnd/NFComponentRef.mo

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,18 @@ public
12251225
end match;
12261226
end depth;
12271227

1228+
function isEmptyArray
1229+
"Returns whether any node in the cref has a dimension that's 0."
1230+
input ComponentRef cref;
1231+
output Boolean isEmpty;
1232+
algorithm
1233+
isEmpty := match cref
1234+
case CREF()
1235+
then Type.isEmptyArray(cref.ty) or isEmptyArray(cref.restCref);
1236+
else false;
1237+
end match;
1238+
end isEmptyArray;
1239+
12281240
function isComplexArray
12291241
input ComponentRef cref;
12301242
output Boolean complexArray;

OMCompiler/Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,11 @@ public
11371137
Boolean literal;
11381138
Expression first_e;
11391139
algorithm
1140+
if isEmptyArray(exp) then
1141+
outExp := makeSubscriptedExp(subscript :: restSubscripts, exp);
1142+
return;
1143+
end if;
1144+
11401145
sub := Subscript.expandSlice(subscript);
11411146

11421147
outExp := match sub

OMCompiler/Compiler/NFFrontEnd/NFInst.mo

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ algorithm
197197
flatModel.variables := List.filterOnFalse(flatModel.variables, Variable.isEmptyArray);
198198
end if;
199199

200+
flatModel := FlatModel.mapExp(flatModel, replaceEmptyArrays);
201+
200202
VerifyModel.verify(flatModel);
201203

202204
if Flags.isSet(Flags.COMBINE_SUBSCRIPTS) then
@@ -3792,5 +3794,48 @@ algorithm
37923794
str := FlatModel.toFlatString(flat_model, FunctionTree.listValues(functions));
37933795
end dumpFlatModel;
37943796

3797+
function replaceEmptyArrays
3798+
"Variables with 0-dimensions are not present in the flat model, so replace
3799+
any cref that refers to such a variable with an empty array expression."
3800+
input output Expression exp;
3801+
protected
3802+
function traverser
3803+
input Expression exp;
3804+
output Expression outExp;
3805+
protected
3806+
ComponentRef cref;
3807+
list<Subscript> subs;
3808+
Type ty;
3809+
algorithm
3810+
outExp := match exp
3811+
case Expression.CREF(cref = cref)
3812+
guard ComponentRef.isEmptyArray(cref)
3813+
algorithm
3814+
if ComponentRef.hasSubscripts(cref) then
3815+
cref := ComponentRef.fillSubscripts(cref);
3816+
cref := ComponentRef.replaceWholeSubscripts(cref);
3817+
subs := ComponentRef.subscriptsAllFlat(cref);
3818+
cref := ComponentRef.stripSubscriptsAll(cref);
3819+
ty := ComponentRef.getSubscriptedType(cref);
3820+
else
3821+
subs := {};
3822+
ty := exp.ty;
3823+
end if;
3824+
3825+
outExp := Expression.makeDefaultValue(ty);
3826+
3827+
if not listEmpty(subs) then
3828+
outExp := Expression.SUBSCRIPTED_EXP(outExp, subs, exp.ty, false);
3829+
end if;
3830+
then
3831+
outExp;
3832+
3833+
else exp;
3834+
end match;
3835+
end traverser;
3836+
algorithm
3837+
exp := Expression.map(exp, traverser);
3838+
end replaceEmptyArrays;
3839+
37953840
annotation(__OpenModelica_Interface="frontend");
37963841
end NFInst;

OMCompiler/Compiler/NFFrontEnd/NFSimplifyModel.mo

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -311,13 +311,14 @@ algorithm
311311
algorithm
312312
dim := Type.nthDimension(Expression.typeOf(e), 1);
313313

314-
if Dimension.isOne(dim) then
315-
// Unroll the loop if the iteration range consists of only one value.
316-
e := Expression.applySubscript(Subscript.INDEX(Expression.INTEGER(1)), e);
317-
body := Statement.replaceIteratorList(stmt.body, stmt.iterator, e);
318-
body := simplifyStatements(body);
319-
statements := listAppend(listReverse(body), statements);
320-
elseif not Dimension.isZero(dim) then
314+
//if Dimension.isOne(dim) then
315+
// // Unroll the loop if the iteration range consists of only one value.
316+
// e := Expression.applySubscript(Subscript.INDEX(Expression.INTEGER(1)), e);
317+
// body := Statement.replaceIteratorList(stmt.body, stmt.iterator, e);
318+
// body := simplifyStatements(body);
319+
// statements := listAppend(listReverse(body), statements);
320+
//elseif not Dimension.isZero(dim) then
321+
if not Dimension.isZero(dim) then
321322
// Otherwise just simplify if the iteration range is not empty.
322323
stmt.range := SOME(SimplifyExp.simplify(e));
323324
stmt.body := simplifyStatements(stmt.body);

OMCompiler/Compiler/NFFrontEnd/NFTyping.mo

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2305,6 +2305,7 @@ protected
23052305
TypingError ty_err;
23062306
Option<Expression> oexp;
23072307
InstContext.Type next_context = InstContext.set(context, NFInstContext.SUBEXPRESSION);
2308+
list<Expression> expl;
23082309
algorithm
23092310
(sizeExp, sizeType, variability, purity) := match sizeExp
23102311
case Expression.SIZE(exp = exp, dimIndex = SOME(index))
@@ -2365,8 +2366,19 @@ algorithm
23652366
fail();
23662367
end if;
23672368

2368-
// Since we don't know which dimension to take the size of, return a size expression.
2369-
exp := Expression.SIZE(exp, SOME(index));
2369+
if Type.isEmptyArray(exp_ty) and not InstContext.inFunction(context) then
2370+
// If the expression has any dimensions that are 0 it might not be safe to generate
2371+
// a size expression with it, since it might be either a variable that's no longer
2372+
// present in the flat model or an array expression that doesn't have enough
2373+
// dimensions (e.g. Real[0, 2] => {}). In that case make an array with the dimension
2374+
// sizes of the expression and index that instead.
2375+
expl := list(Dimension.sizeExp(d) for d in Type.arrayDims(exp_ty));
2376+
exp := Expression.makeExpArray(expl, Type.INTEGER());
2377+
exp := Expression.makeSubscriptedExp({Subscript.makeIndex(index)}, exp);
2378+
else
2379+
// Since we don't know which dimension to take the size of, return a size expression.
2380+
exp := Expression.SIZE(exp, SOME(index));
2381+
end if;
23702382
end if;
23712383
then
23722384
(exp, Type.INTEGER(), variability, purity);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// name: EmptyArray2
2+
// keywords:
3+
// status: correct
4+
// cflags: -d=newInst
5+
//
6+
7+
model EmptyArray2
8+
Real x[0];
9+
Real y = time;
10+
Real z;
11+
algorithm
12+
for m in 1:1 loop
13+
z := if m == 1 then y else x[m - 1];
14+
end for;
15+
end EmptyArray2;
16+
17+
// Result:
18+
// class EmptyArray2
19+
// Real y = time;
20+
// Real z;
21+
// algorithm
22+
// for m in 1:1 loop
23+
// z := if m == 1 then y else {}[m - 1];
24+
// end for;
25+
// end EmptyArray2;
26+
// endResult
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// name: EmptyArray3
2+
// keywords:
3+
// status: correct
4+
// cflags: -d=newInst
5+
//
6+
7+
model EmptyArray3
8+
Real x[0, 2];
9+
Real y = time;
10+
Real z;
11+
algorithm
12+
for m in 1:1 loop
13+
z := if m == 1 then y else size(x, m - 1);
14+
end for;
15+
end EmptyArray3;
16+
17+
// Result:
18+
// class EmptyArray3
19+
// Real y = time;
20+
// Real z;
21+
// algorithm
22+
// for m in 1:1 loop
23+
// z := if m == 1 then y else {0.0, 2.0}[m - 1];
24+
// end for;
25+
// end EmptyArray3;
26+
// endResult

testsuite/flattening/modelica/scodeinst/ForStatement3.mo

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ end ForStatement3;
2121
// Real x[4];
2222
// Real x[5];
2323
// algorithm
24-
// x[2] := time;
24+
// for i in 2:2 loop
25+
// x[i] := time;
26+
// end for;
2527
// end ForStatement3;
2628
// endResult

testsuite/flattening/modelica/scodeinst/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,8 @@ Each4.mo \
350350
Each5.mo \
351351
Each6.mo \
352352
EmptyArray1.mo \
353+
EmptyArray2.mo \
354+
EmptyArray3.mo \
353355
Encapsulated1.mo \
354356
Encapsulated2.mo \
355357
EncapsulatingInst1.mo \

0 commit comments

Comments
 (0)