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

Commit cbc69f9

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] SimplifyExp improvements.
- Added trivial simplifications of binary expressions, such as 0*e=0. - Added simplification of transpose of an array expression. - Turned off expansion of expressions containing calls to functions with array return type when -d=nfExpandOperations is used (on by default), to better mimic the old frontend and avoid unnecessary calls. - Rearranged SimplifyExp and ExpandExp a bit so that expressions are always simplified before being expanded with -d=nfExpandOperations. - Try to expand the argument in Expression.promoteExp to avoid getting promote calls in the flat model that the backend can't handle. Belonging to [master]: - #2634 - OpenModelica/OpenModelica-testsuite#1024
1 parent 7b82c41 commit cbc69f9

File tree

3 files changed

+178
-48
lines changed

3 files changed

+178
-48
lines changed

Compiler/NFFrontEnd/NFExpandExp.mo

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ public
465465
end if;
466466

467467
if expanded then
468-
outExp := expandBinaryElementWise2(exp1, op, exp2, makeBinaryOp);
468+
outExp := expandBinaryElementWise2(exp1, op, exp2, SimplifyExp.simplifyBinaryOp);
469469
else
470470
outExp := exp;
471471
end if;
@@ -522,7 +522,8 @@ public
522522

523523
if expanded then
524524
op := Operator.OPERATOR(Type.arrayElementType(Operator.typeOf(op)), scalarOp);
525-
outExp := Expression.mapArrayElements(exp2, function makeBinaryOp(op = op, exp1 = exp1));
525+
outExp := Expression.mapArrayElements(exp2,
526+
function SimplifyExp.simplifyBinaryOp(op = op, exp1 = exp1));
526527
else
527528
outExp := exp;
528529
end if;
@@ -536,7 +537,7 @@ public
536537
algorithm
537538
exp := match exp2
538539
case Expression.ARRAY() then exp2;
539-
else makeBinaryOp(exp1, op, exp2);
540+
else SimplifyExp.simplifyBinaryOp(exp1, op, exp2);
540541
end match;
541542
end makeScalarArrayBinary_traverser;
542543

@@ -555,7 +556,8 @@ public
555556

556557
if expanded then
557558
op := Operator.OPERATOR(Type.arrayElementType(Operator.typeOf(op)), scalarOp);
558-
outExp := Expression.mapArrayElements(exp1, function makeBinaryOp(op = op, exp2 = exp2));
559+
outExp := Expression.mapArrayElements(exp1,
560+
function SimplifyExp.simplifyBinaryOp(op = op, exp2 = exp2));
559561
else
560562
outExp := exp;
561563
end if;
@@ -675,8 +677,8 @@ public
675677
end if;
676678
mul_op := Operator.makeMul(tyUnlift);
677679
add_op := Operator.makeAdd(tyUnlift);
678-
expl1 := list(makeBinaryOp(e1, mul_op, e2) threaded for e1 in expl1, e2 in expl2);
679-
exp := List.reduce(expl1, function makeBinaryOp(op = add_op));
680+
expl1 := list(SimplifyExp.simplifyBinaryOp(e1, mul_op, e2) threaded for e1 in expl1, e2 in expl2);
681+
exp := List.reduce(expl1, function SimplifyExp.simplifyBinaryOp(op = add_op));
680682
end makeScalarProduct;
681683

682684
function expandBinaryMatrixProduct
@@ -800,19 +802,6 @@ public
800802
end match;
801803
end expandBinaryPowMatrix2;
802804

803-
function makeBinaryOp
804-
input Expression exp1;
805-
input Operator op;
806-
input Expression exp2;
807-
output Expression exp;
808-
algorithm
809-
if Expression.isScalarLiteral(exp1) and Expression.isScalarLiteral(exp2) then
810-
exp := Ceval.evalBinaryOp(exp1, op, exp2);
811-
else
812-
exp := Expression.BINARY(exp1, op, exp2);
813-
end if;
814-
end makeBinaryOp;
815-
816805
function expandUnary
817806
input Expression exp;
818807
input Operator op;
@@ -825,22 +814,11 @@ public
825814
scalar_op := Operator.scalarize(op);
826815

827816
if expanded then
828-
outExp := Expression.mapArrayElements(outExp, function makeUnaryOp(op = scalar_op));
817+
outExp := Expression.mapArrayElements(outExp,
818+
function SimplifyExp.simplifyUnaryOp(op = scalar_op));
829819
end if;
830820
end expandUnary;
831821

832-
function makeUnaryOp
833-
input Expression exp1;
834-
input Operator op;
835-
output Expression exp;
836-
algorithm
837-
if Expression.isScalarLiteral(exp1) then
838-
exp := Ceval.evalUnaryOp(exp1, op);
839-
else
840-
exp := Expression.UNARY(op, exp1);
841-
end if;
842-
end makeUnaryOp;
843-
844822
function expandLogicalBinary
845823
input Expression exp;
846824
output Expression outExp;

Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ protected
4343
import Prefixes = NFPrefixes;
4444
import Ceval = NFCeval;
4545
import ComplexType = NFComplexType;
46+
import ExpandExp = NFExpandExp;
4647
import MetaModelica.Dangerous.listReverseInPlace;
4748

4849
public
@@ -2924,6 +2925,18 @@ public
29242925
end match;
29252926
end isZero;
29262927

2928+
function isOne
2929+
input Expression exp;
2930+
output Boolean isOne;
2931+
algorithm
2932+
isOne := match exp
2933+
case INTEGER() then exp.value == 1;
2934+
case REAL() then exp.value == 1.0;
2935+
case CAST() then isOne(exp.exp);
2936+
else false;
2937+
end match;
2938+
end isOne;
2939+
29272940
function isPositive
29282941
input Expression exp;
29292942
output Boolean positive;
@@ -3219,6 +3232,7 @@ public
32193232
Type ty;
32203233
list<Type> rest_ty;
32213234
Expression arr_exp;
3235+
Boolean expanded;
32223236

32233237
// No types left, we're done!
32243238
case (_, {}) then exp;
@@ -3230,8 +3244,17 @@ public
32303244
// An expression with array type, but which is not an array expression.
32313245
// Such an expression can't be promoted here, so we create a promote call instead.
32323246
case (_, _) guard isArray
3233-
then CALL(Call.makeTypedCall(
3234-
NFBuiltinFuncs.PROMOTE, {exp, INTEGER(dims)}, variability(exp), listHead(types)));
3247+
algorithm
3248+
(outExp, expanded) := ExpandExp.expand(exp);
3249+
3250+
if expanded then
3251+
outExp := promote2(outExp, true, dims, types);
3252+
else
3253+
outExp := CALL(Call.makeTypedCall(
3254+
NFBuiltinFuncs.PROMOTE, {exp, INTEGER(dims)}, variability(exp), listHead(types)));
3255+
end if;
3256+
then
3257+
outExp;
32353258

32363259
// A scalar expression, promote it as many times as the number of types given.
32373260
else

Compiler/NFFrontEnd/NFSimplifyExp.mo

Lines changed: 143 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,9 @@ algorithm
181181
then
182182
exp;
183183

184-
case "sum" then simplifySumProduct(listHead(args), call, isSum = true);
185-
case "product" then simplifySumProduct(listHead(args), call, isSum = false);
184+
case "sum" then simplifySumProduct(listHead(args), call, isSum = true);
185+
case "product" then simplifySumProduct(listHead(args), call, isSum = false);
186+
case "transpose" then simplifyTranspose(listHead(args), call);
186187

187188
else Expression.CALL(call);
188189
end match;
@@ -221,6 +222,17 @@ algorithm
221222
end if;
222223
end simplifySumProduct;
223224

225+
function simplifyTranspose
226+
input Expression arg;
227+
input Call call;
228+
output Expression exp;
229+
algorithm
230+
exp := match arg
231+
case Expression.ARRAY() then Expression.transposeArray(arg);
232+
else Expression.CALL(call);
233+
end match;
234+
end simplifyTranspose;
235+
224236
function simplifySize
225237
input output Expression sizeExp;
226238
algorithm
@@ -274,15 +286,122 @@ algorithm
274286
se1 := simplify(e1);
275287
se2 := simplify(e2);
276288

277-
if Flags.isSet(Flags.NF_EXPAND_OPERATIONS) then
278-
binaryExp := ExpandExp.expand(ExpandExp.makeBinaryOp(se1, op, se2));
279-
elseif Expression.isLiteral(se1) and Expression.isLiteral(se2) then
280-
binaryExp := Ceval.evalBinaryOp(se1, op, se2);
281-
elseif not (referenceEq(e1, se1) and referenceEq(e2, se2)) then
282-
binaryExp := Expression.BINARY(se1, op, se2);
289+
binaryExp := simplifyBinaryOp(se1, op, se2);
290+
291+
if Flags.isSet(Flags.NF_EXPAND_OPERATIONS) and not Expression.hasArrayCall(binaryExp) then
292+
binaryExp := ExpandExp.expand(binaryExp);
283293
end if;
284294
end simplifyBinary;
285295

296+
function simplifyBinaryOp
297+
input Expression exp1;
298+
input Operator op;
299+
input Expression exp2;
300+
output Expression outExp;
301+
302+
import NFOperator.Op;
303+
algorithm
304+
if Expression.isLiteral(exp1) and Expression.isLiteral(exp2) then
305+
outExp := Ceval.evalBinaryOp(exp1, op, exp2);
306+
else
307+
outExp := match op.op
308+
case Op.ADD then simplifyBinaryAdd(exp1, op, exp2);
309+
case Op.SUB then simplifyBinarySub(exp1, op, exp2);
310+
case Op.MUL then simplifyBinaryMul(exp1, op, exp2);
311+
case Op.DIV then simplifyBinaryDiv(exp1, op, exp2);
312+
case Op.POW then simplifyBinaryPow(exp1, op, exp2);
313+
else Expression.BINARY(exp1, op, exp2);
314+
end match;
315+
end if;
316+
end simplifyBinaryOp;
317+
318+
function simplifyBinaryAdd
319+
input Expression exp1;
320+
input Operator op;
321+
input Expression exp2;
322+
output Expression outExp;
323+
algorithm
324+
if Expression.isZero(exp1) then
325+
// 0 + e = e
326+
outExp := exp2;
327+
elseif Expression.isZero(exp2) then
328+
// e + 0 = e
329+
outExp := exp1;
330+
else
331+
outExp := Expression.BINARY(exp1, op, exp2);
332+
end if;
333+
end simplifyBinaryAdd;
334+
335+
function simplifyBinarySub
336+
input Expression exp1;
337+
input Operator op;
338+
input Expression exp2;
339+
output Expression outExp;
340+
algorithm
341+
if Expression.isZero(exp1) then
342+
// 0 - e = -e
343+
outExp := Expression.UNARY(Operator.makeUMinus(Operator.typeOf(op)), exp2);
344+
elseif Expression.isZero(exp2) then
345+
// e - 0 = e
346+
outExp := exp1;
347+
else
348+
outExp := Expression.BINARY(exp1, op, exp2);
349+
end if;
350+
end simplifyBinarySub;
351+
352+
function simplifyBinaryMul
353+
input Expression exp1;
354+
input Operator op;
355+
input Expression exp2;
356+
input Boolean switched = false;
357+
output Expression outExp;
358+
algorithm
359+
outExp := match exp1
360+
// 0 * e = 0
361+
case Expression.INTEGER(value = 0) then exp1;
362+
case Expression.REAL(value = 0.0) then exp1;
363+
364+
// 1 * e = e
365+
case Expression.INTEGER(value = 1) then exp2;
366+
case Expression.REAL(value = 1.0) then exp2;
367+
368+
else
369+
if switched then
370+
Expression.BINARY(exp2, op, exp1)
371+
else
372+
simplifyBinaryMul(exp2, op, exp1, true);
373+
end match;
374+
end simplifyBinaryMul;
375+
376+
function simplifyBinaryDiv
377+
input Expression exp1;
378+
input Operator op;
379+
input Expression exp2;
380+
output Expression outExp;
381+
algorithm
382+
// e / 1 = e
383+
if Expression.isOne(exp2) then
384+
outExp := exp1;
385+
else
386+
outExp := Expression.BINARY(exp1, op, exp2);
387+
end if;
388+
end simplifyBinaryDiv;
389+
390+
function simplifyBinaryPow
391+
input Expression exp1;
392+
input Operator op;
393+
input Expression exp2;
394+
output Expression outExp;
395+
algorithm
396+
if Expression.isZero(exp2) then
397+
outExp := Expression.makeOne(Operator.typeOf(op));
398+
elseif Expression.isOne(exp2) then
399+
outExp := exp1;
400+
else
401+
outExp := Expression.BINARY(exp1, op, exp2);
402+
end if;
403+
end simplifyBinaryPow;
404+
286405
function simplifyUnary
287406
input output Expression unaryExp;
288407
protected
@@ -292,15 +411,25 @@ algorithm
292411
Expression.UNARY(op, e) := unaryExp;
293412
se := simplify(e);
294413

295-
if Flags.isSet(Flags.NF_EXPAND_OPERATIONS) then
296-
unaryExp := ExpandExp.expand(ExpandExp.makeUnaryOp(se, op));
297-
elseif Expression.isLiteral(se) then
298-
unaryExp := Ceval.evalUnaryOp(se, op);
299-
elseif not referenceEq(e, se) then
300-
unaryExp := Expression.UNARY(op, se);
414+
unaryExp := simplifyUnaryOp(se, op);
415+
416+
if Flags.isSet(Flags.NF_EXPAND_OPERATIONS) and not Expression.hasArrayCall(unaryExp) then
417+
unaryExp := ExpandExp.expand(unaryExp);
301418
end if;
302419
end simplifyUnary;
303420

421+
function simplifyUnaryOp
422+
input Expression exp;
423+
input Operator op;
424+
output Expression outExp;
425+
algorithm
426+
if Expression.isLiteral(exp) then
427+
outExp := Ceval.evalUnaryOp(exp, op);
428+
else
429+
outExp := Expression.UNARY(op, exp);
430+
end if;
431+
end simplifyUnaryOp;
432+
304433
function simplifyLogicBinary
305434
input output Expression binaryExp;
306435
protected

0 commit comments

Comments
 (0)