From 18e300fecf0d30598a22ce708a98d856d961cf94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 22 Aug 2013 12:39:09 +0000 Subject: [PATCH] Added code to make separate compilation use dummy .stamp files instead of updating C-code. By comparing the generated code to the old, we only re-compile files that actually changed. Added new debug-flag to be able to turn off function inlining (made separate compilation non-deterministic). git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@16893 f25d12d1-65f4-0310-ae8a-bbce733d8d8e --- Compiler/BackEnd/SimCodeUtil.mo | 14 +++++ Compiler/FrontEnd/DAE.mo | 3 + Compiler/FrontEnd/DAEUtil.mo | 13 ++-- Compiler/FrontEnd/Inline.mo | 8 +++ Compiler/FrontEnd/Inst.mo | 89 ++++++---------------------- Compiler/FrontEnd/ModelicaBuiltin.mo | 2 + Compiler/FrontEnd/Static.mo | 15 ++++- Compiler/Script/CevalScript.mo | 46 +++++++------- Compiler/Util/Flags.mo | 5 +- Compiler/Util/List.mo | 51 ++++++++++++++++ Compiler/Util/System.mo | 9 ++- Compiler/runtime/System_omc.c | 6 -- Compiler/runtime/System_rml.c | 12 ++-- Compiler/runtime/systemimpl.c | 2 +- 14 files changed, 164 insertions(+), 111 deletions(-) diff --git a/Compiler/BackEnd/SimCodeUtil.mo b/Compiler/BackEnd/SimCodeUtil.mo index 6dcd37b62df..72f894d0b35 100644 --- a/Compiler/BackEnd/SimCodeUtil.mo +++ b/Compiler/BackEnd/SimCodeUtil.mo @@ -590,6 +590,19 @@ algorithm end matchcontinue; end getCalledFunctionReferences; +protected function orderRecordDecls + input SimCode.RecordDeclaration decl1; + input SimCode.RecordDeclaration decl2; + output Boolean b; +algorithm + b := match (decl1,decl2) + local + Absyn.Path path1,path2; + case (SimCode.RECORD_DECL_DEF(path=path1),SimCode.RECORD_DECL_DEF(path=path2)) then Absyn.pathGe(path1,path2); + else true; + end match; +end orderRecordDecls; + public function elaborateFunctions input Absyn.Program program; input list daeElements; @@ -608,6 +621,7 @@ algorithm (extraRecordDecls, outRecordTypes) := elaborateRecordDeclarationsForMetarecords(literals, {}, {}); (functions, outRecordTypes, extraRecordDecls, outIncludes, includeDirs, libs) := elaborateFunctions2(program, daeElements, {}, outRecordTypes, extraRecordDecls, includes, {}, {}); (extraRecordDecls, _) := elaborateRecordDeclarationsFromTypes(metarecordTypes, extraRecordDecls, outRecordTypes); + extraRecordDecls := List.sort(extraRecordDecls, orderRecordDecls); end elaborateFunctions; protected function elaborateFunctions2 diff --git a/Compiler/FrontEnd/DAE.mo b/Compiler/FrontEnd/DAE.mo index 6ce8bb293a5..dc9bc75145d 100644 --- a/Compiler/FrontEnd/DAE.mo +++ b/Compiler/FrontEnd/DAE.mo @@ -349,6 +349,9 @@ public uniontype InlineType record NORM_INLINE "Normal inline, inline as soon as possible" end NORM_INLINE; + record BUILTIN_EARLY_INLINE "Inline even if inlining is globally disabled by flags." + end BUILTIN_EARLY_INLINE; + record EARLY_INLINE "Inline even earlier than NORM_INLINE. This will display the inlined code in the flattened model and also works for functions calling other functions that should be inlined." end EARLY_INLINE; diff --git a/Compiler/FrontEnd/DAEUtil.mo b/Compiler/FrontEnd/DAEUtil.mo index 76cbed975e7..498c24f3eec 100644 --- a/Compiler/FrontEnd/DAEUtil.mo +++ b/Compiler/FrontEnd/DAEUtil.mo @@ -4602,12 +4602,13 @@ Function for converting a InlineType to a bool. Whether the inline takes place before or after index reduction does not mather. Any kind of inline will result in true. " -input DAE.InlineType it; -output Boolean b; -algorithm b := matchcontinue(it) - case(DAE.NO_INLINE()) then false; - case(_) then true; - end matchcontinue; + input DAE.InlineType it; + output Boolean b; +algorithm + b := match (it) + case DAE.NO_INLINE() then false; + else true; + end match; end convertInlineTypeToBool; public function daeElements "Retrieve the elements from a DAEList" diff --git a/Compiler/FrontEnd/Inline.mo b/Compiler/FrontEnd/Inline.mo index 310e065eecc..99185d310ae 100644 --- a/Compiler/FrontEnd/Inline.mo +++ b/Compiler/FrontEnd/Inline.mo @@ -1402,6 +1402,13 @@ algorithm Boolean generateEvents; Option comment; + /* If we disable inlining by use of flags, we still inline builtin functions */ + case ((DAE.CALL(attr=DAE.CALL_ATTR(inlineType=inlineType)),_)) + equation + false = Flags.isSet(Flags.INLINE_FUNCTIONS); + failure(DAE.BUILTIN_EARLY_INLINE() = inlineType); + then inTuple; + case ((e1 as DAE.CALL(p,args,DAE.CALL_ATTR(inlineType=inlineType)),(fns,_))) equation true = Config.acceptMetaModelicaGrammar(); @@ -2057,6 +2064,7 @@ algorithm case(DAE.NO_INLINE()) then "No inline"; case(DAE.AFTER_INDEX_RED_INLINE()) then "Inline after index reduction"; case(DAE.EARLY_INLINE()) then "Inline as soon as possible"; + case(DAE.BUILTIN_EARLY_INLINE()) then "Inline as soon as possible, even if inlining is globally disabled"; case(DAE.NORM_INLINE()) then "Inline before index reduction"; end matchcontinue; end printInlineTypeStr; diff --git a/Compiler/FrontEnd/Inst.mo b/Compiler/FrontEnd/Inst.mo index a02c498f1fd..0b03d53d578 100644 --- a/Compiler/FrontEnd/Inst.mo +++ b/Compiler/FrontEnd/Inst.mo @@ -127,6 +127,7 @@ protected import Global; protected import Graph; protected import HashTable; protected import HashTable5; +protected import Inline; protected import InstSection; protected import InstExtends; protected import NFInstUtil; @@ -2782,7 +2783,7 @@ algorithm print(intString(dimension)); print("\n");*/ // adrpo: get the inline type of the function - inlineType = isInlineFunc2(el); + inlineType = isInlineFunc(el); then SOME((path, dimension, inlineType)); @@ -11643,7 +11644,7 @@ algorithm // set the source of this element source = DAEUtil.createElementSource(info, Env.getEnvPath(env), PrefixUtil.prefixToCrefOpt(pre), NONE(), NONE()); - inlineType = isInlineFunc2(c); + inlineType = isInlineFunc(c); partialPrefixBool = SCode.partialBool(partialPrefix); daeElts = optimizeFunctionCheckForLocals(fpath,daeElts,NONE(),{},{},{}); @@ -12135,83 +12136,33 @@ algorithm end matchcontinue; end setFullyQualifiedTypename; -public function isInlineFunc " -Author: stefan -function: isInlineFunc - looks up a function and returns whether or not it is an inline function" - input Absyn.Path inPath; - input Env.Cache inCache; - input Env.Env inEnv; - output DAE.InlineType outBoolean; -algorithm - outBoolean := matchcontinue(inPath,inCache,inEnv) - local - Absyn.Path p; - Env.Cache c; - Env.Env env; - SCode.Element cl; - case(p,c,env) - equation - (c,cl,env) = Lookup.lookupClass(c,env,p,true); - then - isInlineFunc2(cl); - case(_,_,_) then DAE.NO_INLINE(); - end matchcontinue; -end isInlineFunc; - -public function isInlineFunc2 " -Author: bjozac 2009-12 - helper function to isInlineFunc" +protected function isInlineFunc input SCode.Element inClass; output DAE.InlineType outInlineType; algorithm outInlineType := matchcontinue(inClass) local - SCode.Annotation ann; - - case SCode.CLASS(cmt=SCode.COMMENT(annotation_=SOME(ann))) - then isInlineFunc3(ann); - - else DAE.NO_INLINE(); - end matchcontinue; -end isInlineFunc2; - -protected function isInlineFunc3 " -Author Stefan - helper function to isInlineFunc2" - input SCode.Annotation ann; - output DAE.InlineType outBoolean; -algorithm - outBoolean := matchcontinue(ann) - local - list cdr; list smlst; - DAE.InlineType res; - case (SCode.ANNOTATION(SCode.MOD(subModLst = smlst))) - equation - res = isInlineFunc4(smlst); - true = DAEUtil.convertInlineTypeToBool(res); - then res; + case SCode.CLASS(cmt=SCode.COMMENT(annotation_=SOME(SCode.ANNOTATION(SCode.MOD(subModLst = smlst))))) + then isInlineFunc2(smlst); + else DAE.NO_INLINE(); end matchcontinue; -end isInlineFunc3; +end isInlineFunc; -protected function isInlineFunc4 " -Author: stefan -function: isInlineFunc4 - helper function to isInlineFunc3" +protected function isInlineFunc2 input list inSubModList; output DAE.InlineType res; algorithm - res := matchcontinue(inSubModList) + res := match (inSubModList) local list cdr; case ({}) then DAE.NO_INLINE(); case (SCode.NAMEMOD("Inline",SCode.MOD(binding = SOME((Absyn.BOOL(true),_)))) :: cdr) equation - failure(DAE.AFTER_INDEX_RED_INLINE() = isInlineFunc4(cdr)); + failure(DAE.AFTER_INDEX_RED_INLINE() = isInlineFunc2(cdr)); then DAE.NORM_INLINE(); case(SCode.NAMEMOD("LateInline",SCode.MOD(binding = SOME((Absyn.BOOL(true),_)))) :: _) @@ -12227,13 +12178,11 @@ algorithm then DAE.AFTER_INDEX_RED_INLINE(); case (SCode.NAMEMOD("__OpenModelica_EarlyInline",SCode.MOD(binding = SOME((Absyn.BOOL(true),_)))) :: cdr) - equation - DAE.NO_INLINE() = isInlineFunc4(cdr); then DAE.EARLY_INLINE(); - case(_ :: cdr) then isInlineFunc4(cdr); - end matchcontinue; -end isInlineFunc4; + case(_ :: cdr) then isInlineFunc2(cdr); + end match; +end isInlineFunc2; protected function stripFuncOutputsMod "strips the assignment modification of the component declared as output" input SCode.Element elem; @@ -17485,7 +17434,7 @@ algorithm inVars = List.filter(vl,Types.isInputVar); outVars = List.filter(vl,Types.isOutputVar); name = SCode.isBuiltinFunction(cl,List.map(inVars,Types.varName),List.map(outVars,Types.varName)); - inlineType = isInlineFunc2(cl); + inlineType = isInlineFunc(cl); isOpenModelicaPure = not SCode.hasBooleanNamedAnnotationInClass(cl,"__OpenModelica_Impure"); then (DAE.FUNCTION_ATTRIBUTES(inlineType,isOpenModelicaPure,isImpure,DAE.FUNCTION_BUILTIN(SOME(name)),DAE.FP_NON_PARALLEL())); @@ -17495,14 +17444,14 @@ algorithm inVars = List.filter(vl,Types.isInputVar); outVars = List.filter(vl,Types.isOutputVar); name = SCode.isBuiltinFunction(cl,List.map(inVars,Types.varName),List.map(outVars,Types.varName)); - inlineType = isInlineFunc2(cl); + inlineType = isInlineFunc(cl); isOpenModelicaPure = not SCode.hasBooleanNamedAnnotationInClass(cl,"__OpenModelica_Impure"); then (DAE.FUNCTION_ATTRIBUTES(inlineType,isOpenModelicaPure,false,DAE.FUNCTION_BUILTIN(SOME(name)),DAE.FP_PARALLEL_FUNCTION())); //parallel functions: non-builtin case (SCode.CLASS(restriction=SCode.R_FUNCTION(SCode.FR_PARALLEL_FUNCTION())),_) equation - inlineType = isInlineFunc2(cl); + inlineType = isInlineFunc(cl); isBuiltin = Util.if_(SCode.hasBooleanNamedAnnotationInClass(cl,"__OpenModelica_BuiltinPtr"), DAE.FUNCTION_BUILTIN_PTR(), DAE.FUNCTION_NOT_BUILTIN()); isOpenModelicaPure = not SCode.hasBooleanNamedAnnotationInClass(cl,"__OpenModelica_Impure"); then DAE.FUNCTION_ATTRIBUTES(inlineType,isOpenModelicaPure,false,isBuiltin,DAE.FP_PARALLEL_FUNCTION()); @@ -17511,9 +17460,9 @@ algorithm case (SCode.CLASS(restriction=SCode.R_FUNCTION(SCode.FR_KERNEL_FUNCTION())),_) then DAE.FUNCTION_ATTRIBUTES(DAE.NO_INLINE(),true,false,DAE.FUNCTION_NOT_BUILTIN(),DAE.FP_KERNEL_FUNCTION()); - case (SCode.CLASS(restriction=restriction),_) + case (SCode.CLASS(name=name,restriction=restriction),_) equation - inlineType = isInlineFunc2(cl); + inlineType = isInlineFunc(cl); isBuiltin = Util.if_(SCode.hasBooleanNamedAnnotationInClass(cl,"__OpenModelica_BuiltinPtr"), DAE.FUNCTION_BUILTIN_PTR(), DAE.FUNCTION_NOT_BUILTIN()); isOpenModelicaPure = not SCode.hasBooleanNamedAnnotationInClass(cl,"__OpenModelica_Impure"); isImpure = SCode.isRestrictionImpure(restriction); diff --git a/Compiler/FrontEnd/ModelicaBuiltin.mo b/Compiler/FrontEnd/ModelicaBuiltin.mo index b6f23a12c9f..463c902bcc1 100644 --- a/Compiler/FrontEnd/ModelicaBuiltin.mo +++ b/Compiler/FrontEnd/ModelicaBuiltin.mo @@ -1000,6 +1000,7 @@ end generateHeader; function generateSeparateCode input TypeName className[:] := fill($TypeName(AllLoadedClasses),0); + input String stampSuffix := "" "Suffix to add to dependencies (usually .stamp)"; output Boolean success; external "builtin"; annotation(Documentation(info="

Under construction.

@@ -1007,6 +1008,7 @@ annotation(Documentation(info="

Under construction.

end generateSeparateCode; function generateSeparateCodeDependencies + input String stampSuffix := ".c" "Suffix to add to dependencies (often .c.stamp)"; output String [:] dependencies; external "builtin"; annotation(Documentation(info="

Under construction.

diff --git a/Compiler/FrontEnd/Static.mo b/Compiler/FrontEnd/Static.mo index 997de91fd6f..8fc8e469edc 100644 --- a/Compiler/FrontEnd/Static.mo +++ b/Compiler/FrontEnd/Static.mo @@ -7488,6 +7488,7 @@ algorithm (fn_1,functype) := deoverloadFuncname(fn, functype); tuple_ := isTuple(restype); (isBuiltin,builtin,fn_1) := isBuiltinFunc(fn_1,functype); + inlineType := inlineBuiltin(isBuiltin,inlineType); //check the env to see if a call to a parallel or kernle function is a valid one. true := isValidWRTParallelScope(fn,builtin,funcParal,inEnv,info); @@ -7519,7 +7520,7 @@ algorithm /* Instantiate any implicit record constructors needed and add them to the dae function tree */ cache := instantiateImplicitRecordConstructors(cache, inEnv, args_1, st); functionTree := Env.getFunctionTree(cache); - ((call_exp,(_,didInline))) := Inline.inlineCall((call_exp,((SOME(functionTree),{DAE.EARLY_INLINE()}),false))); + ((call_exp,(_,didInline))) := Inline.inlineCall((call_exp,((SOME(functionTree),{DAE.BUILTIN_EARLY_INLINE(),DAE.EARLY_INLINE()}),false))); (call_exp,_) := ExpressionSimplify.condsimplify(didInline,call_exp); didInline := didInline and (not Config.acceptMetaModelicaGrammar() /* Some weird errors when inlining. Becomes boxed even if it shouldn't... */); prop_1 := Debug.bcallret2(didInline, Types.setTypeInProps, restype, prop_1, prop_1); @@ -7527,6 +7528,18 @@ algorithm outCache := cache; end elabCallArgs3; +protected function inlineBuiltin + input DAE.FunctionBuiltin isBuiltin; + input DAE.InlineType inlineType; + output DAE.InlineType outInlineType; +algorithm + outInlineType := match (isBuiltin,inlineType) + case (DAE.FUNCTION_BUILTIN_PTR(),_) + then DAE.BUILTIN_EARLY_INLINE(); + else inlineType; + end match; +end inlineBuiltin; + protected function isValidWRTParallelScope input Absyn.Path inFn; input Boolean isBuiltin; diff --git a/Compiler/Script/CevalScript.mo b/Compiler/Script/CevalScript.mo index 2eaf81a5b38..b6bd2433c8c 100644 --- a/Compiler/Script/CevalScript.mo +++ b/Compiler/Script/CevalScript.mo @@ -824,7 +824,7 @@ algorithm title,xLabel,yLabel,filename2,varNameStr,xml_filename,xml_contents,visvar_str,pwd,omhome,omlib,omcpath,os, platform,usercflags,senddata,res,workdir,gcc,confcmd,touch_file,uname,filenameprefix,compileDir,libDir,exeDir,configDir,from,to, legendStr, gridStr, logXStr, logYStr, x1Str, x2Str, y1Str, y2Str, curveWidthStr, curveStyleStr,scriptFile,logFile, simflags2, outputFile, - systemPath, gccVersion, gd, strlinearizeTime, direction; + systemPath, gccVersion, gd, strlinearizeTime, direction, suffix; list vals; Absyn.Path path,classpath,className,baseClassPath; SCode.Program scodeP,sp; @@ -1876,14 +1876,14 @@ algorithm case (cache,env,"generateEntryPoint",_,st as GlobalScript.SYMBOLTABLE(ast = p),_) then (cache,Values.BOOL(false),st); - case (cache,env,"generateSeparateCodeDependencies",{},(st as GlobalScript.SYMBOLTABLE(ast = p)),_) + case (cache,env,"generateSeparateCodeDependencies",{Values.STRING(suffix)},(st as GlobalScript.SYMBOLTABLE(ast = p)),_) equation sp = SCodeUtil.translateAbsyn2SCode2(p,false); names = List.filterMap(sp,SCode.getElementName); deps = Graph.buildGraph(names,buildDependencyGraph,sp); namesPublic = List.map(List.select(sp, containsPublicInterface), SCode.getElementName); - namesChanged = List.filterMap(sp,getChangedClass); + namesChanged = List.filterMap1(sp,getChangedClass,suffix); hashSetString = HashSetString.emptyHashSet(); hashSetString = List.fold(namesChanged,BaseHashSet.add,hashSetString); // print("namesChanged: " +& stringDelimitList(namesChanged, ",") +& "\n"); @@ -1907,26 +1907,29 @@ algorithm depschanged = List.select1(depsmerged,isChanged,hashSetString); names = List.map(depschanged, Util.tuple21); // print("Files to recompile (" +& intString(listLength(depschanged)) +& "): " +& stringDelimitList(names, ",") +& "\n"); - fileNames = List.map1(names, stringAppend, ".c"); + fileNames = List.map1(names, stringAppend, suffix); _ = List.map(fileNames, System.removeFile); v = ValuesUtil.makeArray(List.map(names,ValuesUtil.makeString)); then (cache,v,st); - case (cache,env,"generateSeparateCode",{Values.ARRAY(valueLst={})},(st as GlobalScript.SYMBOLTABLE(ast = p)),_) + case (cache,env,"generateSeparateCodeDependencies",_,(st as GlobalScript.SYMBOLTABLE(ast = p)),_) + then (cache,Values.META_FAIL(),st); + + case (cache,env,"generateSeparateCode",{Values.ARRAY(valueLst={}),Values.STRING(suffix)},(st as GlobalScript.SYMBOLTABLE(ast = p)),_) equation sp = SCodeUtil.translateAbsyn2SCode(p); setGlobalRoot(Global.instOnlyForcedFunctions,SOME(true)); - deps = generateFunctions(cache,env,p,sp,{}); + deps = generateFunctions(cache,env,p,sp,suffix,{}); setGlobalRoot(Global.instOnlyForcedFunctions,NONE()); then (cache,Values.BOOL(true),st); - case (cache,env,"generateSeparateCode",{Values.ARRAY(valueLst=vals)},(st as GlobalScript.SYMBOLTABLE(ast = p)),_) + case (cache,env,"generateSeparateCode",{Values.ARRAY(valueLst=vals),Values.STRING(suffix)},(st as GlobalScript.SYMBOLTABLE(ast = p)),_) equation sp = SCodeUtil.translateAbsyn2SCode(p); names = List.map(vals,getTypeNameIdent); setGlobalRoot(Global.instOnlyForcedFunctions,SOME(true)); cls = List.map2(names,List.getMemberOnTrue, sp, SCode.isClassNamed); - deps = generateFunctions(cache,env,p,cls,{}); + deps = generateFunctions(cache,env,p,cls,suffix,{}); setGlobalRoot(Global.instOnlyForcedFunctions,NONE()); then (cache,Values.BOOL(true),st); @@ -4657,13 +4660,14 @@ protected function generateFunctions input Env.Env ienv; input Absyn.Program p; input list isp; + input String stamp; input list>> iacc; output list>> deps; algorithm - deps := matchcontinue (icache,ienv,p,isp,iacc) + deps := matchcontinue (icache,ienv,p,isp,stamp,iacc) local String name; - list names,dependencies; + list names,dependencies,dependenciesStamp; list paths; list elementLst; DAE.FunctionTree funcs; @@ -4677,8 +4681,8 @@ algorithm Absyn.Info info; SCode.Element cl; - case (cache,env,_,{},acc) then acc; - case (cache,env,_,(cl as SCode.CLASS(name=name,encapsulatedPrefix=SCode.ENCAPSULATED(),restriction=SCode.R_PACKAGE(),classDef=SCode.PARTS(elementLst=elementLst),info=info as Absyn.INFO(fileName=file)))::sp,acc) + case (cache,env,_,{},_,acc) then acc; + case (cache,env,_,(cl as SCode.CLASS(name=name,encapsulatedPrefix=SCode.ENCAPSULATED(),restriction=SCode.R_PACKAGE(),classDef=SCode.PARTS(elementLst=elementLst),info=info as Absyn.INFO(fileName=file)))::sp,_,acc) equation (0,_) = System.regex(file, "ModelicaBuiltin.mo$", 1, false, false); names = List.map(List.filterOnTrue(List.map(List.filterOnTrue(elementLst, SCode.elementIsClass), SCode.getElementClass), SCode.isFunction), SCode.className); @@ -4690,17 +4694,18 @@ algorithm (_,(_,dependencies)) = DAEUtil.traverseDAEFunctions(d,Expression.traverseSubexpressionsHelper,(matchQualifiedCalls,{}),{}); // print(name +& " has dependencies: " +& stringDelimitList(dependencies,",") +& "\n"); acc = (name,dependencies)::acc; + dependencies = List.sort(dependencies,Util.strcmpBool); dependencies = List.map1(dependencies,stringAppend,".h"); nameHeader = name +& ".h"; - System.writeFile(name +& ".deps", name +& ".o: " +& name +& ".c " +& stringDelimitList(nameHeader::dependencies," ")); + System.writeFile(name +& ".deps", name +& ".o: " +& name +& ".c" +& " " +& stringDelimitList(nameHeader::dependencies," ")); dependencies = List.map1(dependencies,stringAppend,"\""); dependencies = List.map1r(dependencies,stringAppend,"#include \""); SimCodeMain.translateFunctions(p, name, NONE(), d, {}, dependencies); str = Tpl.tplString(Unparsing.programExternalHeader, {cl}); System.writeFile(name +& "_records.c","#include \n" +& str); - acc = generateFunctions(cache,env,p,sp,acc); + acc = generateFunctions(cache,env,p,sp,stamp,acc); then acc; - case (cache,env,_,SCode.CLASS(encapsulatedPrefix=SCode.NOT_ENCAPSULATED(),name=name,info=info as Absyn.INFO(fileName=file))::sp,acc) + case (cache,env,_,SCode.CLASS(encapsulatedPrefix=SCode.NOT_ENCAPSULATED(),name=name,info=info as Absyn.INFO(fileName=file))::sp,_,acc) equation (n,_) = System.regex(file, "ModelicaBuiltin.mo$", 1, false, false); Error.assertion(n > 0, "Not an encapsulated class (required for separate compilation): " +& name, info); @@ -7060,18 +7065,19 @@ end printInterfaceString; protected function getChangedClass input SCode.Element elt; + input String suffix; output String name; algorithm - name := matchcontinue elt + name := matchcontinue (elt,suffix) local String fileName; - case SCode.CLASS(name=name,info=Absyn.INFO(fileName=fileName)) + case (SCode.CLASS(name=name,info=Absyn.INFO(fileName=fileName)),_) equation - false = System.regularFileExists(name +& ".c"); + false = System.regularFileExists(name +& suffix); then name; - case SCode.CLASS(name=name,info=Absyn.INFO(fileName=fileName)) + case (SCode.CLASS(name=name,info=Absyn.INFO(fileName=fileName)),_) equation - true = System.fileIsNewerThan(fileName, name +& ".c"); + true = System.fileIsNewerThan(fileName, name +& suffix); then name; end matchcontinue; end getChangedClass; diff --git a/Compiler/Util/Flags.mo b/Compiler/Util/Flags.mo index 7213ec78c13..867735798d9 100644 --- a/Compiler/Util/Flags.mo +++ b/Compiler/Util/Flags.mo @@ -357,7 +357,9 @@ constant DebugFlag HPCOM = DEBUG_FLAG(95, "hpcom", false, Util.gettext("Enables parallel calculation based on task-graphs.")); constant DebugFlag INITIALIZATION = DEBUG_FLAG(96, "initialization", false, Util.gettext("Shows additional information from the initialization process.")); -constant DebugFlag DUMP_SCC_GRAPHML = DEBUG_FLAG(97, "dumpSCCGraphML", false, +constant DebugFlag INLINE_FUNCTIONS = DEBUG_FLAG(97, "inlineFunctions", true, + Util.gettext("Controls if function inlining should be performed.")); +constant DebugFlag DUMP_SCC_GRAPHML = DEBUG_FLAG(98, "dumpSCCGraphML", false, Util.gettext("Dumps graphml files with the strongly connected components.")); // This is a list of all debug flags, to keep track of which flags are used. A @@ -461,6 +463,7 @@ constant list allDebugFlags = { GEN_GRAPH, HPCOM, INITIALIZATION, + INLINE_FUNCTIONS, DUMP_SCC_GRAPHML }; diff --git a/Compiler/Util/List.mo b/Compiler/Util/List.mo index f3a38c4b5b1..fccaec4db4d 100644 --- a/Compiler/Util/List.mo +++ b/Compiler/Util/List.mo @@ -7278,6 +7278,57 @@ algorithm end matchcontinue; end filterMap_tail; +public function filterMap1 + "Applies a function to each element in the given list, but also filters out + all elements for which the function fails." + input list inList; + input FilterMapFunc inFilterMapFunc; + input ElementType1 inExtraArg; + output list outList; + + partial function FilterMapFunc + input ElementInType inElement; + input ElementType1 inExtraArg; + output ElementOutType outElement; + end FilterMapFunc; +algorithm + outList := listReverse(filterMap1_tail(inList, inFilterMapFunc, inExtraArg, {})); +end filterMap1; + +protected function filterMap1_tail + "Tail recursive implementation of filterMap." + input list inList; + input FilterMapFunc inFilterMapFunc; + input ElementType1 inExtraArg; + input list inAccumList; + output list outList; + + partial function FilterMapFunc + input ElementInType inElement; + input ElementType1 inExtraArg; + output ElementOutType outElement; + end FilterMapFunc; +algorithm + outList := matchcontinue(inList, inFilterMapFunc, inExtraArg, inAccumList) + local + ElementInType ie; + list rest; + ElementOutType oe; + + case (ie :: rest, _, _, _) + equation + oe = inFilterMapFunc(ie,inExtraArg); + then + filterMap1_tail(rest, inFilterMapFunc, inExtraArg, oe :: inAccumList); + + case (_ :: rest, _, _, _) + then filterMap1_tail(rest, inFilterMapFunc, inExtraArg, inAccumList); + + case ({}, _, _, _) then inAccumList; + + end matchcontinue; +end filterMap1_tail; + public function filterOnTrue "Takes a list of values and a filter function over the values and returns a sub list of values for which the matching function returns true. diff --git a/Compiler/Util/System.mo b/Compiler/Util/System.mo index bdbe84b47d9..875d661df77 100644 --- a/Compiler/Util/System.mo +++ b/Compiler/Util/System.mo @@ -392,9 +392,16 @@ end regularFileExists; public function removeFile "Removes a file, returns 0 if suceeds, implemented using remove() in stdio.h" input String fileName; output Integer res; - external "C" res=System_removeFile(fileName) annotation(Library = "omcruntime"); + external "C" res=SystemImpl__removeFile(fileName) annotation(Library = "omcruntime"); end removeFile; +public function renameFile "Removes a file, returns 0 if suceeds, implemented using remove() in stdio.h" + input String fileName1; + input String fileName2; + output Integer res; + external "C" res=rename(fileName1,fileName2) annotation(Include="#include "); +end renameFile; + /* TODO: Implement an external C function for bootstrapped omc or remove me. DO NOT SIMPLY REMOVE THIS COMMENT public function getPackageFileNames input String inString1; diff --git a/Compiler/runtime/System_omc.c b/Compiler/runtime/System_omc.c index fa3e0f52a32..6496c9f93e9 100644 --- a/Compiler/runtime/System_omc.c +++ b/Compiler/runtime/System_omc.c @@ -61,12 +61,6 @@ extern void System_appendFile(const char *filename, const char *data) MMC_THROW(); } -extern int System_removeFile(const char* filename) -{ - return SystemImpl__removeFile(filename); -} - - extern char* System_readFile(const char* filename) { return SystemImpl__readFile(filename); diff --git a/Compiler/runtime/System_rml.c b/Compiler/runtime/System_rml.c index 95c6e1f83bd..472bee3ebb0 100644 --- a/Compiler/runtime/System_rml.c +++ b/Compiler/runtime/System_rml.c @@ -533,12 +533,14 @@ RML_END_LABEL RML_BEGIN_LABEL(System__removeFile) { - char* str = RML_STRINGDATA(rmlA0); - int ret_val; - ret_val = remove(str); - - rmlA0 = (void*) mk_icon(ret_val); + rmlA0 = (void*) mk_icon(SystemImpl__removeFile(RML_STRINGDATA(rmlA0))); + RML_TAILCALLK(rmlSC); +} +RML_END_LABEL +RML_BEGIN_LABEL(System__renameFile) +{ + rmlA0 = (void*) mk_icon(rename(RML_STRINGDATA(rmlA0),RML_STRINGDATA(rmlA1))); RML_TAILCALLK(rmlSC); } RML_END_LABEL diff --git a/Compiler/runtime/systemimpl.c b/Compiler/runtime/systemimpl.c index 26973ee65d7..a007aa5de58 100644 --- a/Compiler/runtime/systemimpl.c +++ b/Compiler/runtime/systemimpl.c @@ -615,7 +615,7 @@ void* SystemImpl__systemCallParallel(void *lst) #pragma omp parallel for private(i) schedule(dynamic) for (i=0; i