Skip to content

Commit

Permalink
[NF] Various fixes.
Browse files Browse the repository at this point in the history
- Fix ExpressionSimplify.evalCat so that it doesn't reverse the
  arguments when dim == 1.
- Disabled constant evaluation of function call arguments during typing.
- Added constant evaluation of ranges.

Belonging to [master]:
  - OpenModelica/OMCompiler#2400
  • Loading branch information
perost authored and OpenModelica-Hudson committed Apr 27, 2018
1 parent 3aae2a0 commit 81ba868
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Compiler/FrontEnd/ExpressionSimplify.mo
Expand Up @@ -1636,7 +1636,7 @@ algorithm
true := dim >= 1;
false := listEmpty(exps);
if 1 == dim then
outExps := listAppend(getArrayContents(e) for e in exps);
outExps := listAppend(getArrayContents(e) for e in listReverse(exps));
outDims := {listLength(outExps)};
return;
end if;
Expand Down
31 changes: 16 additions & 15 deletions Compiler/NFFrontEnd/NFCall.mo
Expand Up @@ -589,26 +589,31 @@ uniontype Call
protected
Function func;
list<Expression> args;
list<Type> arg_ty;
list<Variability> arg_var;
CallAttributes ca;
list<TypedArg> typed_args;
MatchedFunction matchedFunc;
InstNode scope;
Variability var;
Variability var, arg_var;
Type ty;
Expression arg_exp;
algorithm
ARG_TYPED_CALL(call_scope = scope) := call;
matchedFunc := checkMatchingFunctions(call,info);

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

args := {};
var := Variability.CONSTANT;
for a in typed_args loop
var := Prefixes.variabilityMax(var, Util.tuple33(a));
(arg_exp, _, arg_var) := a;
args := arg_exp :: args;
var := Prefixes.variabilityMax(var, arg_var);
end for;
args := listReverseInPlace(args);

ty := Function.returnType(func);

Expand Down Expand Up @@ -845,7 +850,7 @@ uniontype Call
algorithm
typedArgs := {};
for arg in call.arguments loop
(arg, arg_ty, arg_var) := Typing.typeExp(arg, origin, info);
(arg, arg_ty, arg_var) := Typing.typeExp(arg, origin, info, replaceConstants = false);
typedArgs := (arg, arg_ty, arg_var) :: typedArgs;
end for;

Expand All @@ -854,7 +859,7 @@ uniontype Call
typedNamedArgs := {};
for narg in call.named_args loop
(name,arg) := narg;
(arg, arg_ty, arg_var) := Typing.typeExp(arg, origin, info);
(arg, arg_ty, arg_var) := Typing.typeExp(arg, origin, info, replaceConstants = false);
typedNamedArgs := (name, arg, arg_ty, arg_var) :: typedNamedArgs;
end for;

Expand Down Expand Up @@ -1521,8 +1526,7 @@ protected
list<TypedArg> args;
TypedArg start,interval;
algorithm
argtycall := typeNormalCall(call, origin, info);
argtycall := matchTypedNormalCall(argtycall, origin, info);
argtycall := typeMatchNormalCall(call, origin, info);
ty := getType(argtycall);
callExp := Expression.CALL(unboxArgs(argtycall));
end typeDiscreteCall;
Expand Down Expand Up @@ -1762,8 +1766,7 @@ protected
protected
Call argtycall;
algorithm
argtycall := typeNormalCall(call, origin, info);
argtycall := matchTypedNormalCall(argtycall, origin, info);
argtycall := typeMatchNormalCall(call, origin, info);
argtycall := unboxArgs(argtycall);
ty := getType(argtycall);
var := variability(argtycall);
Expand All @@ -1784,8 +1787,7 @@ protected
Call argtycall;
algorithm
// TODO: Rewrite this whole thing.
argtycall := typeNormalCall(call, origin, info);
argtycall := matchTypedNormalCall(argtycall, origin, info);
argtycall := typeMatchNormalCall(call, origin, info);
argtycall := unboxArgs(argtycall);
ty := getType(argtycall);
var := variability(argtycall);
Expand Down Expand Up @@ -2289,8 +2291,7 @@ protected
protected
Call argtycall;
algorithm
argtycall := typeNormalCall(call, origin, info);
argtycall := matchTypedNormalCall(argtycall, origin, info);
argtycall := typeMatchNormalCall(call, origin, info);

ty := getType(argtycall);
var := variability(argtycall);
Expand Down
78 changes: 74 additions & 4 deletions Compiler/NFFrontEnd/NFCeval.mo
Expand Up @@ -149,16 +149,14 @@ algorithm
then
exp;

// Ranges could be evaluated into arrays, but that's less efficient in some
// cases. So here we just evaluate the range's expressions, and let the
// caller worry about vectorization.
case Expression.RANGE()
algorithm
exp1 := evalExp(exp.start, target);
oexp := evalExpOpt(exp.step, target);
exp3 := evalExp(exp.stop, target);
then
Expression.RANGE(exp.ty, exp1, oexp, exp3);
if EvalTarget.isRange(target) then
Expression.RANGE(exp.ty, exp1, oexp, exp3) else evalRange(exp1, oexp, exp3);

case Expression.RECORD()
algorithm
Expand Down Expand Up @@ -295,6 +293,78 @@ algorithm
end if;
end evalTypename;

function evalRange
input Expression start;
input Option<Expression> optStep;
input Expression stop;
output Expression exp;
protected
Expression step;
list<Expression> expl;
Type ty;
list<String> literals;
Integer istep;
algorithm
if isSome(optStep) then
SOME(step) := optStep;

(ty, expl) := match (start, step, stop)
case (Expression.INTEGER(), Expression.INTEGER(istep), Expression.INTEGER())
algorithm
// The compiler decided to randomly dislike using step.value here, hence istep.
expl := list(Expression.INTEGER(i) for i in start.value:istep:stop.value);
then
(Type.INTEGER(), expl);

case (Expression.REAL(), Expression.REAL(), Expression.REAL())
algorithm
expl := list(Expression.REAL(r) for r in start.value:step.value:stop.value);
then
(Type.REAL(), expl);

else
algorithm
printWrongArgsError(getInstanceName(), {start, step, stop}, sourceInfo());
then
fail();
end match;
else
(ty, expl) := match (start, stop)
case (Expression.INTEGER(), Expression.INTEGER())
algorithm
expl := list(Expression.INTEGER(i) for i in start.value:stop.value);
then
(Type.INTEGER(), expl);

case (Expression.REAL(), Expression.REAL())
algorithm
expl := list(Expression.REAL(r) for r in start.value:stop.value);
then
(Type.REAL(), expl);

case (Expression.BOOLEAN(), Expression.BOOLEAN())
algorithm
expl := list(Expression.BOOLEAN(b) for b in start.value:stop.value);
then
(Type.BOOLEAN(), expl);

case (Expression.ENUM_LITERAL(ty = ty as Type.ENUMERATION()), Expression.ENUM_LITERAL())
algorithm
expl := list(Expression.ENUM_LITERAL(ty, listGet(ty.literals, i), i) for i in start.index:stop.index);
then
(ty, expl);

else
algorithm
printWrongArgsError(getInstanceName(), {start, stop}, sourceInfo());
then
fail();
end match;
end if;

exp := Expression.ARRAY(Type.ARRAY(ty, {Dimension.fromInteger(listLength(expl))}), expl);
end evalRange;

function printFailedEvalError
input String name;
input Expression exp;
Expand Down
12 changes: 12 additions & 0 deletions Compiler/NFFrontEnd/NFClass.mo
Expand Up @@ -467,6 +467,18 @@ uniontype Class
output Boolean isFunction = Restriction.isFunction(restriction(cls));
end isFunction;

function isExternalFunction
input Class cls;
output Boolean isExtFunc;
algorithm
isExtFunc := match cls
case EXPANDED_DERIVED() then isExternalFunction(InstNode.getClass(cls.baseClass));
case INSTANCED_CLASS(sections = Sections.EXTERNAL()) then true;
case TYPED_DERIVED() then isExternalFunction(InstNode.getClass(cls.baseClass));
else false;
end match;
end isExternalFunction;

function getPrefixes
input Class cls;
output Prefixes prefs;
Expand Down
5 changes: 5 additions & 0 deletions Compiler/NFFrontEnd/NFFunction.mo
Expand Up @@ -1079,6 +1079,11 @@ uniontype Function
output Boolean isPointer = fn.attributes.isFunctionPointer;
end isFunctionPointer;

function isExternal
input Function fn;
output Boolean isExternal = Class.isExternalFunction(InstNode.getClass(fn.node));
end isExternal;

function inlineBuiltin
input Function fn;
output DAE.InlineType inlineType;
Expand Down
5 changes: 3 additions & 2 deletions Compiler/NFFrontEnd/NFTyping.mo
Expand Up @@ -409,7 +409,7 @@ algorithm
() := match c
case Component.ITERATOR(binding = Binding.UNTYPED_BINDING(), info = info)
algorithm
binding := typeBinding(c.binding, intBitOr(origin, ExpOrigin.ITERATION_RANGE));
binding := typeBinding(c.binding, intBitOr(origin, ExpOrigin.ITERATION_RANGE), replaceConstants = false);

// If the iteration range is structural, it must be a parameter expression.
if structural then
Expand Down Expand Up @@ -761,6 +761,7 @@ end typeComponentBinding;
function typeBinding
input output Binding binding;
input ExpOrigin.Type origin;
input Boolean replaceConstants = true;
algorithm
binding := match binding
local
Expand All @@ -772,7 +773,7 @@ algorithm
case Binding.UNTYPED_BINDING(bindingExp = exp)
algorithm
info := Binding.getInfo(binding);
(exp, ty, var) := typeExp(exp, origin, info);
(exp, ty, var) := typeExp(exp, origin, info, replaceConstants);
then
Binding.TYPED_BINDING(exp, ty, var, binding.origin, binding.isEach);

Expand Down

0 comments on commit 81ba868

Please sign in to comment.