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

Commit cdf224b

Browse files
sjoelundOpenModelica-Hudson
authored andcommitted
Some work-arounds for Ceval of zero-size arrays
The Values.mo structure does not store the type of the array which means that `Values.ARRAY({})` becomes `{} /* T_UNKNOWN[0] */` instead of containing the actual type. We now have some work-arounds for this case: - cevalIfConstant will not try to evaluate literal values - If an empty array is returned in cevalIfConstant, we backpatch the array type to the expected type (but this only works for the top-level expression; hopefully this is enough to not propagate unknown dimensions too far though). Belonging to [master]: - #2074
1 parent d1a57b2 commit cdf224b

4 files changed

Lines changed: 62 additions & 67 deletions

File tree

Compiler/FrontEnd/Ceval.mo

Lines changed: 43 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -885,79 +885,63 @@ public function cevalIfConstant
885885
or if the expression is a call of parameter constness whose return type
886886
contains unknown dimensions (in which case we need to determine the size of
887887
those dimensions)."
888-
input FCore.Cache inCache;
888+
input output FCore.Cache cache;
889889
input FCore.Graph inEnv;
890-
input DAE.Exp inExp;
891-
input DAE.Properties inProp;
890+
input output DAE.Exp exp;
891+
input output DAE.Properties prop;
892892
input Boolean impl;
893893
input SourceInfo inInfo;
894-
output FCore.Cache outCache;
895-
output DAE.Exp outExp;
896-
output DAE.Properties outProp;
897894
algorithm
898-
(outCache, outExp, outProp) :=
899-
matchcontinue(inCache, inEnv, inExp, inProp, impl, inInfo)
895+
if Expression.isEvaluatedConst(exp) then
896+
// Don't mess up the dimensions, etc by using the Values module
897+
return;
898+
end if;
899+
(cache, exp, prop) := matchcontinue prop
900900
local
901-
DAE.Exp e;
902-
Values.Value v;
903-
FCore.Cache cache;
904-
DAE.Properties prop;
901+
Values.Value v;
905902
DAE.Type tp;
906903

907-
/* adrpo: this is not needed! we do dimension propagation on function call!
908-
case (_, _, e as DAE.CALL(attr = DAE.CALL_ATTR(ty = DAE.T_ARRAY(dims = _))),
909-
DAE.PROP(constFlag = DAE.C_PARAM()), _, _)
910-
equation
911-
(e, prop) = cevalWholedimRetCall(e, inCache, inEnv, inInfo, 0);
912-
then
913-
(inCache, e, prop);*/
914-
915-
case (_, _, e, DAE.PROP(constFlag = DAE.C_PARAM(), type_ = tp), _, _) // BoschRexroth specifics
916-
equation
917-
false = Flags.getConfigBool(Flags.CEVAL_EQUATION);
918-
then
919-
(inCache, e, DAE.PROP(tp, DAE.C_VAR()));
920-
921-
case (_, _, e, DAE.PROP(constFlag = DAE.C_CONST()), _, _)
922-
equation
923-
(cache, v, _) = ceval(inCache, inEnv, e, impl, NONE(), Absyn.NO_MSG(), 0);
924-
e = ValuesUtil.valueExp(v);
925-
then
926-
(cache, e, inProp);
904+
case DAE.PROP(constFlag = DAE.C_PARAM(), type_ = tp)
905+
// BoschRexroth specifics
906+
guard not Flags.getConfigBool(Flags.CEVAL_EQUATION)
907+
then (cache, exp, DAE.PROP(tp, DAE.C_VAR()));
927908

928-
case (_, _, e, DAE.PROP_TUPLE(), _, _)
929-
equation
930-
DAE.C_CONST() = Types.propAllConst(inProp);
931-
(cache, v, _) = ceval(inCache, inEnv, e, false, NONE(), Absyn.NO_MSG(), 0);
932-
e = ValuesUtil.valueExp(v);
933-
then
934-
(cache, e, inProp);
909+
case DAE.PROP(constFlag = DAE.C_CONST(), type_ = tp)
910+
algorithm
911+
(cache, v, _) := ceval(cache, inEnv, exp, impl, NONE(), Absyn.NO_MSG(), 0);
912+
exp := ValuesUtil.valueExp(v);
913+
exp := ValuesUtil.fixZeroSizeArray(exp, tp);
914+
then (cache, exp, prop);
935915

936-
case (_, _, _, DAE.PROP_TUPLE(), _, _) // BoschRexroth specifics
937-
equation
938-
false = Flags.getConfigBool(Flags.CEVAL_EQUATION);
939-
DAE.C_PARAM() = Types.propAllConst(inProp);
916+
case DAE.PROP_TUPLE()
917+
algorithm
918+
DAE.C_CONST() := Types.propAllConst(prop);
919+
(cache, v, _) := ceval(cache, inEnv, exp, false, NONE(), Absyn.NO_MSG(), 0);
920+
exp := ValuesUtil.valueExp(v);
921+
then (cache, exp, prop);
922+
923+
case DAE.PROP_TUPLE()
924+
// BoschRexroth specifics
925+
guard not Flags.getConfigBool(Flags.CEVAL_EQUATION)
926+
algorithm
927+
DAE.C_PARAM() := Types.propAllConst(prop);
940928
print(" tuple non constant evaluation not implemented yet\n");
941-
then
942-
fail();
929+
then fail();
943930

944-
case (_, _, e, _, _, _)
945-
equation
946-
true = Expression.isConst(e); // Structural parameters and the like... we can ceval them if we want to
947-
false = Config.acceptMetaModelicaGrammar();
948-
// false = Expression.isConstValue(e);
949-
// print("Try ceval: " + ExpressionDump.printExpStr(e) + "; expect " + Types.unparseType(Types.getPropType(inProp)) + "\n");
950-
(_, v, _) = ceval(inCache, inEnv, e, impl, NONE(), Absyn.NO_MSG(), 0);
951-
// print("Ceval'ed constant: " + ExpressionDump.printExpStr(inExp) + " => " + ValuesUtil.valString(v) + "\n");
952-
e = ValuesUtil.valueExp(v);
953-
// print("Ceval'ed constant: " + ExpressionDump.printExpStr(inExp) + "\n");
954-
then (inCache, e, inProp);
931+
case _
932+
// Structural parameters and the like... we can ceval them if we want to
933+
guard Expression.isConst(exp) and not Config.acceptMetaModelicaGrammar()
934+
algorithm
935+
(_, v, _) := ceval(cache, inEnv, exp, impl, NONE(), Absyn.NO_MSG(), 0);
936+
exp := ValuesUtil.valueExp(v);
937+
exp := ValuesUtil.fixZeroSizeArray(exp, Types.getPropType(prop));
938+
then (cache, exp, prop);
955939

956940
else
957-
equation
941+
algorithm
958942
// If we fail to evaluate, at least we should simplify the expression
959-
(e,_) = ExpressionSimplify.simplify1(inExp);
960-
then (inCache, e, inProp);
943+
(exp,_) := ExpressionSimplify.simplify1(exp);
944+
then (cache, exp, prop);
961945

962946
end matchcontinue;
963947
end cevalIfConstant;

Compiler/FrontEnd/ExpressionSimplify.mo

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,10 @@ algorithm
13001300
e = Expression.makeImpureBuiltinCall("delay",{e,e3,e4},tp);
13011301
then DAE.UNARY(op,e);
13021302

1303+
// The sum of an empty array is simply the sum of its elements
1304+
case DAE.CALL(path=Absyn.IDENT("sum"),expLst={DAE.ARRAY(array={})}, attr=DAE.CALL_ATTR(ty=tp1))
1305+
then Expression.makeConstZero(tp1);
1306+
13031307
// To calculate sums, first try matrix concatenation
13041308
case DAE.CALL(path=Absyn.IDENT("sum"),expLst={DAE.MATRIX(ty=tp1,matrix=mexpl)},attr=DAE.CALL_ATTR(ty=tp2))
13051309
equation

Compiler/FrontEnd/Static.mo

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8462,10 +8462,8 @@ algorithm
84628462
// checkModel this should succeed anyway, since we might be checking a function
84638463
// that takes a vector of unknown size. So pretend that the dimension is 1.
84648464
case (e, (DAE.DIM_UNKNOWN() :: ad), prop)
8465-
algorithm
8466-
true := Flags.getConfigBool(Flags.CHECK_MODEL);
8467-
then
8468-
vectorizeCall(e, DAE.DIM_INTEGER(1) :: ad, inSlots, prop, info);
8465+
guard Flags.getConfigBool(Flags.CHECK_MODEL)
8466+
then vectorizeCall(e, DAE.DIM_INTEGER(1) :: ad, inSlots, prop, info);
84698467

84708468
/* Scalar expression, i.e function call */
84718469
case (e as DAE.CALL(),(dim :: ad),DAE.PROP(tp,c))
@@ -8474,8 +8472,7 @@ algorithm
84748472
exp_type := Types.simplifyType(Types.liftArray(tp, dim)) "pass type of vectorized result expr";
84758473
vect_exp := vectorizeCallScalar(e, exp_type, int_dim, inSlots);
84768474
tp := Types.liftArray(tp, dim);
8477-
then
8478-
vectorizeCall(vect_exp, ad, inSlots, DAE.PROP(tp,c),info);
8475+
then vectorizeCall(vect_exp, ad, inSlots, DAE.PROP(tp,c),info);
84798476

84808477
/* array expression of function calls */
84818478
case (DAE.ARRAY(),(dim :: ad),DAE.PROP(tp,c))
@@ -8484,8 +8481,7 @@ algorithm
84848481
// _ = Types.simplifyType(Types.liftArray(tp, dim));
84858482
vect_exp := vectorizeCallArray(inExp, int_dim, inSlots);
84868483
tp := Types.liftArrayRight(tp, dim);
8487-
then
8488-
vectorizeCall(vect_exp, ad, inSlots, DAE.PROP(tp,c),info);
8484+
then vectorizeCall(vect_exp, ad, inSlots, DAE.PROP(tp,c),info);
84898485

84908486
/* Multiple dimensions are possible to change to a reduction, like:
84918487
* f(arr1,arr2) => array(f(x,y) thread for x in arr1, y in arr2)

Compiler/FrontEnd/ValuesUtil.mo

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2346,5 +2346,16 @@ algorithm
23462346
end match;
23472347
end typeConvertRecord;
23482348

2349+
public function fixZeroSizeArray "Work-around for Values.ARRAY({}) becoming T_UNKNOWN in ValuesUtil.valueExp"
2350+
input output DAE.Exp e;
2351+
input DAE.Type ty;
2352+
algorithm
2353+
e := match e
2354+
case DAE.ARRAY(ty=DAE.T_ARRAY(ty=DAE.T_UNKNOWN()), scalar=false, array={})
2355+
then DAE.ARRAY(ty, not Types.isArray(Types.unliftArray(ty)), {});
2356+
else e;
2357+
end match;
2358+
end fixZeroSizeArray;
2359+
23492360
annotation(__OpenModelica_Interface="frontend");
23502361
end ValuesUtil;

0 commit comments

Comments
 (0)