Skip to content

Commit cbbe306

Browse files
committed
- SimCode.getCalledFunctionsInFunction now uses a HashTable; this is a lot faster for large functions
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@7619 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent 13d4651 commit cbbe306

File tree

2 files changed

+44
-147
lines changed

2 files changed

+44
-147
lines changed

Compiler/BackEnd/SimCode.mo

Lines changed: 43 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public import Env;
6262
public import Dependency;
6363
public import Interactive;
6464
public import HashTableExpToIndex;
65+
public import HashTableStringToPath;
6566
public import Absyn;
6667
public import Ceval;
6768
public import Tpl;
@@ -7634,92 +7635,85 @@ protected function getCalledFunctionsInFunctions
76347635
Goes through the given DAE, finds the given functions and collects
76357636
the names of the functions called from within those functions"
76367637
input list<Absyn.Path> paths;
7637-
input list<Absyn.Path> accumulated;
7638+
input HashTableStringToPath.HashTable ht;
76387639
input DAE.FunctionTree funcs;
7639-
output list<Absyn.Path> res;
7640-
protected
7641-
list<list<Absyn.Path>> pathslist;
7640+
output HashTableStringToPath.HashTable outHt;
76427641
algorithm
7643-
res := matchcontinue(paths,accumulated,funcs)
7642+
outHt := match (paths,ht,funcs)
76447643
local
7645-
list<Absyn.Path> acc,rest;
7644+
list<Absyn.Path> rest;
76467645
Absyn.Path path;
7647-
case ({},accumulated,funcs) then accumulated;
7648-
case (path::rest,accumulated,funcs)
7646+
case ({},ht,funcs) then ht;
7647+
case (path::rest,ht,funcs)
76497648
equation
7650-
acc = getCalledFunctionsInFunction(path, accumulated, funcs);
7651-
res = getCalledFunctionsInFunctions(rest, acc, funcs);
7652-
then res;
7653-
end matchcontinue;
7649+
ht = getCalledFunctionsInFunction2(path, Absyn.pathString(path), ht, funcs);
7650+
ht = getCalledFunctionsInFunctions(rest, ht, funcs);
7651+
then ht;
7652+
end match;
76547653
end getCalledFunctionsInFunctions;
76557654

76567655
public function getCalledFunctionsInFunction
7656+
"function: getCalledFunctionsInFunction
7657+
Goes through the given DAE, finds the given function and collects
7658+
the names of the functions called from within those functions"
7659+
input Absyn.Path path;
7660+
input DAE.FunctionTree funcs;
7661+
output list<Absyn.Path> outPaths;
7662+
protected
7663+
HashTableStringToPath.HashTable ht;
7664+
algorithm
7665+
ht := HashTableStringToPath.emptyHashTable();
7666+
ht := getCalledFunctionsInFunction2(path,Absyn.pathString(path),ht,funcs);
7667+
outPaths := BaseHashTable.hashTableValueList(ht);
7668+
end getCalledFunctionsInFunction;
7669+
7670+
protected function getCalledFunctionsInFunction2
76577671
"function: getCalledFunctionsInFunction
76587672
Goes through the given DAE, finds the given function and collects
76597673
the names of the functions called from within those functions"
76607674
input Absyn.Path inPath;
7661-
input list<Absyn.Path> accumulated;
7675+
input String pathstr;
7676+
input HashTableStringToPath.HashTable ht "paths to not add";
76627677
input DAE.FunctionTree funcs;
7663-
output list<Absyn.Path> outAbsynPathLst;
7678+
output HashTableStringToPath.HashTable outHt "paths to not add";
76647679
algorithm
7665-
outAbsynPathLst := matchcontinue (inPath,accumulated,funcs)
7680+
outHt := matchcontinue (inPath,pathstr,ht,funcs)
76667681
local
7667-
String pathstr,debugpathstr;
7682+
String debugpathstr,str;
76687683
Absyn.Path path;
76697684
DAE.Function funcelem;
7670-
list<DAE.Function> funcelems;
7671-
list<DAE.Function> elements;
7672-
list<DAE.Exp> explist,fcallexps,fcallexps_1, fnrefs;
7673-
list<Absyn.ComponentRef> crefs;
7674-
list<Absyn.Path> calledfuncs, res1, res2, res, acc, varfuncs, fnpaths, fns, referencedFuncs, reffuncs;
7685+
list<DAE.Function> funcelems,elements;
7686+
list<Absyn.Path> calledfuncs, varfuncs, fnpaths, fns;
76757687
list<String> debugpathstrs;
76767688
DAE.DAElist dae;
76777689
list<DAE.Element> els;
7678-
String str;
7679-
list<DAE.Element> varlist;
7680-
list<list<DAE.Element>> varlistlist;
76817690

7682-
case (path,acc,_)
7691+
case (path,pathstr,ht,_)
76837692
equation
7684-
true = listMember(path,acc);
7685-
then acc;
7693+
_ = BaseHashTable.get(Absyn.pathString(path), ht);
7694+
then ht;
76867695

7687-
case (path,acc,funcs)
7696+
case (path,pathstr,ht,funcs)
76887697
equation
7689-
false = listMember(path,acc);
76907698
funcelem = DAEUtil.getNamedFunction(path, funcs);
76917699
els = DAEUtil.getFunctionElements(funcelem);
76927700
// Function reference variables are filtered out
76937701
varfuncs = Util.listFold(els, DAEUtil.collectFunctionRefVarPaths, {});
76947702
(_,(_,varfuncs)) = DAEUtil.traverseDAE2(Util.if_(RTOpts.acceptMetaModelicaGrammar(), els, {}),Expression.traverseSubexpressionsHelper,(DAEUtil.collectValueblockFunctionRefVars,varfuncs));
7695-
//print("varfuncs: " +& Util.stringDelimitList(Util.listMap(varfuncs,Absyn.pathString),",") +& "\n");
7696-
// print("Got expressions in " +& Absyn.pathString(path) +& ": " +& ExpressionDump.printExpStr(DAE.TUPLE(explist)) +& "\n");
76977703
(_,(_,(calledfuncs,_))) = DAEUtil.traverseDAE2(els,Expression.traverseSubexpressionsHelper,(matchNonBuiltinCallsAndFnRefPaths,({},varfuncs)));
7698-
//print("calledfuncs: " +& Util.stringDelimitList(Util.listMap(calledfuncs,Absyn.pathString),",") +& "\n");
7699-
res = getCalledFunctionsInFunctions(calledfuncs, path::acc, funcs);
7700-
/*Debug.fprintln("info", "getCalledFunctionsInFunction: " +& Absyn.pathString(path)) "debug" ;
7701-
Debug.fprint("info", "Found variable function refs to ignore: ") "debug" ;
7702-
debugpathstrs = Util.listMap(varfuncs, Absyn.pathString) "debug" ;
7703-
debugpathstr = Util.stringDelimitList(debugpathstrs, ", ") "debug" ;
7704-
Debug.fprintln("info", debugpathstr) "debug" ;
7705-
Debug.fprint("info", "Found called functions: ") "debug" ;
7706-
debugpathstrs = Util.listMap(res, Absyn.pathString) "debug" ;
7707-
debugpathstr = Util.stringDelimitList(debugpathstrs, ", ") "debug" ;
7708-
Debug.fprintln("info", debugpathstr) "debug" ;*/
7709-
then
7710-
res;
7704+
ht = BaseHashTable.add((pathstr,path),ht);
7705+
ht = getCalledFunctionsInFunctions(calledfuncs, ht, funcs);
7706+
then ht;
77117707

7712-
case (path,acc,funcs)
7708+
case (path,pathstr,ht,funcs)
77137709
equation
7714-
false = listMember(path,acc);
77157710
failure(_ = DAEUtil.getNamedFunction(path, funcs));
7716-
pathstr = Absyn.pathString(path);
7717-
str = "SimCode.getCalledFunctionsInFunction: Class " +& pathstr +& " not found in global scope.";
7711+
str = "SimCode.getCalledFunctionsInFunction2: Class " +& pathstr +& " not found in global scope.";
77187712
Error.addMessage(Error.INTERNAL_ERROR,{str});
77197713
then
77207714
fail();
77217715
end matchcontinue;
7722-
end getCalledFunctionsInFunction;
7716+
end getCalledFunctionsInFunction2;
77237717

77247718
protected function getCallPath
77257719
"function: getCallPath

Compiler/Script/CevalScript.mo

Lines changed: 1 addition & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -4637,7 +4637,7 @@ algorithm
46374637
// First check if the main function exists... If it does not it might be an interactive function...
46384638
mainFunction = DAEUtil.getNamedFunction(path, funcs);
46394639
pathstr = generateFunctionName(path);
4640-
paths = cevalGenerateFunctionDAEs(funcs, path, {});
4640+
paths = SimCode.getCalledFunctionsInFunction(path,funcs);
46414641

46424642
// The list of functions is not ordered, so we need to filter out the main function...
46434643
funcs = Env.getFunctionTree(cache);
@@ -4687,101 +4687,4 @@ algorithm
46874687
end matchcontinue;
46884688
end cevalGenerateFunction;
46894689

4690-
protected function cevalGenerateFunctionDAEs "function: cevalGenerateFunctionStr
4691-
Generates a function with the given path, and all functions that are called
4692-
within that function. The two string lists contains names of functions and
4693-
records already generated, which won\'t be generated again."
4694-
input DAE.FunctionTree funcs;
4695-
input Absyn.Path inPath;
4696-
input list<Absyn.Path> inAbsynPathLst;
4697-
output list<Absyn.Path> outAbsynPathLst;
4698-
algorithm
4699-
outAbsynPathLst := matchcontinue (funcs,inPath,inAbsynPathLst)
4700-
local
4701-
Absyn.Path gfmember,path;
4702-
list<Env.Frame> env,env_1,env_2;
4703-
list<Absyn.Path> gflist,calledfuncs,gflist_1;
4704-
SCode.Class cls;
4705-
DAE.DAElist d,d1,d2,d_1;
4706-
list<String> debugfuncs,calledfuncsstrs,libs,libs_2,calledfuncsstrs_1,rt,rt_1,rt_2;
4707-
String debugfuncsstr,funcname,funccom,thisfuncstr,resstr,ss1;
4708-
Env.Cache cache;
4709-
4710-
// If getmember succeeds, path is in generated functions list, so do nothing
4711-
case (funcs,path,gflist)
4712-
equation
4713-
gfmember = Util.listGetMemberOnTrue(path, gflist, ModUtil.pathEqual);
4714-
then
4715-
gflist;
4716-
4717-
// If getmember fails, path is not in generated functions list, hence generate it
4718-
case (funcs,path,gflist)
4719-
equation
4720-
false = RTOpts.debugFlag("nogen");
4721-
failure(_ = Util.listGetMemberOnTrue(path, gflist, ModUtil.pathEqual));
4722-
Debug.fprintln("ceval", "/*- CevalScript.cevalGenerateFunctionDAEs starting*/");
4723-
Debug.fprintln("ceval", "/*- CevalScript.cevalGenerateFunctionDAEs instantiating*/");
4724-
Debug.fprint("ceval", "/*- CevalScript.cevalGenerateFunctionDAEs getting functions: ");
4725-
calledfuncs = SimCode.getCalledFunctionsInFunction(path, gflist, funcs);
4726-
gflist = path :: gflist; // In case the function is recursive
4727-
calledfuncs = Util.listSetDifference(calledfuncs, gflist); // Filter out things we already know will be ignored...
4728-
debugfuncs = Util.listMap(calledfuncs, Absyn.pathString);
4729-
debugfuncsstr = Util.stringDelimitList(debugfuncs, ", ");
4730-
Debug.fprint("ceval", debugfuncsstr);
4731-
Debug.fprintln("ceval", "*/");
4732-
gflist = cevalGenerateFunctionDAEsList(funcs,calledfuncs,gflist);
4733-
Debug.fprint("ceval", "/*- CevalScript.cevalGenerateFunctionDAEs prefixing dae */");
4734-
then
4735-
gflist;
4736-
4737-
// failure
4738-
case (funcs,path,_)
4739-
equation
4740-
true = RTOpts.debugFlag("nogen");
4741-
ss1 = Absyn.pathString(path);
4742-
ss1 = stringAppendList({"/*- CevalScript.cevalGenerateFunctionDAEs failed( ",ss1," ) set \"nogen\" flag to false */\n"});
4743-
Debug.fprint("failtrace", ss1);
4744-
then
4745-
fail();
4746-
4747-
// failtrace
4748-
case (_,path,_)
4749-
equation
4750-
true = RTOpts.debugFlag("failtrace");
4751-
false = RTOpts.debugFlag("nogen");
4752-
ss1 = Absyn.pathString(path);
4753-
ss1 = stringAppendList({"/*- CevalScript.cevalGenerateFunctionDAEs failed( ",ss1," )*/\n"});
4754-
Debug.fprint("failtrace", ss1);
4755-
then
4756-
fail();
4757-
end matchcontinue;
4758-
end cevalGenerateFunctionDAEs;
4759-
4760-
protected function cevalGenerateFunctionDAEsList "function: cevalGenerateFunctionStrList
4761-
Generates code for several functions."
4762-
input DAE.FunctionTree funcs;
4763-
input list<Absyn.Path> inAbsynPathLst1;
4764-
input list<Absyn.Path> inAbsynPathLst3;
4765-
output list<Absyn.Path> outAbsynPathLst;
4766-
algorithm
4767-
outAbsynPathLst := matchcontinue (funcs,inAbsynPathLst1,inAbsynPathLst3)
4768-
local
4769-
list<Env.Frame> env;
4770-
list<Absyn.Path> gflist,gflist_1,gflist_2,rest;
4771-
String firststr;
4772-
list<String> reststr, rt, rt_1, rt_2;
4773-
Absyn.Path first;
4774-
Env.Cache cache;
4775-
list<String> libs_1,libs_2;
4776-
DAE.DAElist d,d1,d2;
4777-
case (funcs,{},gflist) then gflist;
4778-
case (funcs,(first :: rest),gflist)
4779-
equation
4780-
gflist_1 = cevalGenerateFunctionDAEs(funcs,first,gflist);
4781-
gflist_2 = cevalGenerateFunctionDAEsList(funcs,rest,gflist_1);
4782-
then
4783-
gflist_2;
4784-
end matchcontinue;
4785-
end cevalGenerateFunctionDAEsList;
4786-
47874690
end CevalScript;

0 commit comments

Comments
 (0)