Skip to content

Commit

Permalink
- Added annotation __OpenModelica_Impure. Using it prevents constant …
Browse files Browse the repository at this point in the history
…evaluation of a function call.

  - DAE.T_FUNCTION now has FunctionAttributes instead of InlineType (which is now stored together with the other function attributes)


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@7382 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Dec 13, 2010
1 parent 9e1b0ab commit 2ac5b9e
Show file tree
Hide file tree
Showing 8 changed files with 443 additions and 531 deletions.
6 changes: 3 additions & 3 deletions Compiler/BackEnd/PartFn.mo
Expand Up @@ -1192,14 +1192,14 @@ algorithm
list<DAE.FuncArg> args,args_1,args_2,new_args;
DAE.Type retType;
Option<Absyn.Path> po;
DAE.InlineType isInline;
case((DAE.T_FUNCTION(args,retType,isInline),po),vars)
DAE.FunctionAttributes functionAttributes;
case((DAE.T_FUNCTION(args,retType,functionAttributes),po),vars)
equation
new_args = Types.makeFargsList(vars);
args_1 = Util.listSelect(args,isNotFunctionType);
args_2 = listAppend(args_1,new_args);
then
((DAE.T_FUNCTION(args_2,retType,isInline),po));
((DAE.T_FUNCTION(args_2,retType,functionAttributes),po));
case(_,_)
equation
Debug.fprintln("failtrace","- PartFn.buildNewFunctionType failed");
Expand Down
772 changes: 314 additions & 458 deletions Compiler/FrontEnd/Builtin.mo

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion Compiler/FrontEnd/DAE.mo
Expand Up @@ -734,7 +734,7 @@ public uniontype TType "-TType contains the actual type"
record T_FUNCTION
list<FuncArg> funcArg "funcArg" ;
Type funcResultType "funcResultType ; Only single-result" ;
InlineType inline;
FunctionAttributes functionAttributes;
end T_FUNCTION;

record T_TUPLE
Expand All @@ -755,6 +755,17 @@ public uniontype TType "-TType contains the actual type"

end TType;

public constant FunctionAttributes FUNCTION_ATTRIBUTES_DEFAULT = FUNCTION_ATTRIBUTES(NO_INLINE(),true);
public constant FunctionAttributes FUNCTION_ATTRIBUTES_IMPURE = FUNCTION_ATTRIBUTES(NO_INLINE(),false);

public
uniontype FunctionAttributes
record FUNCTION_ATTRIBUTES
InlineType inline;
Boolean isPure;
end FUNCTION_ATTRIBUTES;
end FunctionAttributes;

public
uniontype Dimension
record DIM_INTEGER "Dimension given by an integer."
Expand Down
80 changes: 51 additions & 29 deletions Compiler/FrontEnd/DAEUtil.mo
Expand Up @@ -2768,7 +2768,7 @@ algorithm
case (DAE.DAE(((DAE.VAR(componentRef = cr,kind=DAE.PARAM(),binding=SOME(e),absynCommentOption=SOME(comment)))):: rest),pv,ht)
equation
SCode.COMMENT(annotation_=SOME(anno)) = comment;
true = hasevaluateAnnotation({anno});
true = hasBooleanNamedAnnotation1({anno},"Evaluate");
e1 = evaluateParameter(e,pv);
ht1 = BaseHashTable.add((cr,e1),ht);
(ht2,_) = evaluateAnnotation1(DAE.DAE(rest),pv,ht1);
Expand All @@ -2777,7 +2777,7 @@ algorithm
case (DAE.DAE(((DAE.VAR(componentRef = cr,kind=DAE.PARAM(),binding=SOME(e),absynCommentOption=SOME(comment)))):: rest),pv,ht)
equation
SCode.CLASS_COMMENT(annotations=annos) = comment;
true = hasevaluateAnnotation(annos);
true = hasBooleanNamedAnnotation1(annos,"Evaluate");
e1 = evaluateParameter(e,pv);
ht1 = BaseHashTable.add((cr,e1),ht);
(ht2,_) = evaluateAnnotation1(DAE.DAE(rest),pv,ht1);
Expand Down Expand Up @@ -2820,74 +2820,96 @@ algorithm
end matchcontinue;
end evaluateParameter;

protected function hasevaluateAnnotation
"function: hasevaluateAnnotation
check if the Evaluate annotation is present in comment"
public function hasBooleanNamedAnnotation
input SCode.Class inClass;
input String namedAnnotation;
output Boolean hasAnn;
algorithm
hasAnn := matchcontinue(inClass,namedAnnotation)
local
list<SCode.Annotation> anns;

case(SCode.CLASS(classDef = SCode.PARTS(annotationLst = anns)),namedAnnotation)
then hasBooleanNamedAnnotation1(anns,namedAnnotation);

case(SCode.CLASS(classDef = SCode.CLASS_EXTENDS(annotationLst = anns)),namedAnnotation)
then hasBooleanNamedAnnotation1(anns,namedAnnotation);
else false;
end matchcontinue;
end hasBooleanNamedAnnotation;

protected function hasBooleanNamedAnnotation1
"check if the named annotation is present"
input list<SCode.Annotation> inAnnos;
input String annotationName;
output Boolean outB;
algorithm
outB := matchcontinue (inAnnos)
outB := matchcontinue (inAnnos,annotationName)
local
Boolean b;
list<SCode.Annotation> rest;
SCode.Mod mod;
case (SCode.ANNOTATION(modification = mod) :: rest)
case (SCode.ANNOTATION(modification = mod) :: rest,annotationName)
equation
true = hasevaluateAnnotation2(mod);
true = hasBooleanNamedAnnotation2(mod,annotationName);
then
true;
case (SCode.ANNOTATION(modification = mod) :: rest)
case (SCode.ANNOTATION(modification = mod) :: rest,annotationName)
equation
false = hasevaluateAnnotation2(mod);
b = hasevaluateAnnotation(rest);
false = hasBooleanNamedAnnotation2(mod,annotationName);
b = hasBooleanNamedAnnotation1(rest,annotationName);
then
b;
end matchcontinue;
end hasevaluateAnnotation;
end hasBooleanNamedAnnotation1;

protected function hasevaluateAnnotation2
"function: hasevaluateAnnotation2
check if the Evaluate annotation is present in comment"
protected function hasBooleanNamedAnnotation2
"check if the named annotation is present"
input SCode.Mod inMod;
input String annotationName;
output Boolean outB;
algorithm
(outB) := matchcontinue (inMod)
(outB) := matchcontinue (inMod,annotationName)
local
Boolean b;
list<SCode.SubMod> subModLst;
case (SCode.MOD(subModLst=subModLst))
case (SCode.MOD(subModLst=subModLst),annotationName)
equation
b = hasevaluateAnnotation3(subModLst);
b = hasBooleanNamedAnnotation3(subModLst,annotationName);
then
b;
end matchcontinue;
end hasevaluateAnnotation2;
end hasBooleanNamedAnnotation2;

protected function hasevaluateAnnotation3
"function: hasevaluateAnnotation3
check if the Evaluate annotation is present in comment"
protected function hasBooleanNamedAnnotation3
"check if the named annotation is present in comment"
input list<SCode.SubMod> inSubModes;
input String namedAnnotation;
output Boolean outB;
algorithm
(outB) := matchcontinue (inSubModes)
(outB) := matchcontinue (inSubModes,namedAnnotation)
local
Boolean b;
list<SCode.SubMod> rest;
SCode.SubMod submod;
SCode.Mod mod;
case (SCode.NAMEMOD(ident = "Evaluate",A=SCode.MOD(absynExpOption=SOME((Absyn.BOOL(value=true),_)))) :: rest) then true;
case (SCode.IDXMOD(an=mod) :: rest)
String id;
case (SCode.NAMEMOD(ident = id,A=SCode.MOD(absynExpOption=SOME((Absyn.BOOL(value=true),_)))) :: rest,namedAnnotation)
equation
true = id ==& namedAnnotation;
then true;
case (SCode.IDXMOD(an=mod) :: rest,namedAnnotation)
equation
true = hasevaluateAnnotation2(mod);
true = hasBooleanNamedAnnotation2(mod,namedAnnotation);
then
true;
case (submod :: rest)
case (submod :: rest,namedAnnotation)
equation
b = hasevaluateAnnotation3(rest);
b = hasBooleanNamedAnnotation3(rest,namedAnnotation);
then
b;
end matchcontinue;
end hasevaluateAnnotation3;
end hasBooleanNamedAnnotation3;

protected function selectBranches
"@author: adrpo
Expand Down
31 changes: 26 additions & 5 deletions Compiler/FrontEnd/Inst.mo
Expand Up @@ -10747,7 +10747,7 @@ algorithm
Env.Cache cache;
InstanceHierarchy ih;
Boolean partialPrefix;
DAE.InlineType isInline;
DAE.FunctionAttributes functionAttributes;
DAE.ElementSource source "the origin of the element";
DAE.FunctionTree funcs;
DAE.DAElist dae,dae2;
Expand All @@ -10761,12 +10761,12 @@ algorithm
case (cache,env,ih,overloadname,(fn :: fns))
equation
(cache,(c as SCode.CLASS(name=id,partialPrefix=partialPrefix,encapsulatedPrefix=encflag,restriction=SCode.R_FUNCTION(),info=info)),cenv) = Lookup.lookupClass(cache, env, fn, true);
(cache,_,ih,_,DAE.DAE(daeElts),_,(DAE.T_FUNCTION(args,tp,isInline),_),st,_,_) =
(cache,_,ih,_,DAE.DAE(daeElts),_,(DAE.T_FUNCTION(args,tp,functionAttributes),_),st,_,_) =
instClass(cache,cenv,ih,UnitAbsynBuilder.emptyInstStore(),
DAE.NOMOD(), Prefix.NOPRE(), Connect.emptySet, c, {}, true, INNER_CALL(), ConnectionGraph.EMPTY);
(cache,fpath) = makeFullyQualified(cache,env, Absyn.IDENT(overloadname));
(cache,ovlfpath) = makeFullyQualified(cache,cenv, Absyn.IDENT(id));
ty = (DAE.T_FUNCTION(args,tp,isInline),SOME(ovlfpath));
ty = (DAE.T_FUNCTION(args,tp,functionAttributes),SOME(ovlfpath));
env_1 = Env.extendFrameT(env, overloadname, ty);
(cache,env_2,ih,resfns) = instOverloadedFunctions(cache,env_1,ih, overloadname, fns);
// TODO: Fix inline here
Expand Down Expand Up @@ -11759,7 +11759,7 @@ algorithm
/* Insert function type construction here after checking input/output arguments? see Types.mo T_FUNCTION */
case (p,(st as ClassInf.FUNCTION(path = _)),vl,_,_,cl)
equation
functype = Types.makeFunctionType(p, vl, isInlineFunc2(cl));
functype = Types.makeFunctionType(p, vl, getFunctionAttributes(cl));
then
functype;
case (_, ClassInf.ENUMERATION(path = p), _, SOME(enumtype), _, _)
Expand Down Expand Up @@ -11874,7 +11874,7 @@ algorithm
/* Insert function type construction here after checking input/output arguments? see Types.mo T_FUNCTION */
case (p,(st as ClassInf.FUNCTION(path = _)),vl,_,cl)
equation
functype = Types.makeFunctionType(p, vl, isInlineFunc2(cl));
functype = Types.makeFunctionType(p, vl, getFunctionAttributes(cl));
then
functype;
case (p, ClassInf.ENUMERATION(path = _), _, SOME(enumtype), _)
Expand Down Expand Up @@ -15212,4 +15212,25 @@ algorithm
end matchcontinue;
end checkSelfReference;

protected function getFunctionAttributes
"Looks at the annotations of an SCode.Class to create the function attributes,
i.e. Inline and Purity"
input SCode.Class cl;
output DAE.FunctionAttributes attr;
algorithm
attr := matchcontinue (cl)
local
SCode.Restriction restriction;
Boolean isExt,purity;
DAE.InlineType inline;
case (SCode.CLASS(restriction=restriction))
equation
inline = isInlineFunc2(cl);
isExt = false; // TODO: We need to check for "builtin" annotation... SCode.restrictionEqual(restriction,SCode.R_EXT_FUNCTION());
purity = not (isExt or DAEUtil.hasBooleanNamedAnnotation(cl,"__OpenModelica_Impure"));
//print("getFunctionAttributes: " +& boolString(purity) +& boolString(isExt) +& boolString(DAEUtil.hasBooleanNamedAnnotation(cl,"__OpenModelica_Impure")) +& "\n");
then DAE.FUNCTION_ATTRIBUTES(inline,purity);
end matchcontinue;
end getFunctionAttributes;

end Inst;
8 changes: 4 additions & 4 deletions Compiler/FrontEnd/Lookup.mo
Expand Up @@ -123,14 +123,14 @@ algorithm
// Special handling for Connections.isRoot
case (cache,env,Absyn.QUALIFIED("Connections", Absyn.IDENT("isRoot")),msg)
equation
t = (DAE.T_FUNCTION({("x", (DAE.T_ANYTYPE(NONE()),NONE()))}, DAE.T_BOOL_DEFAULT, DAE.NO_INLINE()),NONE());
t = (DAE.T_FUNCTION({("x", (DAE.T_ANYTYPE(NONE()),NONE()))}, DAE.T_BOOL_DEFAULT, DAE.FUNCTION_ATTRIBUTES_DEFAULT),NONE());
then
(cache, t, env);

// Special handling for MultiBody 3.x rooted() operator
case (cache,env,Absyn.IDENT("rooted"),msg)
equation
t = (DAE.T_FUNCTION({("x", (DAE.T_ANYTYPE(NONE()),NONE()))}, DAE.T_BOOL_DEFAULT, DAE.NO_INLINE()),NONE());
t = (DAE.T_FUNCTION({("x", (DAE.T_ANYTYPE(NONE()),NONE()))}, DAE.T_BOOL_DEFAULT, DAE.FUNCTION_ATTRIBUTES_DEFAULT),NONE());
then
(cache, t, env);

Expand Down Expand Up @@ -1654,9 +1654,9 @@ algorithm
/* function_name cardinality */
case (env,"cardinality")
then {(DAE.T_FUNCTION({("x",(DAE.T_COMPLEX(ClassInf.CONNECTOR(Absyn.IDENT("$$"),false),{},NONE(),NONE()),NONE()))},
DAE.T_INTEGER_DEFAULT,DAE.NO_INLINE()),NONE()),
DAE.T_INTEGER_DEFAULT,DAE.FUNCTION_ATTRIBUTES_DEFAULT),NONE()),
(DAE.T_FUNCTION({("x",(DAE.T_COMPLEX(ClassInf.CONNECTOR(Absyn.IDENT("$$"),true),{},NONE(),NONE()),NONE()))},
DAE.T_INTEGER_DEFAULT,DAE.NO_INLINE()),NONE())};
DAE.T_INTEGER_DEFAULT,DAE.FUNCTION_ATTRIBUTES_DEFAULT),NONE())};

end matchcontinue;
end createGenericBuiltinFunctions;
Expand Down
25 changes: 13 additions & 12 deletions Compiler/FrontEnd/Static.mo
Expand Up @@ -1948,12 +1948,12 @@ algorithm
DAE.Type resType,tty,tty_1;
list<DAE.FuncArg> args,args_1;
Option<Absyn.Path> po;
DAE.InlineType isInline;
case(slots,(DAE.T_FUNCTION(args,resType,isInline),po))
DAE.FunctionAttributes functionAttributes;
case(slots,(DAE.T_FUNCTION(args,resType,functionAttributes),po))
equation
args = stripExtraArgsFromType2(slots,args);
then
((DAE.T_FUNCTION(args,resType,isInline),po));
((DAE.T_FUNCTION(args,resType,functionAttributes),po));
case(_,_)
equation
Debug.fprintln("failtrace","- Static.stripExtraArgsFromType failed");
Expand Down Expand Up @@ -8603,7 +8603,7 @@ algorithm
Absyn.Path fn,fn_1,fqPath,utPath,fnPrefix,componentType,correctFunctionPath,functionClassPath,fpath;
list<Absyn.Exp> args,t4;
list<Absyn.NamedArg> nargs, translatedNArgs;
Boolean impl,tuple_,builtin;
Boolean impl,tuple_,builtin,isPure;
DAE.InlineType inline;
Option<Interactive.InteractiveSymbolTable> st;
list<DAE.Type> typelist,ktypelist,tys,ltypes;
Expand Down Expand Up @@ -8713,7 +8713,7 @@ algorithm
/* Record constructors, user defined or implicit */ // try the hard stuff first
case (cache,env,fn,args,nargs,impl,stopElab,st,pre,info)
equation
(cache,(t as (DAE.T_FUNCTION(fargs,(outtype as (DAE.T_COMPLEX(complexClassType as ClassInf.RECORD(path=_),_,_,_),_)),DAE.NO_INLINE()),_)),_)
(cache,(t as (DAE.T_FUNCTION(fargs,(outtype as (DAE.T_COMPLEX(complexClassType as ClassInf.RECORD(path=_),_,_,_),_)),_),_)),_)
= Lookup.lookupType(cache,env, fn, NONE());
// print(" inst record: " +& name +& " \n");
(_,recordCl,recordEnv) = Lookup.lookupClass(cache,env,fn, false);
Expand Down Expand Up @@ -8791,14 +8791,14 @@ algorithm
in the function type of the user function and check both the
function name and the function\'s type." ;
Util.setStatefulBoolean(stopElab,true);
(cache,args_1,constlist,restype,functype as (DAE.T_FUNCTION(inline = inline),_),vect_dims,slots) =
(cache,args_1,constlist,restype,functype as (DAE.T_FUNCTION(functionAttributes = DAE.FUNCTION_ATTRIBUTES(isPure = isPure, inline = inline)),_),vect_dims,slots) =
elabTypes(cache, env, args, nargs, typelist, true/* Check types*/, impl,pre,info)
"The constness of a function depends on the inputs. If all inputs are constant the call itself is constant." ;
fn_1 = deoverloadFuncname(fn, functype);
tuple_ = isTuple(restype);
(cache,builtin,fn_1) = isBuiltinFunc(cache,fn_1);
const = Util.listFold(constlist, Types.constAnd, DAE.C_CONST());
const = Util.if_(RTOpts.debugFlag("rml"), DAE.C_VAR(), const) "in RML no function needs to be ceval'ed; this speeds up compilation significantly when bootstrapping";
const = Util.if_(RTOpts.debugFlag("rml") or (not isPure), DAE.C_VAR(), const) "in RML no function needs to be ceval'ed; this speeds up compilation significantly when bootstrapping";
(cache,const) = determineConstSpecialFunc(cache,env,const,fn);
tyconst = elabConsts(restype, const);
prop = getProperties(restype, tyconst);
Expand Down Expand Up @@ -9549,16 +9549,17 @@ algorithm
Option<Absyn.Path> p;
DAE.DAElist dae;
Prefix.Prefix pre;
DAE.FunctionAttributes functionAttributes;

// We found a match.
case (cache,env,args,nargs,((t as (DAE.T_FUNCTION(funcArg = params,funcResultType = restype, inline = isInline),p)) :: trest),checkTypes,impl,pre,info)
case (cache,env,args,nargs,((t as (DAE.T_FUNCTION(funcArg = params,funcResultType = restype, functionAttributes = functionAttributes),p)) :: trest),checkTypes,impl,pre,info)
equation
slots = makeEmptySlots(params);
(cache,args_1,newslots,clist,polymorphicBindings) = elabInputArgs(cache, env, args, nargs, slots, checkTypes, impl, {},pre,info);
dims = slotsVectorizable(newslots);
polymorphicBindings = Types.solvePolymorphicBindings(polymorphicBindings,info,p);
restype = Types.fixPolymorphicRestype(restype, polymorphicBindings, info);
t = (DAE.T_FUNCTION(params,restype,isInline),p);
t = (DAE.T_FUNCTION(params,restype,functionAttributes),p);
t = createActualFunctype(t,newslots,checkTypes) "only created when not checking types for error msg";
then
(cache,args_1,clist,restype,t,dims,newslots);
Expand Down Expand Up @@ -9591,12 +9592,12 @@ algorithm
local
Option<Absyn.Path> optPath;
list<DAE.FuncArg> slotParams,params; DAE.Type restype;
DAE.InlineType isInline;
DAE.FunctionAttributes functionAttributes;
case(tp,_,true) then tp;
/* When not checking types, create function type by looking at the filled slots */
case(tp as (DAE.T_FUNCTION(funcArg = params,funcResultType = restype,inline = isInline),optPath),slots,false) equation
case(tp as (DAE.T_FUNCTION(params,restype,functionAttributes),optPath),slots,false) equation
slotParams = funcargLstFromSlots(slots);
then ((DAE.T_FUNCTION(slotParams,restype,isInline),optPath));
then ((DAE.T_FUNCTION(slotParams,restype,functionAttributes),optPath));
end matchcontinue;
end createActualFunctype;

Expand Down

0 comments on commit 2ac5b9e

Please sign in to comment.