Browse Source

Optimize building of the dependency tree

test
Michael Uleysky 9 years ago
parent
commit
3f0b187d8c
  1. 60
      src/deptree.cpp
  2. 7
      src/deptree.h

60
src/deptree.cpp

@ -1,7 +1,7 @@
#include <stack> #include <stack>
#include "deptree.h" #include "deptree.h"
int DepTree::CreateNodeFromVar(const std::string& var, UsedType& used, CallStack& callstack) int DepTree::CreateNodeFromVar(const std::string& var, DepTreeVars& vars, CallStack& callstack)
{ {
COUT(DEBUG)<<"DepTree::CreateNodeFromVar "<<var<<std::endl; COUT(DEBUG)<<"DepTree::CreateNodeFromVar "<<var<<std::endl;
if(G_vars.count(var)==0) if(G_vars.count(var)==0)
@ -12,22 +12,22 @@ int DepTree::CreateNodeFromVar(const std::string& var, UsedType& used, CallStack
UsedType ids; UsedType ids;
used.insert(var); vars[var]=this;
G_vars[var]->UsedIdents(ids); G_vars[var]->UsedIdents(ids);
type=DepTree::VAR; type=DepTree::VAR;
name=var; name=var;
DepTree* d; DepTreeVars::const_iterator d;
int ret; int ret;
callstack.insert(this); callstack.insert(this);
for(auto& i:ids) for(auto& i:ids)
{ {
d=FindNodeByVar(i); d=vars.find(i);
if(d==0) if(d==vars.end())
{ {
auto n=*childrens.insert(new DepTree).first; auto n=*childrens.insert(new DepTree).first;
n->parents.insert(this); n->parents.insert(this);
ret=n->CreateNodeFromVar(i,used,callstack); ret=n->CreateNodeFromVar(i,vars,callstack);
if(ret!=0) if(ret!=0)
{ {
COUT(ERROR)<<" in definition of variable "<<name<<std::endl; COUT(ERROR)<<" in definition of variable "<<name<<std::endl;
@ -36,13 +36,13 @@ int DepTree::CreateNodeFromVar(const std::string& var, UsedType& used, CallStack
} }
else else
{ {
if(callstack.find(d)!=callstack.end()) if(callstack.find(d->second)!=callstack.end())
{ {
COUT(ERROR)<<"Circular dependency of variable "<<name<<" from variable "<<i<<std::endl; COUT(ERROR)<<"Circular dependency of variable "<<name<<" from variable "<<i<<std::endl;
return 1; return 1;
} }
childrens.insert(d); childrens.insert(d->second);
d->parents.insert(this); d->second->parents.insert(this);
} }
} }
callstack.erase(this); callstack.erase(this);
@ -51,7 +51,7 @@ int DepTree::CreateNodeFromVar(const std::string& var, UsedType& used, CallStack
} }
int DepTree::CreateNodeFromSP(DepTree::NodeType list, G_toType::size_type ind, UsedType& used) int DepTree::CreateNodeFromSP(DepTree::NodeType list, G_toType::size_type ind, DepTreeVars& vars)
{ {
if(list!=DepTree::SAVE && list!=DepTree::PRINT) if(list!=DepTree::SAVE && list!=DepTree::PRINT)
{ {
@ -68,16 +68,16 @@ int DepTree::CreateNodeFromSP(DepTree::NodeType list, G_toType::size_type ind, U
if(type==DepTree::SAVE) G_tosave[index]->UsedIdents(ids); if(type==DepTree::SAVE) G_tosave[index]->UsedIdents(ids);
else if(type==DepTree::PRINT) G_toprint[index]->UsedIdents(ids); else if(type==DepTree::PRINT) G_toprint[index]->UsedIdents(ids);
DepTree* d; DepTreeVars::const_iterator d;
int ret; int ret;
for(auto& i:ids) for(auto& i:ids)
{ {
d=FindNodeByVar(i); d=vars.find(i);
if(d==0) if(d==vars.end())
{ {
auto n=*childrens.insert(new DepTree).first; auto n=*childrens.insert(new DepTree).first;
n->parents.insert(this); n->parents.insert(this);
ret=n->CreateNodeFromVar(i,used,callstack); ret=n->CreateNodeFromVar(i,vars,callstack);
if(ret!=0) if(ret!=0)
{ {
COUT(ERROR)<<" in "<<((type==DepTree::SAVE)?"save":"print")<<" directive "<<((type==DepTree::SAVE)?G_tosave:G_toprint)[index]->Dump()<<"."<<std::endl; COUT(ERROR)<<" in "<<((type==DepTree::SAVE)?"save":"print")<<" directive "<<((type==DepTree::SAVE)?G_tosave:G_toprint)[index]->Dump()<<"."<<std::endl;
@ -86,8 +86,8 @@ int DepTree::CreateNodeFromSP(DepTree::NodeType list, G_toType::size_type ind, U
} }
else else
{ {
childrens.insert(d); childrens.insert(d->second);
d->parents.insert(this); d->second->parents.insert(this);
} }
} }
@ -103,48 +103,30 @@ int DepTree::CreateGlobalTree(UsedType& used)
return 2; return 2;
} }
DepTreeVars vars;
type=DepTree::ROOT; type=DepTree::ROOT;
for(G_toType::size_type i=0; i<G_tosave.size(); i++) for(G_toType::size_type i=0; i<G_tosave.size(); i++)
{ {
auto n=*childrens.insert(new DepTree).first; auto n=*childrens.insert(new DepTree).first;
n->parents.insert(this); n->parents.insert(this);
auto ret=n->CreateNodeFromSP(DepTree::SAVE,i,used); auto ret=n->CreateNodeFromSP(DepTree::SAVE,i,vars);
if(ret!=0) return ret; if(ret!=0) return ret;
} }
for(G_toType::size_type i=0; i<G_toprint.size(); i++) for(G_toType::size_type i=0; i<G_toprint.size(); i++)
{ {
auto n=*childrens.insert(new DepTree).first; auto n=*childrens.insert(new DepTree).first;
n->parents.insert(this); n->parents.insert(this);
auto ret=n->CreateNodeFromSP(DepTree::PRINT,i,used); auto ret=n->CreateNodeFromSP(DepTree::PRINT,i,vars);
if(ret!=0) return ret; if(ret!=0) return ret;
} }
return 0; for(auto& i: vars) used.insert(i.first);
}
DepTree* DepTree::FindNodeByVarFromCurrent(const std::string& var) const
{
if(type==DepTree::VAR && name==var) return const_cast<DepTree*>(this);
DepTree* d;
for(auto& i:childrens)
{
d=i->FindNodeByVarFromCurrent(var);
if(d!=0) return d;
}
return 0; return 0;
} }
DepTree* DepTree::FindNodeByVar(const std::string& var) const
{
const DepTree* curnode=this;
while(curnode->parents.size()!=0) curnode=*(curnode->parents.begin());
return curnode->FindNodeByVarFromCurrent(var);
}
DepTree::LeafVector DepTree::FindLeafNodes() const DepTree::LeafVector DepTree::FindLeafNodes() const
{ {
LeafVector leafs; LeafVector leafs;

7
src/deptree.h

@ -10,6 +10,7 @@
class DepTree class DepTree
{ {
typedef std::vector<DepTree*> LeafVector; typedef std::vector<DepTree*> LeafVector;
typedef std::map<std::string,DepTree*> DepTreeVars;
enum NodeType {NOTDEF,ROOT,SAVE,PRINT,VAR}; enum NodeType {NOTDEF,ROOT,SAVE,PRINT,VAR};
typedef std::set<DepTree*> NodeVector; typedef std::set<DepTree*> NodeVector;
@ -21,10 +22,8 @@ class DepTree
std::string name; std::string name;
mutable bool visited; mutable bool visited;
int CreateNodeFromVar(const std::string& var, UsedType& used, CallStack& callstack); int CreateNodeFromVar(const std::string& var, DepTreeVars& vars, CallStack& callstack);
int CreateNodeFromSP(NodeType list, G_toType::size_type ind, UsedType& used); int CreateNodeFromSP(NodeType list, G_toType::size_type ind, DepTreeVars& vars);
DepTree* FindNodeByVarFromCurrent(const std::string& var) const;
DepTree* FindNodeByVar(const std::string& var) const;
LeafVector FindLeafNodes() const; LeafVector FindLeafNodes() const;
public: public:
DepTree():type(DepTree::NOTDEF),visited(false) {} DepTree():type(DepTree::NOTDEF),visited(false) {}

Loading…
Cancel
Save