Skip to content

Commit

Permalink
Fix for #3669.
Browse files Browse the repository at this point in the history
- Rewrote InstVar.instArrayDimInteger to be more efficient, and more
  tail recursive than it claimed to be.
- Changed Lookup.makeDimensionSubscript so it uses DAE.RANGE for
  integer dimensions, instead of expanding to an array.
- Updated rest of the front end to handles range slices properly.
  • Loading branch information
perost committed Feb 9, 2016
1 parent 5018d90 commit f45a8b2
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 134 deletions.
41 changes: 37 additions & 4 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -12310,7 +12310,7 @@ algorithm
// That whole creating IM should be done the way checkModel works. but it's not. :( so
// we have this.
case DAE.INDEX(exp = DAE.ARRAY())
then expandSlice(inSubscript.exp);
then expandSliceExp(inSubscript.exp);

// An index subscript, return it as an array.
case DAE.INDEX() then {inSubscript};
Expand All @@ -12321,7 +12321,7 @@ algorithm

// A slice subscript.
case DAE.SLICE()
then expandSlice(inSubscript.exp);
then expandSliceExp(inSubscript.exp);

end match;
end expandSubscript;
Expand Down Expand Up @@ -12357,7 +12357,7 @@ algorithm
end match;
end expandDimension;

protected function expandSlice
public function expandSliceExp
"Expands a slice subscript expression."
input DAE.Exp inSliceExp;
output list<DAE.Subscript> outSubscripts;
Expand All @@ -12370,8 +12370,11 @@ algorithm
case DAE.ARRAY(array = expl)
then List.map(expl, makeIndexSubscript);

case DAE.RANGE()
then List.map(Expression.expandRange(inSliceExp), makeIndexSubscript);

end match;
end expandSlice;
end expandSliceExp;

public function dimensionSizesSubscripts
input list<Integer> inDimSizes;
Expand Down Expand Up @@ -12868,5 +12871,35 @@ algorithm
outContinue := not outContainsCall;
end containsAnyCall_traverser;

public function rangeSize
"Tries to figure out the size of a range expression. Either return the size or
fails."
input DAE.Exp inRange;
output Integer outSize;
algorithm
outSize := match inRange
local
Integer start, step, stop;

case DAE.RANGE(start = DAE.ICONST(start),
step = NONE(),
stop = DAE.ICONST(stop))
then max(stop - start, 0);

case DAE.RANGE(start = DAE.ICONST(start),
step = SOME(DAE.ICONST(step)),
stop = DAE.ICONST(stop))
algorithm
if step <> 0 then
outSize := max(realInt(floor(realDiv(stop - start, step))) + 1, 0);
else
fail();
end if;
then
outSize;

end match;
end rangeSize;

annotation(__OpenModelica_Interface="frontend");
end Expression;
45 changes: 23 additions & 22 deletions Compiler/FrontEnd/ExpressionSimplify.mo
Expand Up @@ -1749,7 +1749,7 @@ protected function simplifyCref
input Type inType;
output DAE.Exp exp;
algorithm
exp := matchcontinue (origExp, inCREF, inType)
exp := matchcontinue inCREF
local
Type t,t2,t3;
list<Subscript> ssl;
Expand All @@ -1759,32 +1759,21 @@ algorithm
DAE.Exp expCref;
Integer index;

case(_,DAE.CREF_IDENT(idn,t2,(ssl as ((DAE.SLICE(DAE.ARRAY(_,_,_))) :: _))),t)
case DAE.CREF_IDENT(idn,t2,(ssl as ((DAE.SLICE(DAE.ARRAY(_,_,_))) :: _)))
equation
cr = ComponentReference.makeCrefIdent(idn,t2,{});
expCref = Expression.makeCrefExp(cr,t);
expCref = Expression.makeCrefExp(cr, inType);
exp = simplifyCref2(expCref,ssl);
then exp;

/*
case (_, DAE.CREF_QUAL(idn,t2 as DAE.T_METATYPE(DAE.T_METAARRAY()),ssl,DAE.CREF_IDENT(idn2,t3)),t)
equation
exp = DAE.ASUB(DAE.CREF(DAE.CREF_IDENT(idn,t2,{}),t2), list(Expression.subscriptIndexExp(s) for s in ssl));
print(ExpressionDump.printExpStr(exp) + "\n");
index = match tt as Types.metaArrayElementType(t2)
// case DAE.T_METARECORD() then t2.fields;
case DAE.T_METAUNIONTYPE() then List.position(idn2, tt.singletonFields);
end match;
exp = DAE.RSUB(exp, index, idn2, t);
print(ExpressionDump.printExpStr(origExp) + "\n");
print(ExpressionDump.printExpStr(exp) + "\n");
print("CREF_QUAL: " + idn + "\n");
print("CREF_QUAL: " + Types.unparseType(t2) + "\n");
print("CREF_QUAL: " + Types.unparseType(t) + "\n");
print("CREF_QUAL: " + Types.unparseType(t3) + "\n");
then exp;
*/
case (_, DAE.CREF_QUAL(idn, DAE.T_METATYPE(ty=t2), ssl, cr), t)
case DAE.CREF_IDENT(subscriptLst = DAE.SLICE(exp = DAE.RANGE()) :: _)
algorithm
cr := ComponentReference.crefStripSubs(inCREF);
expCref := Expression.makeCrefExp(cr, inType);
then
simplifyCref2(expCref, inCREF.subscriptLst);

case DAE.CREF_QUAL(idn, DAE.T_METATYPE(ty=t2), ssl, cr)
equation
exp = simplifyCrefMM1(idn, t2, ssl);
exp = simplifyCrefMM(exp, Expression.typeof(exp), cr);
Expand Down Expand Up @@ -1827,6 +1816,18 @@ algorithm
then
exp;

case (DAE.CREF(cr as DAE.CREF_IDENT(), t),
(ss as DAE.SLICE(exp = DAE.RANGE())) :: ssl)
algorithm
subs := Expression.expandSliceExp(ss.exp);
crefs := list(ComponentReference.subscriptCref(cr, List.create(s)) for s in subs);
t := Types.unliftArray(t);
expl := list(Expression.makeCrefExp(cr, t) for cr in crefs);
dim := listLength(expl);
exp := DAE.ARRAY(DAE.T_ARRAY(t, {DAE.DIM_INTEGER(dim)}, DAE.emptyTypeSource), true, expl);
then
simplifyCref2(exp, ssl);

case(DAE.ARRAY(tp,sc,expl), ssl )
equation
expl = List.map1(expl,simplifyCref2,ssl);
Expand Down
143 changes: 51 additions & 92 deletions Compiler/FrontEnd/InstVar.mo
Expand Up @@ -1614,7 +1614,7 @@ algorithm
// Handle DIM_INTEGER, where the dimension is >0
case (cache,env,ih,store,ci_state,_,_,_,(_,_),_,_,DAE.DIM_INTEGER(integer = stop),_,_,_,_,_,_,graph,csets)
equation
(cache,env,ih,store,dae,csets,ty,graph) = instArrayDimInteger(cache,env,ih,store,ci_state,inMod,inPrefix,inIdent,inElement,inPrefixes,stop,inDimensionLst,inIntegerLst,inInstDims,inBoolean,inComment,info,graph,csets,DAE.emptyDae);
(cache,env,ih,store,dae,csets,ty,graph) = instArrayDimInteger(cache,env,ih,store,ci_state,inMod,inPrefix,inIdent,inElement,inPrefixes,stop,inDimensionLst,inIntegerLst,inInstDims,inBoolean,inComment,info,graph,csets);
then
(cache,env,ih,store,dae,csets,ty,graph);

Expand Down Expand Up @@ -1668,113 +1668,72 @@ Special case for DIM_INTEGER: tail-recursive implementation since the number of
input ClassInf.State inState;
input DAE.Mod inMod;
input Prefix.Prefix inPrefix;
input String inIdent;
input String inName;
input tuple<SCode.Element, SCode.Attributes> inElement;
input SCode.Prefixes inPrefixes;
input Integer thisDim;
input DAE.Dimensions inDimensionLst;
input list<DAE.Subscript> inIntegerLst;
input Integer inDimensionSize;
input DAE.Dimensions inRestDimensions;
input list<DAE.Subscript> inSubscripts;
input list<list<DAE.Dimension>> inInstDims;
input Boolean inBoolean;
input Boolean inImpl;
input SCode.Comment inComment;
input SourceInfo info;
input SourceInfo inInfo;
input ConnectionGraph.ConnectionGraph inGraph;
input Connect.Sets inSets;
input DAE.DAElist accDae;
output FCore.Cache outCache;
output FCore.Graph outEnv;
output InnerOuter.InstHierarchy outIH;
output UnitAbsyn.InstStore outStore;
output DAE.DAElist outDae;
output Connect.Sets outSets;
output DAE.Type outType;
output ConnectionGraph.ConnectionGraph outGraph;
output FCore.Cache outCache = inCache;
output FCore.Graph outEnv = inEnv;
output InnerOuter.InstHierarchy outIH = inIH;
output UnitAbsyn.InstStore outStore = inStore;
output DAE.DAElist outDae = DAE.emptyDae;
output Connect.Sets outSets = inSets;
output DAE.Type outType = DAE.T_UNKNOWN_DEFAULT;
output ConnectionGraph.ConnectionGraph outGraph = inGraph;
protected
SCode.Element c, cls;
DAE.Mod mod, imod;
Absyn.Path cls_path;
SCode.Mod smod;
SCode.Attributes attr;
DAE.Exp e;
DAE.Subscript s;
list<list<DAE.Dimension>> inst_dims;
DAE.DAElist dae;
algorithm
(outCache,outEnv,outIH,outStore,outDae,outSets,outType,outGraph) :=
match (inCache,inEnv,inIH,inStore,inState,inMod,inPrefix,inIdent,inElement,inPrefixes,thisDim,inDimensionLst,inIntegerLst,inInstDims,inBoolean,inComment,info,inGraph,inSets,accDae)
local
DAE.Exp e,lhs,rhs;
DAE.Properties p;
FCore.Cache cache;
FCore.Graph env_1,env_2,env,compenv;
Connect.Sets csets;
DAE.Type ty;
ClassInf.State st,ci_state;
DAE.ComponentRef cr;
DAE.Type ty_1;
DAE.Mod mod,mod_1,mod_2;
Prefix.Prefix pre;
String n, str1, str2, str3, str4;
SCode.Element cl;
SCode.Attributes attr;
Integer i,stop,i_1;
DAE.Dimension dim;
DAE.Dimensions dims;
list<DAE.Subscript> idxs;
InstDims inst_dims;
Boolean impl;
SCode.Comment comment;
DAE.DAElist dae,dae1,dae2,daeLst;
ConnectionGraph.ConnectionGraph graph;
InstanceHierarchy ih;
DAE.ElementSource source "the origin of the element";
DAE.Subscript s;
SCode.Element clBase;
Absyn.Path path;
SCode.Attributes absynAttr;
SCode.Mod scodeMod;
DAE.Mod mod2, mod3;
String lit;
list<String> l;
Integer enum_size;
Absyn.Path enum_type, enum_lit;
SCode.Prefixes pf;
UnitAbsyn.InstStore store;

// Stop=true
case (cache,env,ih,store,_,_,_,_,(_,_),_,0,_,_,_,_,_,_,graph,csets,dae) then (cache,env,ih,store,dae,csets,DAE.T_UNKNOWN_DEFAULT,graph);

// Stop=false

// adrpo: if a class is derived WITH AN ARRAY DIMENSION we should instVar2 the derived from type not the actual type!!!
case (cache,env,ih,store,ci_state,mod,pre,n,
(cl as SCode.CLASS(classDef=SCode.DERIVED(typeSpec=Absyn.TPATH(path,SOME(_)),
modifications=scodeMod)),
attr),
pf,i,dims,idxs,_,impl,comment,_,graph, _, _)
equation
true = i > 0;
(_,clBase,_) = Lookup.lookupClass(cache, env, path, SOME(cl.info));
(cls, mod, attr, inst_dims) := match inElement
// adrpo: if a class is derived WITH AN ARRAY DIMENSION we should instVar2
// the derived from type not the actual type!!!
case (c as SCode.CLASS(classDef = SCode.DERIVED(
typeSpec = Absyn.TPATH(cls_path, SOME(_)), modifications = smod)),
attr)
algorithm
(_, cls, _) := Lookup.lookupClass(outCache, outEnv, cls_path, SOME(c.info));
/* adrpo: TODO: merge also the attributes, i.e.:
type A = input discrete flow Integer[3];
A x; <-- input discrete flow IS NOT propagated even if it should. FIXME!
*/
//SOME(attr3) = SCode.mergeAttributes(attr,SOME(absynAttr));

scodeMod = InstUtil.chainRedeclares(mod, scodeMod);

(_,mod2) = Mod.elabMod(cache, env, ih, pre, scodeMod, impl, Mod.DERIVED(path), info);
mod3 = Mod.merge(mod, mod2);
e = DAE.ICONST(i);
mod_1 = Mod.lookupIdxModification(mod3, e);
s = DAE.INDEX(e);
(cache,env_1,ih,store,dae1,csets,ty,graph) = instVar2(cache,env,ih, store,ci_state, mod_1, pre, n, clBase, attr, pf, dims, (s :: idxs), {} /* inst_dims */, impl, comment, info, graph, inSets);
(cache,_,ih,store,daeLst,csets,_,graph) = instArrayDimInteger(cache, env, ih, store, ci_state, mod, pre, n, (cl,attr), pf, i - 1, dims, idxs, {} /* inst_dims */, impl, comment,info,graph, csets, DAEUtil.joinDaes(dae1, accDae));
then
(cache,env_1,ih,store,daeLst,csets,ty,graph);

case (cache,env,ih,store,ci_state,mod,pre,n,(cl,attr),pf,i,dims,idxs,inst_dims,impl,comment,_,graph,csets,_)
equation
true = i > 0;
e = DAE.ICONST(i);
mod_1 = Mod.lookupIdxModification(mod, e);
s = DAE.INDEX(e);
(cache,env_1,ih,store,dae1,csets,ty,graph) = instVar2(cache,env,ih, store,ci_state, mod_1, pre, n, cl, attr, pf,dims, (s :: idxs), inst_dims, impl, comment,info,graph, csets);
(cache,_,ih,store,daeLst,csets,_,graph) = instArrayDimInteger(cache,env,ih,store, ci_state, mod, pre, n, (cl,attr), pf, i - 1, dims, idxs, inst_dims, impl, comment,info,graph, csets, DAEUtil.joinDaes(dae1, accDae));
smod := InstUtil.chainRedeclares(inMod, smod);
(_, mod) := Mod.elabMod(outCache, outEnv, outIH, inPrefix, smod, inImpl,
Mod.DERIVED(cls_path), inInfo);
mod := Mod.merge(inMod, mod);
then
(cache,env_1,ih,store,daeLst,csets,ty,graph);
(cls, mod, attr, {});

case (cls, attr) then (cls, inMod, attr, inInstDims);
end match;

for i in inDimensionSize:-1:1 loop
e := DAE.ICONST(i);
imod := Mod.lookupIdxModification(mod, e);
s := DAE.INDEX(e);

(outCache, outEnv, outIH, outStore, dae, outSets, outType, outGraph) :=
instVar2(outCache, inEnv, outIH, outStore, inState, imod, inPrefix,
inName, cls, attr, inPrefixes, inRestDimensions, s :: inSubscripts,
inst_dims, inImpl, inComment, inInfo, outGraph, outSets);
outDae := DAEUtil.joinDaes(dae, outDae);
end for;
end instArrayDimInteger;

protected function instArrayDimEnum
Expand Down
21 changes: 14 additions & 7 deletions Compiler/FrontEnd/Lookup.mo
Expand Up @@ -2644,8 +2644,9 @@ algorithm
DAE.Type t,t_1;
DAE.Dimension dim;
DAE.TypeSource ts;
DAE.Subscript sub;
list<DAE.Subscript> ys,s;
Integer sz,ind,dim_int;
Integer sz,ind,dim_int,step;
list<DAE.Exp> se;
DAE.Exp e;

Expand All @@ -2658,6 +2659,14 @@ algorithm
then
DAE.T_ARRAY(t_1,{dim},ts);

case (DAE.T_ARRAY(dims = {dim}, ty = t, source = ts),
DAE.SLICE(exp = e as DAE.RANGE()) :: ys)
algorithm
t_1 := checkSubscripts(t, ys);
dim_int := Expression.rangeSize(e);
then
DAE.T_ARRAY(t_1, {DAE.DIM_INTEGER(dim_int)}, ts);

case (DAE.T_ARRAY(dims = {dim}, ty = t, source = ts),
(DAE.SLICE(exp = DAE.ARRAY(array = se)) :: ys))
equation
Expand Down Expand Up @@ -3032,15 +3041,13 @@ algorithm

// Special case when addressing array[0].
case DAE.DIM_INTEGER(integer = 0)
then
DAE.SLICE(DAE.ARRAY(DAE.T_INTEGER_DEFAULT, true, {DAE.ICONST(0)}));
then DAE.SLICE(DAE.ARRAY(DAE.T_INTEGER_DEFAULT, true, {DAE.ICONST(0)}));

// Array with integer dimension.
case DAE.DIM_INTEGER(integer = sz)
equation
expl = List.map(List.intRange(sz), Expression.makeIntegerExp);
then
DAE.SLICE(DAE.ARRAY(DAE.T_INTEGER_DEFAULT, true, expl));
then DAE.SLICE(DAE.RANGE(
DAE.T_ARRAY(DAE.T_INTEGER_DEFAULT, {DAE.DIM_INTEGER(inDim.integer)}, DAE.emptyTypeSource),
DAE.ICONST(1), NONE(), DAE.ICONST(inDim.integer)));

// Array with boolean dimension.
case DAE.DIM_BOOLEAN()
Expand Down

0 comments on commit f45a8b2

Please sign in to comment.