Skip to content

Commit

Permalink
- Known external "C" calls are now treated as external "builtin"
Browse files Browse the repository at this point in the history
  - That is, Modelica.Math.sin becomes a call to sin because it is calling the same C function we know that the builtin function is calling
  - This finds more functions than just Modelica.Math.sin (some of the testcases mapped their own external "C" function to C)
  - We should also be able to change Derive.mo to do pattern-matching against "sin" now, instead of calling Builtin.isSin


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@7722 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Jan 19, 2011
1 parent 70f444b commit a6fc8da
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 43 deletions.
7 changes: 7 additions & 0 deletions Compiler/FrontEnd/Absyn.mo
Expand Up @@ -4993,4 +4993,11 @@ algorithm
e := CONS(e1,e2);
end makeCons;

public function crefIdent
input ComponentRef cr;
output String str;
algorithm
CREF_IDENT(str,{}) := cr;
end crefIdent;

end Absyn;
3 changes: 2 additions & 1 deletion Compiler/FrontEnd/DAE.mo
Expand Up @@ -749,7 +749,7 @@ public uniontype TType "-TType contains the actual type"

end TType;

public constant FunctionAttributes FUNCTION_ATTRIBUTES_BUILTIN = FUNCTION_ATTRIBUTES(NO_INLINE(),true,FUNCTION_BUILTIN());
public constant FunctionAttributes FUNCTION_ATTRIBUTES_BUILTIN = FUNCTION_ATTRIBUTES(NO_INLINE(),true,FUNCTION_BUILTIN(NONE()));
public constant FunctionAttributes FUNCTION_ATTRIBUTES_DEFAULT = FUNCTION_ATTRIBUTES(NO_INLINE(),true,FUNCTION_NOT_BUILTIN());
public constant FunctionAttributes FUNCTION_ATTRIBUTES_IMPURE = FUNCTION_ATTRIBUTES(NO_INLINE(),false,FUNCTION_NOT_BUILTIN());

Expand All @@ -767,6 +767,7 @@ uniontype FunctionBuiltin
record FUNCTION_NOT_BUILTIN "Function is not builtin"
end FUNCTION_NOT_BUILTIN;
record FUNCTION_BUILTIN "Function is builtin"
Option<String> name;
end FUNCTION_BUILTIN;
record FUNCTION_BUILTIN_PTR "The function has a body, but its function pointer is builtin. This means inline code+optimized pointer if need be."
end FUNCTION_BUILTIN_PTR;
Expand Down
29 changes: 22 additions & 7 deletions Compiler/FrontEnd/Inst.mo
Expand Up @@ -11499,7 +11499,7 @@ algorithm
end matchcontinue;
end daeDeclare4;

public function mktype
protected function mktype
"function: mktype
From a class typename, its inference state, and a list of subcomponents,
this function returns DAE.Type. If the class inference state
Expand Down Expand Up @@ -11527,6 +11527,7 @@ algorithm
DAE.Type resType;
ClassInf.State classState;
DAE.EqualityConstraint equalityConstraint;
DAE.FunctionAttributes funcattr;
case (p,ClassInf.TYPE_INTEGER(path = _),v,_,_,_)
equation
somep = getOptPath(p);
Expand Down Expand Up @@ -11555,7 +11556,8 @@ 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, getFunctionAttributes(cl));
funcattr = getFunctionAttributes(cl,vl);
functype = Types.makeFunctionType(p, vl, funcattr);
then
functype;
case (_, ClassInf.ENUMERATION(path = p), _, SOME(enumtype), _, _)
Expand Down Expand Up @@ -11634,6 +11636,7 @@ algorithm
Option<Absyn.Path> somep;
SCode.Class cl;
Option<tuple<DAE.TType, Option<Absyn.Path>>> bc;
DAE.FunctionAttributes funcattr;
case (p,ci,vs,SOME(tp),_)
equation
true = Types.isArray(tp);
Expand Down Expand Up @@ -11669,7 +11672,8 @@ 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, getFunctionAttributes(cl));
funcattr = getFunctionAttributes(cl,vl);
functype = Types.makeFunctionType(p, vl, funcattr);
then
functype;
case (p, ClassInf.ENUMERATION(path = _), _, SOME(enumtype), _)
Expand Down Expand Up @@ -14555,21 +14559,32 @@ 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;
input list<DAE.Var> vl;
output DAE.FunctionAttributes attr;
algorithm
attr := match (cl)
attr := matchcontinue (cl,vl)
local
SCode.Restriction restriction;
Boolean purity;
DAE.FunctionBuiltin isBuiltin;
DAE.InlineType inline;
case (SCode.CLASS(restriction=restriction))
String name;
list<DAE.Var> inVars,outVars;
case (SCode.CLASS(restriction=SCode.R_EXT_FUNCTION()),vl)
equation
inVars = Util.listFilter(vl,Types.isInputVar);
outVars = Util.listFilter(vl,Types.isOutputVar);
name = SCode.isBuiltinFunction(cl,Util.listMap(inVars,Types.varName),Util.listMap(outVars,Types.varName));
inline = isInlineFunc2(cl);
purity = not DAEUtil.hasBooleanNamedAnnotation(cl,"__OpenModelica_Impure");
then (DAE.FUNCTION_ATTRIBUTES(inline,purity,DAE.FUNCTION_BUILTIN(SOME(name))));
case (SCode.CLASS(restriction=restriction),_)
equation
inline = isInlineFunc2(cl);
isBuiltin = Util.if_(SCode.isBuiltinFunction(cl), DAE.FUNCTION_BUILTIN(), Util.if_(DAEUtil.hasBooleanNamedAnnotation(cl,"__OpenModelica_BuiltinPtr"), DAE.FUNCTION_BUILTIN_PTR(), DAE.FUNCTION_NOT_BUILTIN()));
isBuiltin = Util.if_(DAEUtil.hasBooleanNamedAnnotation(cl,"__OpenModelica_BuiltinPtr"), DAE.FUNCTION_BUILTIN_PTR(), DAE.FUNCTION_NOT_BUILTIN());
purity = not DAEUtil.hasBooleanNamedAnnotation(cl,"__OpenModelica_Impure");
then DAE.FUNCTION_ATTRIBUTES(inline,purity,isBuiltin);
end match;
end matchcontinue;
end getFunctionAttributes;

protected function checkFunctionElement
Expand Down
33 changes: 29 additions & 4 deletions Compiler/FrontEnd/SCode.mo
Expand Up @@ -3507,13 +3507,38 @@ algorithm
CLASSDEF(classDef=cl) := el;
end getElementClass;

protected constant list<String> knownExternalCFunctions = {"acos"};

public function isBuiltinFunction
input Class cl;
output Boolean b;
input list<String> inVars;
input list<String> outVars;
output String name;
algorithm
b := match cl
case CLASS(restriction=R_EXT_FUNCTION(),classDef=PARTS(externalDecl=SOME(Absyn.EXTERNALDECL(lang=SOME("builtin"))))) then true;
else false;
name := match (cl,inVars,outVars)
local
Absyn.Info info;
String inc,outVar1,outVar2,name1,name2;
list<String> argsStr;
list<Absyn.Exp> args;
case (CLASS(name=name,restriction=R_EXT_FUNCTION(),classDef=PARTS(externalDecl=SOME(Absyn.EXTERNALDECL(funcName=NONE(),lang=SOME("builtin"))))),_,_)
then name;
case (CLASS(restriction=R_EXT_FUNCTION(),classDef=PARTS(externalDecl=SOME(Absyn.EXTERNALDECL(funcName=SOME(name),lang=SOME("builtin"))))),_,_)
then name;
case (CLASS(restriction=R_EXT_FUNCTION(),
classDef=PARTS(externalDecl=SOME(Absyn.EXTERNALDECL(funcName=SOME(name),lang=SOME("C"),output_=SOME(Absyn.CREF_IDENT(outVar2,{})),args=args)))),inVars,{outVar1})
equation
true = listMember(name,{"sin","cos","tan","asin","acos","atan","atan2","sinh","cosh","tanh","exp","log","log10","sqrt"});
true = outVar2 ==& outVar1;
argsStr = Util.listMapMap(args, Absyn.expCref, Absyn.crefIdent);
equality(argsStr = inVars);
then name;
case (CLASS(name=name,
restriction=R_EXT_FUNCTION(),
classDef=PARTS(externalDecl=SOME(Absyn.EXTERNALDECL(funcName=NONE(),lang=SOME("C"))))),_,_)
equation
true = listMember(name,{"sin","cos","tan","asin","acos","atan","atan","sinh","cosh","tanh","exp","log","log10","sqrt"});
then name;
end match;
end isBuiltinFunction;

Expand Down
45 changes: 24 additions & 21 deletions Compiler/FrontEnd/Static.mo
Expand Up @@ -6296,44 +6296,49 @@ protected function isBuiltinFunc "function: isBuiltinFunc
input Absyn.Path inPath "the path of the found function";
input DAE.Type ty;
output DAE.FunctionBuiltin isBuiltin;
output Boolean b;
output Absyn.Path outPath "make the path non-FQ";
algorithm
(isBuiltin,outPath) := matchcontinue (inPath,ty)
(isBuiltin,b,outPath) := matchcontinue (inPath,ty)
local
Ident id;
Absyn.Path path;
Env.Cache cache;
case (path,(DAE.T_FUNCTION(functionAttributes=DAE.FUNCTION_ATTRIBUTES(isBuiltin=isBuiltin)),_))
case (path,(DAE.T_FUNCTION(functionAttributes=DAE.FUNCTION_ATTRIBUTES(isBuiltin=isBuiltin as DAE.FUNCTION_BUILTIN(_))),_))
equation
path = Absyn.makeNotFullyQualified(path);
then (isBuiltin,true,path);
case (path,(DAE.T_FUNCTION(functionAttributes=DAE.FUNCTION_ATTRIBUTES(isBuiltin=isBuiltin as DAE.FUNCTION_BUILTIN_PTR())),_))
equation
false = valueEq(isBuiltin,DAE.FUNCTION_NOT_BUILTIN());
path = Absyn.makeNotFullyQualified(path);
then (isBuiltin,path);
then (isBuiltin,false,path);
case (Absyn.IDENT(name = id),_)
equation
_ = elabBuiltinHandler(id);
then
(DAE.FUNCTION_BUILTIN(),inPath);
(DAE.FUNCTION_BUILTIN(SOME(id)),true,inPath);
case (Absyn.QUALIFIED("OpenModelicaInternal",Absyn.IDENT(name = id)),_)
equation
_ = elabBuiltinHandlerInternal(id);
then
(DAE.FUNCTION_BUILTIN(),inPath);
(DAE.FUNCTION_BUILTIN(SOME(id)),true,inPath);
case (Absyn.FULLYQUALIFIED(path),ty)
equation
(DAE.FUNCTION_BUILTIN(),path) = isBuiltinFunc(path,ty);
(isBuiltin as DAE.FUNCTION_BUILTIN(_),_,path) = isBuiltinFunc(path,ty);
then
(DAE.FUNCTION_BUILTIN(),path);
(isBuiltin,true,path);

case (Absyn.QUALIFIED("Connections", Absyn.IDENT("isRoot")),_) then (DAE.FUNCTION_BUILTIN(),inPath);
case (Absyn.QUALIFIED("Connections", Absyn.IDENT("isRoot")),_)
then (DAE.FUNCTION_BUILTIN(NONE()),true,inPath);

// elaborate substring (Modelica.Utilities.Strings.substring(string, startIndex, endIndex)
case (inPath,_)
equation
Builtin.isSubstring(inPath);
_ = elabBuiltinHandler("substring");
then (DAE.FUNCTION_BUILTIN(),inPath);
then (DAE.FUNCTION_BUILTIN(NONE()),true,inPath);

case (path,_) then (DAE.FUNCTION_NOT_BUILTIN(),path);
case (path,_) then (DAE.FUNCTION_NOT_BUILTIN(),false,path);
end matchcontinue;
end isBuiltinFunc;

Expand Down Expand Up @@ -8326,8 +8331,7 @@ algorithm
"The constness of a function depends on the inputs. If all inputs are constant the call itself is constant." ;
(fn_1,functype) = deoverloadFuncname(fn, functype);
tuple_ = isTuple(restype);
(isBuiltin,fn_1) = isBuiltinFunc(fn_1,functype);
builtin = valueEq(DAE.FUNCTION_BUILTIN(),isBuiltin);
(isBuiltin,builtin,fn_1) = isBuiltinFunc(fn_1,functype);
const = Util.listFold(constlist, Types.constAnd, DAE.C_CONST());
const = Util.if_((RTOpts.debugFlag("rml") and not builtin) 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);
Expand Down Expand Up @@ -8548,22 +8552,22 @@ algorithm
then (cache,Util.SUCCESS());

/* Recursive calls (by looking at envinronment) skipped */
case(cache,env,name,false,NONE(),_,_)
case(cache,env,name,_,NONE(),_,_)
equation
false = Env.isTopScope(env);
true = Absyn.pathSuffixOf(name,Env.getEnvName(env));
then (cache,Util.SUCCESS());

/* Recursive calls (by looking in cache) skipped */
case(cache,env,name,false,_,_,_)
case(cache,env,name,_,_,_,_)
equation
(cache,cl,env) = Lookup.lookupClass(cache,env,name,false);
(cache,name) = Inst.makeFullyQualified(cache,env,name);
Env.checkCachedInstFuncGuard(cache,name);
then (cache,Util.SUCCESS());

/* Class must be looked up*/
case(cache,env,name,false,NONE(),_,_)
case(cache,env,name,_,NONE(),_,_)
equation
(cache,cl,env) = Lookup.lookupClass(cache,env,name,false);
(cache,name) = Inst.makeFullyQualified(cache,env,name);
Expand All @@ -8572,14 +8576,14 @@ algorithm
then (cache,Util.SUCCESS());

/* class already available*/
case(cache,env,name,false,SOME(cl),_,_)
case(cache,env,name,_,SOME(cl),_,_)
equation
(cache,name) = Inst.makeFullyQualified(cache,env,name);
(cache,env,_) = Inst.implicitFunctionInstantiation(cache,env,InnerOuter.emptyInstHierarchy,DAE.NOMOD(),Prefix.NOPRE(),Connect.emptySet,cl,{});
then (cache,Util.SUCCESS());

/* Call to function reference variable */
case (cache,env,name,false,NONE(),_,_)
case (cache,env,name,_,NONE(),_,_)
equation
cref = pathToComponentRef(name);
(cache,_,(DAE.T_FUNCTION(funcArg = _),_),_,_,_,env,_,_) = Lookup.lookupVar(cache,env,cref);
Expand Down Expand Up @@ -9025,9 +9029,8 @@ algorithm
Absyn.Path fn;
String name;
DAE.TType tty;
case (_,(tty as DAE.T_FUNCTION(functionAttributes = DAE.FUNCTION_ATTRIBUTES(isBuiltin=DAE.FUNCTION_BUILTIN())),SOME(fn)))
case (_,(tty as DAE.T_FUNCTION(functionAttributes = DAE.FUNCTION_ATTRIBUTES(isBuiltin=DAE.FUNCTION_BUILTIN(SOME(name)))),_))
equation
name = Absyn.pathLastIdent(fn);
fn = Absyn.IDENT(name);
then (fn,(tty,SOME(fn)));
case (_,(DAE.T_FUNCTION(funcArg = _),SOME(fn))) then (fn,inType);
Expand Down Expand Up @@ -10210,7 +10213,7 @@ 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);
(isBuiltin,_,path) = isBuiltinFunc(path,t);
isBuiltinFn = not valueEq(DAE.FUNCTION_NOT_BUILTIN(),isBuiltin);
(tt,optPath) = t;
t = (tt, Util.if_(isBuiltinFn, SOME(path), optPath)) "some builtin functions store NONE() there";
Expand Down
14 changes: 4 additions & 10 deletions Compiler/FrontEnd/Types.mo
Expand Up @@ -2941,11 +2941,8 @@ algorithm
end match;
end getConnectorVars;

protected function isInputVar "function: isInputVar
author: LS

Succeds if variable is an input variable.
"
public function isInputVar
"Succeds if variable is an input variable."
input Var inVar;
algorithm
_:=
Expand All @@ -2963,11 +2960,8 @@ algorithm
end match;
end isInputVar;

protected function isOutputVar "function: isOutputVar
author: LS

Succeds if variable is an output variable.
"
public function isOutputVar
"Succeds if variable is an output variable."
input Var inVar;
algorithm
_:=
Expand Down

0 comments on commit a6fc8da

Please sign in to comment.