Skip to content

Commit

Permalink
[NF] Simplification improvements.
Browse files Browse the repository at this point in the history
- Move simplification of sum/product from the typing phase to the model
  simplification phase, so that it's done after loop unrolling.
- Reevaluate the type of simplified crefs and ranges, since their types
  can depend on the simplified expressions.

Belonging to [master]:
  - OpenModelica/OMCompiler#2550
  • Loading branch information
perost authored and OpenModelica-Hudson committed Jul 2, 2018
1 parent 582a038 commit 7d0153e
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 47 deletions.
50 changes: 4 additions & 46 deletions Compiler/NFFrontEnd/NFBuiltinCall.mo
Expand Up @@ -710,29 +710,8 @@ protected
(arg, ty, variability) := Typing.typeExp(listHead(args), origin, info);
ty := Type.arrayElementType(ty);

if intBitAnd(origin, intBitOr(ExpOrigin.FUNCTION, ExpOrigin.ALGORITHM)) == 0 then
(arg, expanded) := ExpandExp.expand(arg);
else
expanded := false;
end if;

if expanded then
args := Expression.arrayScalarElements(arg);

if listEmpty(args) then
callExp := Expression.makeZero(ty);
else
callExp :: args := args;
op := Operator.makeAdd(ty);

for e in args loop
callExp := Expression.BINARY(callExp, op, e);
end for;
end if;
else
{fn} := Function.typeRefCache(fn_ref);
callExp := Expression.CALL(Call.makeTypedCall(fn, {arg}, variability, ty));
end if;
{fn} := Function.typeRefCache(fn_ref);
callExp := Expression.CALL(Call.makeTypedCall(fn, {arg}, variability, ty));
end typeSumCall;

function typeProductCall
Expand Down Expand Up @@ -762,29 +741,8 @@ protected
(arg, ty, variability) := Typing.typeExp(listHead(args), origin, info);
ty := Type.arrayElementType(ty);

if intBitAnd(origin, intBitOr(ExpOrigin.FUNCTION, ExpOrigin.ALGORITHM)) == 0 then
(arg, expanded) := ExpandExp.expand(arg);
else
expanded := false;
end if;

if expanded then
args := Expression.arrayScalarElements(arg);

if listEmpty(args) then
callExp := Expression.makeOne(ty);
else
callExp :: args := args;
op := Operator.makeMul(ty);

for e in args loop
callExp := Expression.BINARY(callExp, op, e);
end for;
end if;
else
{fn} := Function.typeRefCache(fn_ref);
callExp := Expression.CALL(Call.makeTypedCall(fn, {arg}, variability, ty));
end if;
{fn} := Function.typeRefCache(fn_ref);
callExp := Expression.CALL(Call.makeTypedCall(fn, {arg}, variability, ty));
end typeProductCall;

function typeSmoothCall
Expand Down
66 changes: 65 additions & 1 deletion Compiler/NFFrontEnd/NFSimplifyExp.mo
Expand Up @@ -45,6 +45,8 @@ import NFCeval.EvalTarget;
import NFFunction.Function;
import ComponentRef = NFComponentRef;
import ExpandExp = NFExpandExp;
import TypeCheck = NFTypeCheck;
import Absyn;

public

Expand All @@ -55,6 +57,7 @@ algorithm
case Expression.CREF()
algorithm
exp.cref := ComponentRef.simplifySubscripts(exp.cref);
exp.ty := ComponentRef.getSubscriptedType(exp.cref);
then
exp;

Expand All @@ -65,7 +68,7 @@ algorithm
exp;

case Expression.RANGE()
then Expression.RANGE(exp.ty, simplify(exp.start), simplifyOpt(exp.step), simplify(exp.stop));
then simplifyRange(exp);

case Expression.RECORD()
algorithm
Expand Down Expand Up @@ -102,6 +105,31 @@ algorithm
end match;
end simplifyOpt;

function simplifyRange
input Expression range;
output Expression exp;
protected
Expression start_exp1, stop_exp1, start_exp2, stop_exp2;
Option<Expression> step_exp1, step_exp2;
Type ty;
algorithm
Expression.RANGE(ty = ty, start = start_exp1, step = step_exp1, stop = stop_exp1) := range;

start_exp2 := simplify(start_exp1);
step_exp2 := simplifyOpt(step_exp1);
stop_exp2 := simplify(stop_exp1);

if referenceEq(start_exp1, start_exp2) and
referenceEq(step_exp1, step_exp2) and
referenceEq(stop_exp1, stop_exp2) then
exp := range;
else
ty := TypeCheck.getRangeType(start_exp2, step_exp2, stop_exp2,
Type.arrayElementType(ty), Absyn.dummyInfo);
exp := Expression.RANGE(ty, start_exp2, step_exp2, stop_exp2);
end if;
end simplifyRange;

function simplifyCall
input output Expression callExp;
protected
Expand Down Expand Up @@ -151,10 +179,46 @@ algorithm
then
exp;

case "sum" then simplifySumProduct(listHead(args), call, isSum = true);
case "product" then simplifySumProduct(listHead(args), call, isSum = false);

else Expression.CALL(call);
end match;
end simplifyBuiltinCall;

function simplifySumProduct
input Expression arg;
input Call call;
input Boolean isSum;
output Expression exp;
protected
Boolean expanded;
list<Expression> args;
Type ty;
Operator op;
algorithm
(exp, expanded) := ExpandExp.expand(arg);

if expanded then
args := Expression.arrayScalarElements(exp);
ty := Expression.typeOf(arg);

if listEmpty(args) then
exp := if isSum then Expression.makeZero(ty) else Expression.makeOne(ty);
else
exp :: args := args;
op := if isSum then Operator.makeAdd(Type.arrayElementType(ty)) else
Operator.makeMul(Type.arrayElementType(ty));

for e in args loop
exp := Expression.BINARY(exp, op, e);
end for;
end if;
else
exp := Expression.CALL(call);
end if;
end simplifySumProduct;

function simplifySize
input output Expression sizeExp;
algorithm
Expand Down

0 comments on commit 7d0153e

Please sign in to comment.