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

fixed domgraph to deal with nop blocks better

Former-commit-id: 5e9ce8e9ca6bfe79f98704ba353bdda9d609b2e2
parent 96273d18
No related branches found
No related tags found
No related merge requests found
......@@ -3,8 +3,8 @@ namespace libIRDB
{
using namespace std;
using DominatorMap_t = map<const IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlockSet_t>;
using BlockToBlockMap_t = map<const IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlock_t*>;
using DominatorMap_t = map<IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlockSet_t>;
using BlockToBlockMap_t = map<IRDB_SDK::BasicBlock_t*, IRDB_SDK::BasicBlock_t*>;
......@@ -18,27 +18,38 @@ namespace libIRDB
// get the (post) dominators for a node
IRDB_SDK::BasicBlockSet_t& GetDominators(const IRDB_SDK::BasicBlock_t* node) { return dom_graph[node]; }
IRDB_SDK::BasicBlockSet_t& GetPostDominators(const IRDB_SDK::BasicBlock_t* node) { return post_dom_graph[node]; }
IRDB_SDK::BasicBlockSet_t& GetDominators(IRDB_SDK::BasicBlock_t* node) { return dom_graph[node]; }
IRDB_SDK::BasicBlockSet_t& GetPostDominators(IRDB_SDK::BasicBlock_t* node) { return post_dom_graph[node]; }
const IRDB_SDK::BasicBlockSet_t& getDominators(const IRDB_SDK::BasicBlock_t* node) const { return dom_graph.at(node); }
const IRDB_SDK::BasicBlockSet_t& getPostDominators(const IRDB_SDK::BasicBlock_t* node) const { return post_dom_graph.at(node); }
const IRDB_SDK::BasicBlockSet_t& getDominators(const IRDB_SDK::BasicBlock_t* node) const { return dom_graph.at(const_cast<IRDB_SDK::BasicBlock_t*>(node)); }
const IRDB_SDK::BasicBlockSet_t& getDominated (const IRDB_SDK::BasicBlock_t* node) const { return dominated_graph.at(const_cast<IRDB_SDK::BasicBlock_t*>(node)); }
// const IRDB_SDK::BasicBlockSet_t& getPostDominators(const IRDB_SDK::BasicBlock_t* node) const { assert(0); }
// const IRDB_SDK::BasicBlockSet_t& getPostDominated (const IRDB_SDK::BasicBlock_t* node) const { assert(0); }
bool hasWarnings() const { return warn; }
// get the immeidate (post) dominators for a node
const IRDB_SDK::BasicBlock_t* getImmediateDominator(const IRDB_SDK::BasicBlock_t* node) const
{ auto it=idom_graph.find(node); return (it!=idom_graph.end()) ? it->second : NULL; }
const IRDB_SDK::BasicBlock_t* getImmediatePostDominators(const IRDB_SDK::BasicBlock_t* node) const
{ auto it=post_idom_graph.find(node); return (it!=post_idom_graph.end()) ? it->second : NULL; }
const IRDB_SDK::BasicBlock_t* getImmediateDominator (const IRDB_SDK::BasicBlock_t* node) const
{
auto it=idom_graph.find(const_cast<IRDB_SDK::BasicBlock_t*>(node));
return (it!=idom_graph.end()) ? it->second : nullptr;
}
const IRDB_SDK::BasicBlockSet_t& getImmediateDominated (const IRDB_SDK::BasicBlock_t* node) const
{
const static IRDB_SDK::BasicBlockSet_t empty;
auto it=idominated_graph.find(const_cast<IRDB_SDK::BasicBlock_t*>(node));
return (it!=idominated_graph.end()) ? it->second : empty; }
// const IRDB_SDK::BasicBlock_t* getImmediatePostDominator(const IRDB_SDK::BasicBlock_t* node) const { assert(0); }
// const IRDB_SDK::BasicBlockSet_t& getImmediatePostDominated(const IRDB_SDK::BasicBlock_t* node) const { assert(0); }
void dump(ostream& os=cout) const;
private:
void Dominated_Compute();
typedef const IRDB_SDK::BasicBlockSet_t& (*pred_func_ptr_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);
BlockToBlockMap_t Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N, const DominatorMap_t &Domin, IRDB_SDK::BasicBlock_t* r);
......@@ -47,6 +58,9 @@ namespace libIRDB
DominatorMap_t dom_graph;
BlockToBlockMap_t idom_graph;
DominatorMap_t dominated_graph;
DominatorMap_t idominated_graph;
DominatorMap_t post_dom_graph;
BlockToBlockMap_t post_idom_graph;
......
......@@ -167,7 +167,7 @@ void BasicBlock_t::BuildBlock
assert(insn);
const auto icfs = insn->getIBTargets();
const auto d = DecodedInstruction_t::factory(insn);
const auto include_icfs = (d->isReturn() || d->isCall() ) ;
const auto include_icfs = !(d->isReturn() || d->isCall() ) ;
if(icfs != nullptr && include_icfs)
......
......@@ -44,20 +44,22 @@ 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)
: cfg(*p_cfg), warn(false)
{
auto &blocks=p_cfg->getBlocks();
assert(needs_postdoms==false);
assert(needs_idoms==false);
// typedef const BasicBlockSet_t& (*) (const BasicBlock_t* node) pred_func_ptr_t;
pred_func_ptr_t func_get_predecessors=[](const IRDB_SDK::BasicBlock_t* node) -> const IRDB_SDK::BasicBlockSet_t&
{
return node->getPredecessors();
};
dom_graph=Dom_Comp(p_cfg->getBlocks(), func_get_predecessors, p_cfg->getEntry());
idom_graph=Idom_Comp(p_cfg->getBlocks(), dom_graph, p_cfg->getEntry());
dom_graph=Dom_Comp(blocks, func_get_predecessors, p_cfg->getEntry());
idom_graph=Idom_Comp(blocks, dom_graph, p_cfg->getEntry());
Dominated_Compute();
// a func may have multiple exit nodes. how do we deal with that?
// psuedo-block? invoke this for each exit block?
......@@ -300,6 +302,7 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N
};
};
//for each n \in N-{r} do
for (auto n : NminusR)
{
......@@ -312,6 +315,26 @@ BlockToBlockMap_t DominatorGraph_t::Idom_Comp(const IRDB_SDK::BasicBlockSet_t& N
} // IDom_Comp
void DominatorGraph_t::Dominated_Compute()
{
for(auto p : dom_graph)
{
auto dominates = p.first;
auto dominated_set = p.second;
for(auto dominated : dominated_set)
dominated_graph[dominated].insert(dominates);
}
for(auto p : idom_graph)
{
auto dominates = p.first;
auto dominated = p.second;
idominated_graph[dominated].insert(dominates);
}
}
ostream& IRDB_SDK::operator<<(ostream& os, const DominatorGraph_t& dg)
......@@ -322,28 +345,43 @@ ostream& IRDB_SDK::operator<<(ostream& os, const DominatorGraph_t& dg)
void DominatorGraph_t::dump(ostream& os) const
{
// for_each(dg.cfg.GetBlocks().begin(), dg.cfg.GetBlocks().end(), [&](const BasicBlock_t* blk)
for(auto blk : cfg.getBlocks())
{
assert(blk);
const auto& blk_dominates=getDominators(blk);
const auto& blk_dominators=getDominators(blk);
auto first_insn=*(blk->getInstructions().begin());
assert(first_insn);
os<<"\tBlock entry id:" <<blk->getInstructions()[0]->getBaseID()<<endl;
os<<"\t\tDominated by: ";
for(auto dom : blk_dominates)
os<<"\tBlock entry id:" <<dec<<blk->getInstructions()[0]->getBaseID()<<endl;
os<<"\t\tBlocks that (eventually) dominate me: ";
for(auto blk : blk_dominators)
{
os<<dom->getInstructions()[0]->getBaseID()<<", ";
os<<blk->getInstructions()[0]->getBaseID()<<", ";
};
os<<endl;
const IRDB_SDK::BasicBlock_t* idom=getImmediateDominator(blk);
if(idom)
os<<"\t\tImmediate Dominator: "<<hex<<idom->getInstructions()[0]->getBaseID()<<endl;
os<<"\t\tMy Immediate Dominator: "<<dec<<idom->getInstructions()[0]->getBaseID()<<endl;
else
os<<"\t\tNo Immed Dominator."<<endl;
os<<"\t\tBlocks I (eventually) Dominate: ";
const auto& dominated_blocks=getDominated(blk);
for(auto blk : dominated_blocks)
{
os<<blk->getInstructions()[0]->getBaseID()<<", ";
};
os<<endl;
os<<"\t\tBlocks I Immediately Dominate: ";
const auto& imm_dominated_blocks=getImmediateDominated(blk);
for(auto blk : imm_dominated_blocks)
{
os<<blk->getInstructions()[0]->getBaseID()<<", ";
};
os<<endl;
};
}
......@@ -356,3 +394,7 @@ IRDB_SDK::DominatorGraph_t::factory(const ControlFlowGraph_t* p_cfg, const bool
return unique_ptr<IRDB_SDK::DominatorGraph_t>(new libIRDB::DominatorGraph_t(real_cfg, needs_postdoms, needs_idoms));
}
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