Skip to content

Commit

Permalink
- Added support for list and listReverse reductions
Browse files Browse the repository at this point in the history
  - listReverse builds the result using cons
  - list builds the result using destructive cons-operations
  - Neither way uses listReverse or allocate more cons-cells than required


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@8135 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Mar 7, 2011
1 parent 4ef9549 commit 77ee5f8
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 9 deletions.
22 changes: 21 additions & 1 deletion Compiler/FrontEnd/ExpressionSimplify.mo
Expand Up @@ -309,6 +309,13 @@ algorithm
then
exp1;

case DAE.REDUCTION(path,e1,idn,e2)
equation
e1 = simplify1(e1);
e2 = simplify1(e2);
then
DAE.REDUCTION(path,e1,idn,e2);

// anything else
case e
then
Expand Down Expand Up @@ -357,7 +364,7 @@ algorithm
list<DAE.Exp> el;
Integer i;
Real r;
String s;
String s,idn;
case DAE.MATCHEXPRESSION(inputs={e}, localDecls={}, cases={
DAE.CASE(patterns={DAE.PAT_CONSTANT(exp=DAE.BCONST(b1))},localDecls={},body={},result=SOME(e1)),
DAE.CASE(patterns={DAE.PAT_CONSTANT(exp=DAE.BCONST(b2))},localDecls={},body={},result=SOME(e2))
Expand Down Expand Up @@ -418,6 +425,16 @@ algorithm
e1_1 = DAE.LIST(el);
then e1_1;

case DAE.CALL(path=path as Absyn.IDENT("listReverse"),expLst={DAE.REDUCTION(Absyn.IDENT("list"),e1,idn,e2)},ty=tp)
equation
e1 = DAE.REDUCTION(Absyn.IDENT("listReverse"),e1,idn,e2);
then simplify(e1);

case DAE.CALL(path=path as Absyn.IDENT("listReverse"),expLst={DAE.REDUCTION(Absyn.IDENT("listReverse"),e1,idn,e2)},ty=tp)
equation
e1 = DAE.REDUCTION(Absyn.IDENT("list"),e1,idn,e2);
then simplify(e1);

case DAE.CALL(path=path as Absyn.IDENT("listLength"),expLst={e1},ty=tp)
equation
DAE.LIST(el) = simplify(e1);
Expand Down Expand Up @@ -446,6 +463,9 @@ algorithm
DAE.BOX(e1_1) = simplify(e1);
then e1_1;

case DAE.UNBOX(exp=DAE.BOX(e1)) then e1;
case DAE.BOX(DAE.UNBOX(exp=e1)) then e1;

case DAE.IFEXP(e,DAE.BOX(e1),DAE.BOX(e2))
equation
e = simplify(DAE.IFEXP(e,e1,e2));
Expand Down
23 changes: 17 additions & 6 deletions Compiler/FrontEnd/Static.mo
Expand Up @@ -1049,15 +1049,16 @@ algorithm
// Expansion failed in previous case, generate reduction call.
case (cache,env,fn,exp,{(iter,SOME(iterexp))},impl,st,doVect,pre,info)
equation
(cache,iterexp_1,DAE.PROP((DAE.T_ARRAY(arrayType = iterty),_),iterconst),_)
(cache,iterexp_1,DAE.PROP(iterty,iterconst),_)
= elabExp(cache, env, iterexp, impl, st, doVect,pre,info);
iterty = Types.unliftArrayOrList(iterty);
env_1 = Env.openScope(env, false, SOME(Env.forIterScopeName),NONE());
env_1 = Env.extendFrameForIterator(env_1, iter, iterty, DAE.UNBOUND(),
SCode.CONST(), SOME(iterconst));
(cache,exp_1,DAE.PROP(expty, expconst),st) =
elabExp(cache, env_1, exp, impl, st, doVect,pre,info);
const = Types.constAnd(expconst, iterconst);
expty = reductionType(fn, expty, iterexp_1);
(exp_1,expty) = reductionType(fn, exp_1, expty, iterexp_1);
prop = DAE.PROP(expty, const);
fn_1 = Absyn.crefToPath(fn);
then
Expand All @@ -1072,14 +1073,24 @@ end elabCallReduction;

protected function reductionType
input Absyn.ComponentRef fn;
input DAE.Exp inExp;
input DAE.Type inType;
input DAE.Exp inRangeExp;
output DAE.Exp outExp;
output DAE.Type outType;
algorithm
outType := match(fn, inType, inRangeExp)
case (Absyn.CREF_IDENT(name = "array"), _, _)
then Types.liftArray(inType, DAE.DIM_EXP(inRangeExp));
else then inType;
(outExp,outType) := match(fn, inExp, inType, inRangeExp)
case (Absyn.CREF_IDENT(name = "array"), _, _, _)
then (inExp, Types.liftArray(inType, DAE.DIM_EXP(inRangeExp)));
case (Absyn.CREF_IDENT(name = "list"), inExp, _, _)
equation
(inExp,inType) = Types.matchType(inExp, inType, DAE.T_BOXED_DEFAULT, true);
then (inExp,(DAE.T_LIST(inType), NONE()));
case (Absyn.CREF_IDENT(name = "listReverse"), inExp, _, _)
equation
(inExp,inType) = Types.matchType(inExp, inType, DAE.T_BOXED_DEFAULT, true);
then (inExp,(DAE.T_LIST(inType), NONE()));
else (inExp,inType);
end match;
end reductionType;

Expand Down
12 changes: 12 additions & 0 deletions Compiler/FrontEnd/Types.mo
Expand Up @@ -2028,6 +2028,18 @@ algorithm
end match;
end unliftArray;

public function unliftArrayOrList
input Type inType;
output Type outType;
algorithm
outType := match (inType)
local
Type ty;
case ((DAE.T_LIST(ty),_)) then ty;
else unliftArray(inType);
end match;
end unliftArrayOrList;

protected function typeArraydim "function: typeArraydim

If type is an array, return it array dimension
Expand Down
50 changes: 48 additions & 2 deletions Compiler/susan_codegen/SimCode/SimCodeC.tpl
Expand Up @@ -4329,7 +4329,7 @@ template algStmtForGeneric_impl(Exp exp, Ident iterator, String type,
<<
<%preExp%>
{
<%type%> <%iterName%>;
<%type%> <%iterName%>;
for(<%tvar%> = 1; <%tvar%> <= size_of_dimension_<%arrayType%>(<%evar%>, 1); ++<%tvar%>) {
<%if not acceptMetaModelicaGrammar() then '<%stateVar%> = get_memory_state();'%>
Expand Down Expand Up @@ -5674,6 +5674,51 @@ template daeExpReduction(Exp exp, Context context, Text &preExp /*BUFP*/,
"Generates code for a reduction expression."
::=
match exp
case REDUCTION(path = IDENT(name = name as "listReverse"), range = range)
case REDUCTION(path = IDENT(name = name as "list"), range = range) then
let &tmpVarDecls = buffer ""
let &tmpExpPre = buffer ""
let &bodyExpPre = buffer ""
let acc = tempDecl("modelica_metatype", &tmpVarDecls)
let resHead = tempDecl("modelica_metatype", &varDecls)
let resTail = match name case "list" then tempDecl("modelica_metatype*", &tmpVarDecls)
let lstExp = daeExp(range, context, &tmpExpPre, &tmpVarDecls)
let bodyExp = daeExp(expr, context, &bodyExpPre, &tmpVarDecls)
let iteratorName = contextIteratorName(ident, context)
let &preExp += <<
{ /* "<%name%>" reduction */
<%tmpVarDecls%>
modelica_metatype <%iteratorName%>;
<%tmpExpPre%>
<%acc%> = <%lstExp%>;
<% match name
case "list" then
<<
<%resHead%> = 0;
<%resTail%> = &<%resHead%>;
>>
case "listReverse" then
'<%resHead%> = mmc_mk_nil();'
%>
while (!listEmpty(<%acc%>)) {
<%iteratorName%> = MMC_CAR(<%acc%>);
<%bodyExpPre%>
<% match name
case "list" then // Let's save some bytes from being garbage by using runtime trickery. We get a little bit of overhead from filling the CDR with 0 and patching it as we go, but lower memory overhead should make up for it.
<<
*<%resTail%> = mmc_mk_cons(<%bodyExp%>,0);
<%resTail%> = &MMC_CDR(*<%resTail%>);
>>
case "listReverse" then // This is too easy; the damn list is already in the correct order
'<%resHead%> = mmc_mk_cons(<%bodyExp%>,<%resHead%>);'
%>
<%acc%> = MMC_CDR(<%acc%>);
}
<% match name case "list" then '*<%resTail%> = mmc_mk_nil();' %>
}<%\n%>
>>
resHead
// Array reductions
case REDUCTION(path = IDENT(name = op)) then
let identType = expTypeFromExpModelica(expr)
let accFun = daeExpReductionFnName(op, identType)
Expand All @@ -5692,7 +5737,7 @@ case REDUCTION(path = IDENT(name = op)) then
let &preExp +=
<<
<%res%> = <%startValue%>;
<%daeExpReductionLoop(exp, body, context, &varDecls)%>
<%daeExpReductionLoop(exp, body, context, &varDecls)%><%\n%>
>>
res
end daeExpReduction;
Expand Down Expand Up @@ -6067,6 +6112,7 @@ case VARIABLE(__) then 'modelica_metatype'
case FUNCTION_PTR(__) then 'modelica_fnptr'
end varTypeBoxed;
template expTypeRW(DAE.ExpType type)
"Helper to writeOutVarRecordMembers."
::=
Expand Down

0 comments on commit 77ee5f8

Please sign in to comment.