Skip to content
Snippets Groups Projects
Commit 0896dd5c authored by Jason Hiser's avatar Jason Hiser :tractor:
Browse files

added DFS api, used it to speed up dominator calculations

parent 3b3d3ded
No related branches found
No related tags found
No related merge requests found
Pipeline #4131 passed
...@@ -51,8 +51,8 @@ namespace libIRDB ...@@ -51,8 +51,8 @@ namespace libIRDB
using pred_func_ptr_t = const IRDB_SDK::BasicBlockSet_t& (*) (const IRDB_SDK::BasicBlock_t* node); using pred_func_ptr_t = const IRDB_SDK::BasicBlockSet_t& (*) (const IRDB_SDK::BasicBlock_t* node);
DominatorMap_t Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pred_func_ptr_t pred_func, IRDB_SDK::BasicBlock_t* r); DominatorMap_t Dom_Comp(const IRDB_SDK::BasicBlockVector_t& N, pred_func_ptr_t pred_func, IRDB_SDK::BasicBlock_t* r);
BlockToBlockMap_t Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r); BlockToBlockMap_t Idom_Comp(const IRDB_SDK::BasicBlockVector_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r);
DominatorMap_t dom_graph; DominatorMap_t dom_graph;
......
...@@ -8,7 +8,7 @@ myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME']) ...@@ -8,7 +8,7 @@ myenv.Replace(SECURITY_TRANSFORMS_HOME=os.environ['SECURITY_TRANSFORMS_HOME'])
libname="irdb-cfg" libname="irdb-cfg"
files= ''' files= '''
BasicBlock.cpp callgraph.cpp CFG.cpp domgraph.cpp criticaledge.cpp BasicBlock.cpp callgraph.cpp CFG.cpp domgraph.cpp criticaledge.cpp dfs.cpp
''' '''
cpppath=''' cpppath='''
$IRDB_SDK/include/ $IRDB_SDK/include/
......
#include <irdb-core>
#include <irdb-cfg>
#include <vector>
using namespace IRDB_SDK;
using VisitedMap_t = map<BasicBlock_t*,bool> ;
static void doDFS(BasicBlockVector_t &order, VisitedMap_t &visited, BasicBlock_t* node)
{
// visit this node
visited[node]=true;
order.push_back(node);
// visit each successor
for(auto successor : node->getSuccessors())
{
if(!visited[successor])
doDFS(order,visited,successor);
}
}
BasicBlockVector_t IRDB_SDK::getDFSOrder(ControlFlowGraph_t* cfg)
{
assert(cfg!=nullptr);
auto ret = BasicBlockVector_t();
ret.reserve(cfg->getBlocks().size());
auto visited = VisitedMap_t();
// explicitly fill the map with falses.
for(auto& node : cfg->getBlocks())
visited[node]=false;
doDFS(ret,visited,cfg->getEntry());
// for each node in the map
for(auto &p : visited)
// if it's not visited
if(p.second == false)
// that means it appeared unreachable from the entry block
// add it to the dfs end.
ret.push_back(p.first);
return move(ret);
}
...@@ -44,20 +44,18 @@ inline S const& find_map_object( const std::map< T , S > &a_map, const T& key) ...@@ -44,20 +44,18 @@ inline S const& find_map_object( const std::map< T , S > &a_map, const T& key)
DominatorGraph_t::DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms, bool needs_idoms) DominatorGraph_t::DominatorGraph_t(const ControlFlowGraph_t* p_cfg, bool needs_postdoms, bool needs_idoms)
: cfg(*p_cfg), warn(false) : cfg(*p_cfg), warn(false)
{ {
auto &blocks=p_cfg->getBlocks();
assert(needs_postdoms==false); assert(needs_postdoms==false);
assert(needs_idoms==false); assert(needs_idoms==false);
const auto dfs_order = getDFSOrder(const_cast<ControlFlowGraph_t*>(p_cfg));
pred_func_ptr_t func_get_predecessors=[](const IRDB_SDK::BasicBlock_t* node) -> const IRDB_SDK::BasicBlockSet_t& pred_func_ptr_t func_get_predecessors=[](const IRDB_SDK::BasicBlock_t* node) -> const IRDB_SDK::BasicBlockSet_t&
{ {
return node->getPredecessors(); return node->getPredecessors();
}; };
dom_graph=Dom_Comp(blocks, func_get_predecessors, p_cfg->getEntry()); dom_graph = Dom_Comp(dfs_order, func_get_predecessors, p_cfg->getEntry());
idom_graph=Idom_Comp(blocks, dom_graph, p_cfg->getEntry()); idom_graph = Idom_Comp(dfs_order, dom_graph, p_cfg->getEntry());
Dominated_Compute(); Dominated_Compute();
...@@ -111,7 +109,7 @@ end || Dom_Comp ...@@ -111,7 +109,7 @@ end || Dom_Comp
*/ */
DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pred_func_ptr_t get_preds, IRDB_SDK::BasicBlock_t* r) DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockVector_t& N, pred_func_ptr_t get_preds, IRDB_SDK::BasicBlock_t* r)
{ {
/* /*
D, T: set of Node D, T: set of Node
...@@ -125,17 +123,15 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pr ...@@ -125,17 +123,15 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pr
DominatorMap_t Domin; DominatorMap_t Domin;
Domin[r].insert(r); Domin[r].insert(r);
IRDB_SDK::BasicBlockSet_t NminusR=N;
NminusR.erase(r);
/* /*
for each n \in N - {r} do for each n \in N - {r} do
Domin(n)={N} Domin(n)={N}
od od
*/ */
for( auto n : NminusR) for( const auto &n : N)
{ {
Domin[n]=N; if(n==r) continue;
Domin[n]=IRDB_SDK::BasicBlockSet_t(ALLOF(N));
}; };
/* /*
...@@ -147,17 +143,18 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pr ...@@ -147,17 +143,18 @@ DominatorMap_t DominatorGraph_t::Dom_Comp(const IRDB_SDK::BasicBlockSet_t& N, pr
/* /*
for each n \in N - {r} do for each n \in N - {r} do
*/ */
for( auto n : NminusR) for( const auto &n : N)
{ {
if(n == r) continue;
/* T := N */ /* T := N */
T=N; T = IRDB_SDK::BasicBlockSet_t(ALLOF(N));
/* /*
for each p \in Pred(n) do for each p \in Pred(n) do
T = T intersect Domin(p) T = T intersect Domin(p)
done done
*/ */
for(auto p : get_preds(n) ) for(const auto &p : get_preds(n) )
{ {
IRDB_SDK::BasicBlockSet_t tmp; IRDB_SDK::BasicBlockSet_t tmp;
set_intersection(T.begin(), T.end(), Domin[p].begin(), Domin[p].end(), inserter(tmp,tmp.begin())); set_intersection(T.begin(), T.end(), Domin[p].begin(), Domin[p].end(), inserter(tmp,tmp.begin()));
...@@ -248,21 +245,20 @@ end || IDom_Comp ...@@ -248,21 +245,20 @@ end || IDom_Comp
BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r) BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockVector_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r)
{ {
// n, s, t: Node // n, s, t: Node
//BasicBlock_t* n=NULL, *s=NULL, *t=NULL; const auto verbose=false;
// Tmp: Node -> set of Node // Tmp: Node -> set of Node
DominatorMap_t Tmp; auto Tmp = DominatorMap_t();
// IDom: Node->Node // IDom: Node->Node
BlockToBlockMap_t IDom; auto IDom = BlockToBlockMap_t() ;
// calculate this set as we use it several times auto tmp_n_total_size = 0u;
IRDB_SDK::BasicBlockSet_t NminusR = N; auto inner_total = 0u;
NminusR.erase(r); auto inner_checks = 0u;
// for each n \in N do // for each n \in N do
...@@ -271,15 +267,22 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N ...@@ -271,15 +267,22 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N
//Tmp(n) := Domin(n) - {n} //Tmp(n) := Domin(n) - {n}
Tmp[n] = Domin.at(n); Tmp[n] = Domin.at(n);
Tmp[n].erase(n); Tmp[n].erase(n);
tmp_n_total_size += Tmp[n].size();
// od // od
}; }
if(verbose)
cout << "Average size of Tmp[n] = " << tmp_n_total_size / Tmp.size() << endl;
//for each n \in N - {r} do //for each n \in N - {r} do
for(auto n : NminusR) for(auto n : N)
{ {
if( n == r) continue;
// for each s \in Tmp(n) do // for each s \in Tmp(n) do
auto Tmp_n=Tmp[n]; auto Tmp_n=Tmp[n];
// for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* s) // for_each( Tmp_n.begin(), Tmp_n.end(), [&]( BasicBlock_t* s)
for (auto s : Tmp_n) for (auto s : Tmp_n)
{ {
...@@ -292,20 +295,29 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N ...@@ -292,20 +295,29 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N
if(t != s) if(t != s)
{ {
//if t \in Tmp(s) then //if t \in Tmp(s) then
inner_checks ++;
if( is_in_container(Tmp[s],t)) if( is_in_container(Tmp[s],t))
{ {
//Tmp(n) -= {t} //Tmp(n) -= {t}
Tmp[n].erase(t); Tmp[n].erase(t);
inner_total ++;
} }
} }
}; };
}; };
}; };
if(verbose)
{
cout << "Inner checks = " << inner_checks << endl;
cout << "Inner total = " << inner_total << endl;
}
//for each n \in N-{r} do //for each n \in N-{r} do
for (auto n : NminusR) for (auto n : N)
{ {
if(n == r) continue;
//IDom(n) = <only element in>Tmp(n) //IDom(n) = <only element in>Tmp(n)
IDom[n]= *(Tmp[n].begin()); IDom[n]= *(Tmp[n].begin());
if(Tmp[n].size()!=1) // should only be one idominator. if(Tmp[n].size()!=1) // should only be one idominator.
......
Subproject commit 3267ac26338c701dffa3267da6c6ca15475b4999 Subproject commit f2ad120cbf9fa7d965288472b67cecb197bb5a12
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment