Skip to content

Commit

Permalink
Changes to ModelicaBuiltin
Browse files Browse the repository at this point in the history
- Added type inference for Modelica builtin operators.
  When using annotation __OpenModelica_UnboxArguments=true, the result
  is an expression that is not boxed.
- Made the following functions not use the elabBuiltinHandler
  - delay (with a fix in ExpressionSimplify for 2->3 args)
  - diagonal
  - previous
  - subSample
  - superSample
  • Loading branch information
sjoelund authored and OpenModelica-Hudson committed Feb 9, 2017
1 parent e4c31ea commit 674967b
Show file tree
Hide file tree
Showing 14 changed files with 171 additions and 348 deletions.
29 changes: 14 additions & 15 deletions Compiler/FFrontEnd/FBuiltin.mo
Expand Up @@ -350,10 +350,16 @@ public function getInitialFunctions
"Fetches the Absyn.Program representation of the functions (and other classes) in the initial environment"
output Absyn.Program initialProgram;
output SCode.Program initialSCodeProgram;
protected
String fileModelica,fileMetaModelica,fileParModelica,filePDEModelica;
algorithm
fileModelica := Settings.getInstallationDirectoryPath() + "/lib/omc/ModelicaBuiltin.mo";
fileMetaModelica := Settings.getInstallationDirectoryPath() + "/lib/omc/MetaModelicaBuiltin.mo";
fileParModelica := Settings.getInstallationDirectoryPath() + "/lib/omc/ParModelicaBuiltin.mo";
filePDEModelica := Settings.getInstallationDirectoryPath() + "/lib/omc/PDEModelicaBuiltin.mo";

(initialProgram,initialSCodeProgram) := matchcontinue ()
local
String fileModelica,fileMetaModelica,fileParModelica,filePDEModelica;
list<tuple<Integer,tuple<Absyn.Program,SCode.Program>>> assocLst;
list<Absyn.Class> classes,classes1,classes2;
Absyn.Program p;
Expand All @@ -371,12 +377,10 @@ algorithm
case ()
equation
true = intEq(Flags.getConfigEnum(Flags.GRAMMAR), Flags.METAMODELICA);
fileModelica = Settings.getInstallationDirectoryPath() + "/lib/omc/ModelicaBuiltin.mo";
fileMetaModelica = Settings.getInstallationDirectoryPath() + "/lib/omc/MetaModelicaBuiltin.mo";
Error.assertionOrAddSourceMessage(System.regularFileExists(fileModelica),Error.FILE_NOT_FOUND_ERROR,{fileModelica},Absyn.dummyInfo);
Error.assertionOrAddSourceMessage(System.regularFileExists(fileMetaModelica),Error.FILE_NOT_FOUND_ERROR,{fileMetaModelica},Absyn.dummyInfo);
Absyn.PROGRAM(classes=classes1,within_=Absyn.TOP()) = Parser.parsebuiltin(fileModelica,"UTF-8");
Absyn.PROGRAM(classes=classes2,within_=Absyn.TOP()) = Parser.parsebuiltin(fileMetaModelica,"UTF-8");
Absyn.PROGRAM(classes=classes1,within_=Absyn.TOP()) = Parser.parsebuiltin(fileModelica,"UTF-8",acceptedGram=Flags.METAMODELICA);
Absyn.PROGRAM(classes=classes2,within_=Absyn.TOP()) = Parser.parsebuiltin(fileMetaModelica,"UTF-8",acceptedGram=Flags.METAMODELICA);
classes = listAppend(classes1,classes2);
p = Absyn.PROGRAM(classes,Absyn.TOP());
(p as Absyn.PROGRAM(classes=classes)) = MetaUtil.createMetaClassesInProgram(p);
Expand All @@ -387,12 +391,10 @@ algorithm
case ()
equation
true = intEq(Flags.getConfigEnum(Flags.GRAMMAR), Flags.PARMODELICA);
fileModelica = Settings.getInstallationDirectoryPath() + "/lib/omc/ModelicaBuiltin.mo";
fileParModelica = Settings.getInstallationDirectoryPath() + "/lib/omc/ParModelicaBuiltin.mo";
Error.assertionOrAddSourceMessage(System.regularFileExists(fileModelica),Error.FILE_NOT_FOUND_ERROR,{fileModelica},Absyn.dummyInfo);
Error.assertionOrAddSourceMessage(System.regularFileExists(fileParModelica),Error.FILE_NOT_FOUND_ERROR,{fileParModelica},Absyn.dummyInfo);
Absyn.PROGRAM(classes=classes1,within_=Absyn.TOP()) = Parser.parsebuiltin(fileModelica,"UTF-8");
Absyn.PROGRAM(classes=classes2,within_=Absyn.TOP()) = Parser.parsebuiltin(fileParModelica,"UTF-8");
Absyn.PROGRAM(classes=classes1,within_=Absyn.TOP()) = Parser.parsebuiltin(fileModelica,"UTF-8",acceptedGram=Flags.METAMODELICA);
Absyn.PROGRAM(classes=classes2,within_=Absyn.TOP()) = Parser.parsebuiltin(fileParModelica,"UTF-8",acceptedGram=Flags.METAMODELICA);
classes = listAppend(classes1,classes2);
p = Absyn.PROGRAM(classes,Absyn.TOP());
sp = List.map(classes, SCodeUtil.translateClass);
Expand All @@ -402,22 +404,19 @@ algorithm
case ()
equation
true = intEq(Flags.getConfigEnum(Flags.GRAMMAR), Flags.MODELICA) or intEq(Flags.getConfigEnum(Flags.GRAMMAR), Flags.OPTIMICA);
fileModelica = Settings.getInstallationDirectoryPath() + "/lib/omc/ModelicaBuiltin.mo";
Error.assertionOrAddSourceMessage(System.regularFileExists(fileModelica),Error.FILE_NOT_FOUND_ERROR,{fileModelica},Absyn.dummyInfo);
(p as Absyn.PROGRAM(classes=classes)) = Parser.parsebuiltin(fileModelica,"UTF-8");
(p as Absyn.PROGRAM(classes=classes)) = Parser.parsebuiltin(fileModelica,"UTF-8",acceptedGram=Flags.METAMODELICA);
sp = List.map(classes, SCodeUtil.translateClass);
assocLst = getGlobalRoot(Global.builtinIndex);
setGlobalRoot(Global.builtinIndex, (Flags.MODELICA,(p,sp))::assocLst);
then (p,sp);
case ()
equation
true = intEq(Flags.getConfigEnum(Flags.GRAMMAR), Flags.PDEMODELICA);
fileModelica = Settings.getInstallationDirectoryPath() + "/lib/omc/ModelicaBuiltin.mo";
filePDEModelica = Settings.getInstallationDirectoryPath() + "/lib/omc/PDEModelicaBuiltin.mo";
Error.assertionOrAddSourceMessage(System.regularFileExists(fileModelica),Error.FILE_NOT_FOUND_ERROR,{fileModelica},Absyn.dummyInfo);
Error.assertionOrAddSourceMessage(System.regularFileExists(filePDEModelica),Error.FILE_NOT_FOUND_ERROR,{filePDEModelica},Absyn.dummyInfo);
Absyn.PROGRAM(classes=classes1,within_=Absyn.TOP()) = Parser.parsebuiltin(fileModelica,"UTF-8");
Absyn.PROGRAM(classes=classes2,within_=Absyn.TOP()) = Parser.parsebuiltin(filePDEModelica,"UTF-8");
Absyn.PROGRAM(classes=classes1,within_=Absyn.TOP()) = Parser.parsebuiltin(fileModelica,"UTF-8",acceptedGram=Flags.METAMODELICA);
Absyn.PROGRAM(classes=classes2,within_=Absyn.TOP()) = Parser.parsebuiltin(filePDEModelica,"UTF-8",acceptedGram=Flags.METAMODELICA);
classes = listAppend(classes1,classes2);
p = Absyn.PROGRAM(classes,Absyn.TOP());
sp = List.map(classes, SCodeUtil.translateClass);
Expand Down
5 changes: 3 additions & 2 deletions Compiler/FrontEnd/DAE.mo
Expand Up @@ -1044,10 +1044,10 @@ partial function EvaluateSingletonTypeFunction
output Type ty;
end EvaluateSingletonTypeFunction;

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

public
uniontype FunctionAttributes
Expand All @@ -1068,6 +1068,7 @@ uniontype FunctionBuiltin

record FUNCTION_BUILTIN "Function is builtin"
Option<String> name;
Boolean unboxArgs;
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."
Expand Down
6 changes: 6 additions & 0 deletions Compiler/FrontEnd/ExpressionSimplify.mo
Expand Up @@ -1250,6 +1250,12 @@ algorithm
guard Expression.isConst(e1)
then Expression.makeConstZeroE(e1);

// We only match delay with 3 arguments in most places...
case e as DAE.CALL(path=Absyn.IDENT("delay"),expLst={e1,e2})
algorithm
e.expLst := {e1,e2,e2};
then e;

// delay of constant expression
case DAE.CALL(path=Absyn.IDENT("delay"),expLst={e1,_,_})
guard Expression.isConst(e1)
Expand Down
4 changes: 2 additions & 2 deletions Compiler/FrontEnd/Inst.mo
Expand Up @@ -2420,7 +2420,7 @@ algorithm
SCode.DERIVED(Absyn.TCOMPLEX(Absyn.IDENT("polymorphic"),{Absyn.TPATH(Absyn.IDENT("Any"),NONE())},NONE()),modifications = mod, attributes=DA),
_,_,_,_,inst_dims,impl,_,graph,_,_,_,_,_)
equation
true = Config.acceptMetaModelicaGrammar();
// true = Config.acceptMetaModelicaGrammar(); // We use this for builtins also
false = Util.getStatefulBoolean(stopInst);
true = Mod.emptyModOrEquality(mods) and SCode.emptyModOrEquality(mod);
(cache,_,ih,_,csets,oDA) = instClassDefHelper(cache,env,ih,{},pre,inst_dims,impl,{}, inSets,info);
Expand All @@ -2432,7 +2432,7 @@ algorithm
SCode.DERIVED(typeSpec=Absyn.TCOMPLEX(path=Absyn.IDENT("polymorphic")),modifications=mod),
_,_,_,_,_,_,_,_,_,_,_,_,_)
equation
true = Config.acceptMetaModelicaGrammar();
// true = Config.acceptMetaModelicaGrammar(); // We use this for builtins also
true = Mod.emptyModOrEquality(mods) and SCode.emptyModOrEquality(mod);
Error.addSourceMessage(Error.META_POLYMORPHIC, {className}, info);
then fail();
Expand Down
2 changes: 1 addition & 1 deletion Compiler/FrontEnd/InstFunction.mo
Expand Up @@ -403,7 +403,7 @@ algorithm

ty1 = InstUtil.setFullyQualifiedTypename(ty,fpath);
checkExtObjOutput(ty1,info);
(ty1,_) = Types.traverseType(ty1, -1, Types.makeExpDimensionsUnknown);
// (ty1,_) = Types.traverseType(ty1, -1, Types.makeExpDimensionsUnknown);
env_1 = FGraph.mkTypeNode(cenv, n, ty1);
vis = SCode.PUBLIC();
(cache,tempenv,ih,_,_,_,_,_,_,_,_,_) =
Expand Down
8 changes: 5 additions & 3 deletions Compiler/FrontEnd/InstUtil.mo
Expand Up @@ -7208,7 +7208,7 @@ algorithm
attr := matchcontinue (cl,vl)
local
SCode.Restriction restriction;
Boolean isOpenModelicaPure, isImpure, hasOutVars;
Boolean isOpenModelicaPure, isImpure, hasOutVars, unboxArgs;
DAE.FunctionBuiltin isBuiltin;
DAE.InlineType inlineType;
String name;
Expand All @@ -7222,7 +7222,8 @@ algorithm
inlineType = isInlineFunc(cl);
isOpenModelicaPure = not SCode.hasBooleanNamedAnnotationInClass(cl,"__OpenModelica_Impure");
isImpure = if isImpure then true else SCode.hasBooleanNamedAnnotationInClass(cl,"__ModelicaAssociation_Impure");
then (DAE.FUNCTION_ATTRIBUTES(inlineType,isOpenModelicaPure,isImpure,false,DAE.FUNCTION_BUILTIN(SOME(name)),DAE.FP_NON_PARALLEL()));
unboxArgs = SCode.hasBooleanNamedAnnotationInClass(cl, "__OpenModelica_UnboxArguments");
then (DAE.FUNCTION_ATTRIBUTES(inlineType,isOpenModelicaPure,isImpure,false,DAE.FUNCTION_BUILTIN(SOME(name), unboxArgs),DAE.FP_NON_PARALLEL()));

//parallel functions: There are some builtin functions.
case (SCode.CLASS(restriction=SCode.R_FUNCTION(SCode.FR_PARALLEL_FUNCTION())),_)
Expand All @@ -7232,7 +7233,8 @@ algorithm
name = SCode.isBuiltinFunction(cl,List.map(inVars,Types.varName),List.map(outVars,Types.varName));
inlineType = isInlineFunc(cl);
isOpenModelicaPure = not SCode.hasBooleanNamedAnnotationInClass(cl,"__OpenModelica_Impure");
then (DAE.FUNCTION_ATTRIBUTES(inlineType,isOpenModelicaPure,false,false,DAE.FUNCTION_BUILTIN(SOME(name)),DAE.FP_PARALLEL_FUNCTION()));
unboxArgs = SCode.hasBooleanNamedAnnotationInClass(cl, "__OpenModelica_UnboxArguments");
then (DAE.FUNCTION_ATTRIBUTES(inlineType,isOpenModelicaPure,false,false,DAE.FUNCTION_BUILTIN(SOME(name), unboxArgs),DAE.FP_PARALLEL_FUNCTION()));

//parallel functions: non-builtin
case (SCode.CLASS(restriction=SCode.R_FUNCTION(SCode.FR_PARALLEL_FUNCTION())),_)
Expand Down
97 changes: 70 additions & 27 deletions Compiler/FrontEnd/ModelicaBuiltin.mo
Expand Up @@ -367,12 +367,10 @@ end skew;
// SCodeFlatten to define which builtin functions exist (SCodeFlatten doesn't
// care how the functions are defined, only if they exist or not).

impure function delay "Delay expression"
external "builtin";
function delay = $overload(OpenModelica.Internal.delay2,OpenModelica.Internal.delay3) "Delay expression"
annotation(__OpenModelica_Impure=true, Documentation(info="<html>
See <a href=\"modelica://ModelicaReference.Operators.'delay()'\">delay()</a>
</html>"));
end delay;

function min "Returns the smallest element"
external "builtin";
Expand Down Expand Up @@ -423,9 +421,11 @@ function smooth "Indicate smoothness of expression"
</html>"));
end smooth;

function diagonal "Returns a diagonal matrix"
function diagonal<T> "Returns a diagonal matrix"
input T v[:];
output T mat[size(v,1),size(v,1)];
external "builtin";
annotation(Documentation(info="<html>
annotation(__OpenModelica_UnboxArguments=true, Documentation(info="<html>
See <a href=\"modelica://ModelicaReference.Operators.'diagonal()'\">diagonal()</a>
</html>"));
end diagonal;
Expand Down Expand Up @@ -495,34 +495,13 @@ function sample "Overloaded operator to either trigger time events or to convert
</html>"));
end sample;

function previous "Access previous value of a clocked variable"
external "builtin";
annotation(Documentation(info="<html>
See <a href=\"modelica://ModelicaReference.Operators.'previous()'\">previous()</a>
</html>"));
end previous;

function hold "Conversion from clocked discrete-time to continuous time"
external "builtin";
annotation(Documentation(info="<html>
See <a href=\"modelica://ModelicaReference.Operators.'hold()'\">hold()</a>
</html>"));
end hold;

impure function subSample "Conversion from faster clock to slower clock"
external "builtin";
annotation(Documentation(info="<html>
See <a href=\"modelica://ModelicaReference.Operators.'subSample()'\">subSample()</a>
</html>"));
end subSample;

function superSample "Conversion from slower clock to faster clock"
external "builtin";
annotation(Documentation(info="<html>
See <a href=\"modelica://ModelicaReference.Operators.'superSample()'\">superSample()</a>
</html>"));
end superSample;

function shiftSample "First activation of clock is shifted in time"
external "builtin";
annotation(Documentation(info="<html>
Expand Down Expand Up @@ -815,13 +794,33 @@ external "builtin";
annotation(version="Modelica 3.3");
end spatialDistribution;

function previous<T> "Access previous value of a clocked variable"
input T u;
output T y;
external "builtin";
annotation(__OpenModelica_UnboxArguments=true, version="Modelica 3.3", Documentation(info="<html>
See <a href=\"modelica://ModelicaReference.Operators.'previous()'\">previous()</a>
</html>"));
end previous;

function subSample = $overload(OpenModelica.Internal.subSampleExpression, OpenModelica.Internal.subSampleClock)
"Conversion from faster clock to slower clock"
annotation(version="Modelica 3.3", Documentation(info="<html>
See <a href=\"modelica://ModelicaReference.Operators.'subSample()'\">subSample()</a>
</html>"));

function superSample = $overload(OpenModelica.Internal.superSampleExpression, OpenModelica.Internal.superSampleClock)
"Conversion from slower clock to faster clock"
annotation(version="Modelica 3.3", Documentation(info="<html>
See <a href=\"modelica://ModelicaReference.Operators.'superSample()'\">superSample()</a>
</html>"));

/* Actually contains more...
record SimulationResult
String resultFile;
String simulationOptions;
String messages;
end SimulationResult; */

encapsulated package OpenModelica "OpenModelica internal defintions and scripting functions"

type $Code "Code quoting is not a uniontype yet because that would require enabling MetaModelica extensions in the regular compiler.
Expand Down Expand Up @@ -851,6 +850,50 @@ package Internal "Contains internal implementations, e.g. overloaded builtin fun
type BuiltinType "Integer,Real,String,enumeration or array of some kind"
end BuiltinType;

impure function subSampleExpression<T>
input T u;
parameter input Integer factor(min=0)=0;
output T y;
external "builtin" y=subSample(u,factor);
annotation(__OpenModelica_UnboxArguments=true);
end subSampleExpression;

impure function subSampleClock
input Clock u;
parameter input Integer factor(min=0)=0;
output Clock y;
external "builtin" y=subSample(u,factor);
end subSampleClock;

impure function superSampleExpression<T>
input T u;
parameter input Integer factor(min=0)=0;
output T y;
external "builtin" y=superSample(u,factor);
annotation(__OpenModelica_UnboxArguments=true);
end superSampleExpression;

impure function superSampleClock
input Clock u;
parameter input Integer factor(min=0)=0;
output Clock y;
external "builtin" y=superSample(u,factor);
end superSampleClock;

impure function delay2
input Real expr;
parameter input Real delayTime;
output Real value;
external "builtin" value=delay(expr, delayTime);
end delay2;

impure function delay3
input Real expr, delayTime;
parameter input Real delayMax;
output Real value;
external "builtin" value=delay(expr, delayTime, delayMax);
end delay3;

function intAbs
input Integer v;
output Integer o;
Expand Down
4 changes: 3 additions & 1 deletion Compiler/FrontEnd/Parser.mo
Expand Up @@ -84,13 +84,15 @@ end parsestring;
function parsebuiltin "Like parse, but skips the SCode check to avoid infinite loops for ModelicaBuiltin.mo."
input String filename;
input String encoding;
input Integer acceptedGram=Config.acceptedGrammar();
input Integer languageStandardInt=Flags.getConfigEnum(Flags.LANGUAGE_STANDARD);
output Absyn.Program outProgram;
annotation(__OpenModelica_EarlyInline = true);
protected
String realpath;
algorithm
realpath := Util.replaceWindowsBackSlashWithPathDelimiter(System.realpath(filename));
outProgram := ParserExt.parse(realpath, Util.testsuiteFriendly(realpath), Config.acceptedGrammar(), encoding, Flags.getConfigEnum(Flags.LANGUAGE_STANDARD), Config.getRunningTestsuite());
outProgram := ParserExt.parse(realpath, Util.testsuiteFriendly(realpath), acceptedGram, encoding, languageStandardInt, Config.getRunningTestsuite());
end parsebuiltin;

function parsestringexp "Parse a string as if it was a sequence of statements"
Expand Down
6 changes: 6 additions & 0 deletions Compiler/FrontEnd/PrefixUtil.mo
Expand Up @@ -915,6 +915,12 @@ algorithm
case (cache,_,_,DAE.META_OPTION(NONE()),_)
equation
then (cache,DAE.META_OPTION(NONE()));

case (cache,env,ih,e as DAE.UNBOX(e1),p)
equation
(cache,e1) = prefixExp(cache, env, ih, e1, p);
e.exp = e1;
then (cache,e);
// ------------------------

// no prefix, return the input expression
Expand Down

0 comments on commit 674967b

Please sign in to comment.