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

Commit 4912fd6

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Inlining fixes.
- Create an appropriate dimension expression for ranges of unknown size. - Do replacements in array dimensions during inlining too. - Fix Call.typeArgs so that only external function arguments are left unevaluated, and not all function arguments. Belonging to [master]: - #2418
1 parent bc9cece commit 4912fd6

File tree

6 files changed

+328
-78
lines changed

6 files changed

+328
-78
lines changed

Compiler/NFFrontEnd/NFBuiltinFuncs.mo

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,11 +216,36 @@ constant Function ABS_REAL = Function.FUNCTION(Path.IDENT("abs"),
216216
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
217217
Pointer.createImmutable(true), Pointer.createImmutable(0));
218218

219+
constant Function MAX_INT = Function.FUNCTION(Path.IDENT("max"),
220+
InstNode.EMPTY_NODE(), {INT_PARAM, INT_PARAM}, {INT_PARAM}, {}, {},
221+
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
222+
Pointer.createImmutable(true), Pointer.createImmutable(0));
223+
219224
constant Function MAX_REAL = Function.FUNCTION(Path.IDENT("max"),
220225
InstNode.EMPTY_NODE(), {REAL_PARAM, REAL_PARAM}, {REAL_PARAM}, {}, {},
221226
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
222227
Pointer.createImmutable(true), Pointer.createImmutable(0));
223228

229+
constant Function DIV_INT = Function.FUNCTION(Path.IDENT("div"),
230+
InstNode.EMPTY_NODE(), {INT_PARAM, INT_PARAM}, {INT_PARAM}, {}, {},
231+
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
232+
Pointer.createImmutable(true), Pointer.createImmutable(0));
233+
234+
constant Function FLOOR = Function.FUNCTION(Path.IDENT("floor"),
235+
InstNode.EMPTY_NODE(), {REAL_PARAM}, {REAL_PARAM}, {}, {},
236+
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
237+
Pointer.createImmutable(true), Pointer.createImmutable(0));
238+
239+
constant Function INTEGER_REAL = Function.FUNCTION(Path.IDENT("integer"),
240+
InstNode.EMPTY_NODE(), {REAL_PARAM}, {INT_PARAM}, {}, {},
241+
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
242+
Pointer.createImmutable(true), Pointer.createImmutable(0));
243+
244+
constant Function INTEGER_ENUM = Function.FUNCTION(Path.IDENT("Integer"),
245+
InstNode.EMPTY_NODE(), {ENUM_PARAM}, {INT_PARAM}, {}, {},
246+
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
247+
Pointer.createImmutable(true), Pointer.createImmutable(0));
248+
224249
constant Function POSITIVE_MAX_REAL = Function.FUNCTION(Path.IDENT("$OMC$PositiveMax"),
225250
InstNode.EMPTY_NODE(), {REAL_PARAM, REAL_PARAM}, {REAL_PARAM}, {}, {},
226251
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,

Compiler/NFFrontEnd/NFCall.mo

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -550,15 +550,25 @@ uniontype Call
550550
input SourceInfo info;
551551
algorithm
552552
call := match call
553-
case UNTYPED_CALL() algorithm
554-
typeCachedFunctions(call.ref);
555-
then
556-
typeArgs(call, origin, info);
553+
local
554+
list<Function> fnl;
555+
Boolean is_external;
557556

558-
else algorithm
559-
Error.assertion(false, getInstanceName() + " got invalid function call expression", sourceInfo());
560-
then
561-
fail();
557+
case UNTYPED_CALL()
558+
algorithm
559+
fnl := typeCachedFunctions(call.ref);
560+
// Don't evaluate constants or structural parameters for external functions,
561+
// the code generation can't handle it in some cases (see bug #4904).
562+
// TODO: Remove this when #4904 is fixed.
563+
is_external := if listEmpty(fnl) then false else Function.isExternal(listHead(fnl));
564+
then
565+
typeArgs(call, not is_external, origin, info);
566+
567+
else
568+
algorithm
569+
Error.assertion(false, getInstanceName() + " got invalid function call expression", sourceInfo());
570+
then
571+
fail();
562572
end match;
563573
end typeNormalCall;
564574

@@ -576,6 +586,7 @@ uniontype Call
576586
case ComponentRef.CREF(node = fn_node)
577587
algorithm
578588
CachedData.FUNCTION(functions, typed, special) := InstNode.getFuncCache(fn_node);
589+
579590
// Type the function(s) if not already done.
580591
if not typed then
581592
functions := list(Function.typeFunction(f) for f in functions);
@@ -613,9 +624,6 @@ uniontype Call
613624
matchedFunc := checkMatchingFunctions(call,info);
614625

615626
func := matchedFunc.func;
616-
// Don't evaluate structural parameters for external functions, the code generation can't handle it in
617-
// some cases (see bug #4904). For constants we'll get issues no matter if we evaluate them or not,
618-
// but evaluating them will probably cause the last amount of issues.
619627
typed_args := matchedFunc.args;
620628

621629
args := {};
@@ -840,6 +848,7 @@ uniontype Call
840848

841849
function typeArgs
842850
input output Call call;
851+
input Boolean replaceConstants;
843852
input ExpOrigin.Type origin;
844853
input SourceInfo info;
845854
algorithm
@@ -856,7 +865,7 @@ uniontype Call
856865
algorithm
857866
typedArgs := {};
858867
for arg in call.arguments loop
859-
(arg, arg_ty, arg_var) := Typing.typeExp(arg, origin, info, replaceConstants = false);
868+
(arg, arg_ty, arg_var) := Typing.typeExp(arg, origin, info, replaceConstants = replaceConstants);
860869
typedArgs := (arg, arg_ty, arg_var) :: typedArgs;
861870
end for;
862871

@@ -865,7 +874,7 @@ uniontype Call
865874
typedNamedArgs := {};
866875
for narg in call.named_args loop
867876
(name,arg) := narg;
868-
(arg, arg_ty, arg_var) := Typing.typeExp(arg, origin, info, replaceConstants = false);
877+
(arg, arg_ty, arg_var) := Typing.typeExp(arg, origin, info, replaceConstants = replaceConstants);
869878
typedNamedArgs := (name, arg, arg_ty, arg_var) :: typedNamedArgs;
870879
end for;
871880

@@ -1512,6 +1521,18 @@ protected
15121521
callExp := Expression.CALL(call);
15131522
end typeStringCall;
15141523

1524+
function isExternal
1525+
input Call call;
1526+
output Boolean isExternal;
1527+
algorithm
1528+
isExternal := match call
1529+
case UNTYPED_CALL() then Class.isExternalFunction(InstNode.getClass(ComponentRef.node(call.ref)));
1530+
case ARG_TYPED_CALL() then Class.isExternalFunction(InstNode.getClass(ComponentRef.node(call.ref)));
1531+
case TYPED_CALL() then Function.isExternal(call.fn);
1532+
else false;
1533+
end match;
1534+
end isExternal;
1535+
15151536
protected
15161537
function typeDiscreteCall
15171538
"Types a function call that can be typed normally, but which always has

Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -528,35 +528,61 @@ public
528528
output Type ty;
529529
algorithm
530530
ty := match exp
531-
case INTEGER() then Type.INTEGER();
532-
case REAL() then Type.REAL();
533-
case STRING() then Type.STRING();
534-
case BOOLEAN() then Type.BOOLEAN();
535-
case ENUM_LITERAL() then exp.ty;
536-
case CREF() then exp.ty;
537-
case ARRAY() then exp.ty;
538-
case RANGE() then exp.ty;
539-
case TUPLE() then exp.ty;
540-
case RECORD() then exp.ty;
541-
case CALL() then Call.typeOf(exp.call);
542-
case SIZE(dimIndex = SOME(_)) then Type.INTEGER();
543-
case SIZE() then typeOf(exp.exp);
544-
case END() then Type.INTEGER();
545-
case BINARY() then Operator.typeOf(exp.operator);
546-
case UNARY() then Operator.typeOf(exp.operator);
547-
case LBINARY() then Operator.typeOf(exp.operator);
548-
case LUNARY() then Operator.typeOf(exp.operator);
549-
case RELATION() then Operator.typeOf(exp.operator);
550-
case IF() then typeOf(exp.trueBranch);
551-
case CAST() then exp.ty;
552-
case UNBOX() then exp.ty;
531+
case INTEGER() then Type.INTEGER();
532+
case REAL() then Type.REAL();
533+
case STRING() then Type.STRING();
534+
case BOOLEAN() then Type.BOOLEAN();
535+
case ENUM_LITERAL() then exp.ty;
536+
case CREF() then exp.ty;
537+
case ARRAY() then exp.ty;
538+
case RANGE() then exp.ty;
539+
case TUPLE() then exp.ty;
540+
case RECORD() then exp.ty;
541+
case CALL() then Call.typeOf(exp.call);
542+
case SIZE() then if isSome(exp.dimIndex) then
543+
Type.INTEGER() else typeOf(exp.exp);
544+
case END() then Type.INTEGER();
545+
case BINARY() then Operator.typeOf(exp.operator);
546+
case UNARY() then Operator.typeOf(exp.operator);
547+
case LBINARY() then Operator.typeOf(exp.operator);
548+
case LUNARY() then Operator.typeOf(exp.operator);
549+
case RELATION() then Operator.typeOf(exp.operator);
550+
case IF() then typeOf(exp.trueBranch);
551+
case CAST() then exp.ty;
552+
case UNBOX() then exp.ty;
553553
case SUBSCRIPTED_EXP() then exp.ty;
554-
case TUPLE_ELEMENT() then exp.ty;
555-
case BOX() then Type.METABOXED(typeOf(exp.exp));
554+
case TUPLE_ELEMENT() then exp.ty;
555+
case BOX() then Type.METABOXED(typeOf(exp.exp));
556556
else Type.UNKNOWN();
557557
end match;
558558
end typeOf;
559559

560+
function setType
561+
input Type ty;
562+
input output Expression exp;
563+
algorithm
564+
() := match exp
565+
case ENUM_LITERAL() algorithm exp.ty := ty; then ();
566+
case CREF() algorithm exp.ty := ty; then ();
567+
case TYPENAME() algorithm exp.ty := ty; then ();
568+
case ARRAY() algorithm exp.ty := ty; then ();
569+
case RANGE() algorithm exp.ty := ty; then ();
570+
case TUPLE() algorithm exp.ty := ty; then ();
571+
case RECORD() algorithm exp.ty := ty; then ();
572+
case CALL() algorithm exp.call := Call.setType(exp.call, ty); then ();
573+
case BINARY() algorithm exp.operator := Operator.setType(ty, exp.operator); then ();
574+
case UNARY() algorithm exp.operator := Operator.setType(ty, exp.operator); then ();
575+
case LBINARY() algorithm exp.operator := Operator.setType(ty, exp.operator); then ();
576+
case LUNARY() algorithm exp.operator := Operator.setType(ty, exp.operator); then ();
577+
case RELATION() algorithm exp.operator := Operator.setType(ty, exp.operator); then ();
578+
case CAST() algorithm exp.ty := ty; then ();
579+
case UNBOX() algorithm exp.ty := ty; then ();
580+
case SUBSCRIPTED_EXP() algorithm exp.ty := ty; then ();
581+
case TUPLE_ELEMENT() algorithm exp.ty := ty; then ();
582+
else ();
583+
end match;
584+
end setType;
585+
560586
function typeCast
561587
input Expression exp;
562588
input Type castTy;
@@ -3491,5 +3517,16 @@ public
34913517
end match;
34923518
end lookupRecordField;
34933519

3520+
function enumIndexExp
3521+
input Expression enumExp;
3522+
output Expression indexExp;
3523+
algorithm
3524+
indexExp := match enumExp
3525+
case ENUM_LITERAL() then INTEGER(enumExp.index);
3526+
else CALL(Call.makeBuiltinCall(
3527+
NFBuiltinFuncs.INTEGER_ENUM, {enumExp}, variability(enumExp)));
3528+
end match;
3529+
end enumIndexExp;
3530+
34943531
annotation(__OpenModelica_Interface="frontend");
34953532
end NFExpression;

Compiler/NFFrontEnd/NFInline.mo

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ import DAE.InlineType;
3939
import NFFunction.Function;
4040
import NFInstNode.InstNode;
4141
import Subscript = NFSubscript;
42+
import Dimension = NFDimension;
43+
import Type = NFType;
4244

4345
function inlineCallExp
4446
input Expression callExp;
@@ -95,6 +97,9 @@ algorithm
9597

9698
stmt := listHead(body);
9799

100+
// TODO: Instead of repeating this for each input we should probably
101+
// just build a lookup tree or hash table and go through the
102+
// statement once.
98103
for i in inputs loop
99104
arg :: args := args;
100105
stmt := Statement.mapExp(stmt,
@@ -112,12 +117,13 @@ function replaceCrefNode
112117
input output Expression exp;
113118
input InstNode node;
114119
input Expression value;
120+
protected
121+
InstNode cr_node;
122+
ComponentRef rest_cr;
123+
list<Subscript> subs;
124+
Type ty, repl_ty;
115125
algorithm
116126
exp := match exp
117-
local
118-
InstNode cr_node;
119-
ComponentRef rest_cr;
120-
list<Subscript> subs;
121127

122128
// TODO: This only works for simple crefs, for complex crefs (i.e. records)
123129
// we need to somehow replace the rest of the cref with nodes from the
@@ -128,8 +134,35 @@ algorithm
128134

129135
else exp;
130136
end match;
137+
138+
// Replace expressions in dimensions too.
139+
ty := Expression.typeOf(exp);
140+
repl_ty := Type.mapDims(ty, function replaceDimExp(node = node, value = value));
141+
142+
if not referenceEq(ty, repl_ty) then
143+
exp := Expression.setType(repl_ty, exp);
144+
end if;
131145
end replaceCrefNode;
132146

147+
function replaceDimExp
148+
input output Dimension dim;
149+
input InstNode node;
150+
input Expression value;
151+
algorithm
152+
dim := match dim
153+
local
154+
Expression exp;
155+
156+
case Dimension.EXP()
157+
algorithm
158+
exp := Expression.map(dim.exp, function replaceCrefNode(node = node, value = value));
159+
then
160+
Dimension.fromExp(exp, dim.var);
161+
162+
else dim;
163+
end match;
164+
end replaceDimExp;
165+
133166
function getOutputExp
134167
input Statement stmt;
135168
input InstNode outputNode;

Compiler/NFFrontEnd/NFType.mo

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,43 @@ public
517517
end match;
518518
end dimensionCount;
519519

520+
function mapDims
521+
input output Type ty;
522+
input FuncT func;
523+
524+
partial function FuncT
525+
input output Dimension dim;
526+
end FuncT;
527+
algorithm
528+
() := match ty
529+
case ARRAY()
530+
algorithm
531+
ty.dimensions := list(func(d) for d in ty.dimensions);
532+
then
533+
();
534+
535+
case TUPLE()
536+
algorithm
537+
ty.types := list(mapDims(t, func) for t in ty.types);
538+
then
539+
();
540+
541+
case FUNCTION()
542+
algorithm
543+
ty.resultType := mapDims(ty.resultType, func);
544+
then
545+
();
546+
547+
case METABOXED()
548+
algorithm
549+
ty.ty := mapDims(ty.ty, func);
550+
then
551+
();
552+
553+
else ();
554+
end match;
555+
end mapDims;
556+
520557
function nthEnumLiteral
521558
input Type ty;
522559
input Integer index;

0 commit comments

Comments
 (0)