Skip to content

Commit

Permalink
- Fixed inlining of function pointers that do not return boxed data
Browse files Browse the repository at this point in the history
- Added expression simplification for "if cond then true else false => cond" and "if cond then false else true => not cond"
  - This found more simple equations in mosfiles-nosim/Model{1,2}.mos


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@7736 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Jan 21, 2011
1 parent 83125e9 commit 6cf97d7
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 36 deletions.
2 changes: 1 addition & 1 deletion Compiler/FrontEnd/DAE.mo
Expand Up @@ -958,7 +958,7 @@ uniontype ExpType "- Basic types
end ET_FUNCTION_REFERENCE_VAR;
record ET_FUNCTION_REFERENCE_FUNC "MetaModelica Function Reference that is a direct reference to a function"
Boolean builtin;
ExpType resType "type of the non-boxptr function";
Type functionType "type of the non-boxptr function";
end ET_FUNCTION_REFERENCE_FUNC;

record ET_METATYPE "MetaModelica boxed types (any)" end ET_METATYPE;
Expand Down
45 changes: 30 additions & 15 deletions Compiler/FrontEnd/ExpressionSimplify.mo
Expand Up @@ -287,26 +287,13 @@ algorithm
then
e;

// if condition is constant
case (DAE.IFEXP(expCond = e1,expThen = e2,expElse = e3))
equation
e1_1 = simplify1(e1);
true = Expression.isConst(e1_1);
b = Expression.getBoolConst(e1_1);
res = Util.if_(b,e2,e3);
res = simplify1(res);
then
res;

// if true and false branches are equal
case (DAE.IFEXP(expCond = e1,expThen = e2,expElse = e3))
equation
e1_1 = simplify1(e1);
e2_1 = simplify1(e2);
e3_1 = simplify1(e3);
remove_if = Expression.expEqual(e2_1, e3_1);
res = Util.if_(remove_if, e2_1, DAE.IFEXP(e1,e2_1,e3_1));
then
res;
then simplifyIfExp(e1_1,e2_1,e3_1);

// component references
case DAE.CREF(componentRef = c_1 as DAE.CREF_IDENT(idn,_,s),ty=t)
Expand All @@ -322,6 +309,34 @@ algorithm
end matchcontinue;
end simplify1;

protected function simplifyIfExp
"Handles simplification of if-expressions"
input DAE.Exp cond;
input DAE.Exp tb;
input DAE.Exp fb;
output DAE.Exp exp;
algorithm
exp := match (cond,tb,fb)
local
Boolean remove_if;
// Condition is constant
case (DAE.BCONST(true),tb,fb) then tb;
case (DAE.BCONST(false),tb,fb) then fb;
// The expression is the condition
case (exp,DAE.BCONST(true),DAE.BCONST(false)) then exp;
case (exp,DAE.BCONST(false),DAE.BCONST(true))
equation
exp = DAE.LUNARY(DAE.NOT(), exp);
then simplify1(exp);
// Are the branches equal?
case (cond,tb,fb)
equation
remove_if = Expression.expEqual(tb,fb);
exp = Util.if_(remove_if, tb, DAE.IFEXP(cond,tb,fb));
then exp;
end match;
end simplifyIfExp;

protected function simplifyMetaModelica "simplifies MetaModelica expressions"
input DAE.Exp exp;
output DAE.Exp outExp;
Expand Down
38 changes: 27 additions & 11 deletions Compiler/FrontEnd/Inline.mo
Expand Up @@ -45,6 +45,7 @@ encapsulated package Inline
public import Absyn;
public import BackendDAE;
public import DAE;
public import Error;
public import SCode;
public import Util;
public import Values;
Expand All @@ -58,8 +59,8 @@ protected import ComponentReference;
protected import Debug;
protected import DAEUtil;
protected import Expression;
protected import ExpressionDump;
protected import ExpressionSimplify;
protected import Types;

public function inlineCalls
"function: inlineCalls
Expand Down Expand Up @@ -1115,7 +1116,8 @@ algorithm
then body;
case(_,_)
equation
Debug.fprintln("failtrace","Inline.getFunctionBody failed");
Debug.fprintln("failtrace", "Inline.getFunctionBody failed");
// Error.addMessage(Error.INTERNAL_ERROR, {"Inline.getFunctionBody failed"});
then
fail();
end matchcontinue;
Expand Down Expand Up @@ -1181,14 +1183,14 @@ algorithm
then
((e,argmap));
/* TODO: Use the inlineType of the function reference! */
case((DAE.CALL(path,expLst,tuple_,false,DAE.ET_METATYPE(),inlineType),argmap))
case((DAE.CALL(path,expLst,tuple_,false,DAE.ET_METATYPE(),_),argmap))
equation
cref = ComponentReference.pathToCref(path);
(e as DAE.CREF(componentRef=cref,ty=ty)) = getExpFromArgMap(argmap,cref);
path = ComponentReference.crefToPath(cref);
expLst = Util.listMap(expLst,Expression.unboxExp);
b = Expression.isBuiltinFunctionReference(e);
ty2 = functionReferenceType(ty);
(ty2,inlineType) = functionReferenceType(ty);
e = DAE.CALL(path,expLst,tuple_,b,ty2,inlineType);
e = boxIfUnboxedFunRef(e,ty);
e = ExpressionSimplify.simplify(e);
Expand All @@ -1198,26 +1200,40 @@ algorithm
end replaceArgs;

protected function boxIfUnboxedFunRef
"Replacing a function pointer with a regular function means that you:
(1) Need to unbox all inputs
(2) Need to box the output if it was not done before
This function handles (2)
"
input DAE.Exp exp;
input DAE.ExpType ty;
output DAE.Exp outExp;
algorithm
outExp := match (exp,ty)
case (exp,DAE.ET_FUNCTION_REFERENCE_FUNC(resType=DAE.ET_METATYPE())) then exp;
case (exp,DAE.ET_FUNCTION_REFERENCE_FUNC(resType=DAE.ET_STRING())) then exp;
case (exp,DAE.ET_FUNCTION_REFERENCE_FUNC(resType=_))
then DAE.BOX(exp);
local
DAE.Type t;
case (exp,DAE.ET_FUNCTION_REFERENCE_FUNC(functionType=(DAE.T_FUNCTION(funcResultType=t),_)))
equation
exp = Util.if_(Types.isBoxedType(t), exp, DAE.BOX(exp));
then exp;
else exp;
end match;
end boxIfUnboxedFunRef;

protected function functionReferenceType
"Retrieves the ExpType that the call should have (this changes if the replacing
function does not return a boxed value).
We also return the inline type of the new call."
input DAE.ExpType ty1;
output DAE.ExpType ty2;
output DAE.InlineType inline;
algorithm
ty2 := match ty1
case DAE.ET_FUNCTION_REFERENCE_FUNC(resType=ty2) then ty2;
else ty1;
(ty2,inline) := match ty1
local
DAE.Type ty;
case DAE.ET_FUNCTION_REFERENCE_FUNC(functionType=(DAE.T_FUNCTION(functionAttributes=DAE.FUNCTION_ATTRIBUTES(inline=inline),funcResultType=ty),_))
then (Types.elabType(ty),inline);
else (ty1,DAE.NO_INLINE());
end match;
end functionReferenceType;

Expand Down
16 changes: 7 additions & 9 deletions Compiler/FrontEnd/Static.mo
Expand Up @@ -10138,15 +10138,14 @@ algorithm
SCode.Accessibility acc,acc_1;
SCode.Variability variability;
Option<Absyn.Path> optPath;
DAE.Type t,resTy;
DAE.Type t,origt;
DAE.TType tt;
DAE.Binding binding;
DAE.Exp exp,exp1,exp2,crefExp,expASUB;
list<Env.Frame> env;
Absyn.ComponentRef c;
Boolean impl;
Env.Cache cache;
Boolean doVect,isBuiltinFn;
Boolean impl,doVect,isBuiltinFn,isBuiltinFnOrInlineBuiltin;
DAE.ExpType et;
Absyn.InnerOuter io;
String s,scope;
Expand Down Expand Up @@ -10213,16 +10212,15 @@ algorithm
//true = RTOpts.debugFlag("fnptr") or RTOpts.acceptMetaModelicaGrammar();
path = Absyn.crefToPath(c);
(cache,{t}) = Lookup.lookupFunctionsInEnv(cache,env,path,info);
(isBuiltin,_,path) = isBuiltinFunc(path,t);
isBuiltinFn = not valueEq(DAE.FUNCTION_NOT_BUILTIN(),isBuiltin);
(isBuiltin,isBuiltinFn,path) = isBuiltinFunc(path,t);
isBuiltinFnOrInlineBuiltin = not valueEq(DAE.FUNCTION_NOT_BUILTIN(),isBuiltin);
(tt,optPath) = t;
t = (tt, Util.if_(isBuiltinFn, SOME(path), optPath)) "some builtin functions store NONE() there";
(DAE.T_FUNCTION(funcResultType=resTy),SOME(fpath)) = t;
et = Types.elabType(resTy);
origt = (tt, Util.if_(isBuiltinFn, SOME(path), optPath)) "some builtin functions store NONE() there";
(_,SOME(fpath)) = t;
t = Types.makeFunctionPolymorphicReference(t);
c = Absyn.pathToCref(fpath);
expCref = ComponentReference.toExpCref(c);
exp = Expression.makeCrefExp(expCref,DAE.ET_FUNCTION_REFERENCE_FUNC(isBuiltinFn,et));
exp = Expression.makeCrefExp(expCref,DAE.ET_FUNCTION_REFERENCE_FUNC(isBuiltinFnOrInlineBuiltin,origt));
// This is not done by lookup - only elabCall. So we should do it here.
(cache,Util.SUCCESS()) = instantiateDaeFunction(cache,env,path,isBuiltinFn,NONE(),true);
then
Expand Down

0 comments on commit 6cf97d7

Please sign in to comment.