void ControlDependenceGraphBase::computeDependencies(Function &F, PostDominatorTree &pdt) { root = new ControlDependenceNode(); nodes.insert(root); for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { ControlDependenceNode *bn = new ControlDependenceNode(BB); nodes.insert(bn); bbMap[BB] = bn; } for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { BasicBlock *A = BB; ControlDependenceNode *AN = bbMap[A]; for (succ_iterator succ = succ_begin(A), end = succ_end(A); succ != end; ++succ) { BasicBlock *B = *succ; assert(A && B); if (A == B || !pdt.dominates(B,A)) { BasicBlock *L = pdt.findNearestCommonDominator(A,B); ControlDependenceNode::EdgeType type = ControlDependenceGraphBase::getEdgeType(A,B); if (A == L) { switch (type) { case ControlDependenceNode::TRUE: AN->addTrue(AN); break; case ControlDependenceNode::FALSE: AN->addFalse(AN); break; case ControlDependenceNode::OTHER: AN->addOther(AN); break; } AN->addParent(AN); } for (DomTreeNode *cur = pdt[B]; cur && cur != pdt[L]; cur = cur->getIDom()) { ControlDependenceNode *CN = bbMap[cur->getBlock()]; switch (type) { case ControlDependenceNode::TRUE: AN->addTrue(CN); break; case ControlDependenceNode::FALSE: AN->addFalse(CN); break; case ControlDependenceNode::OTHER: AN->addOther(CN); break; } assert(CN); CN->addParent(AN); } } } } // ENTRY -> START for (DomTreeNode *cur = pdt[&F.getEntryBlock()]; cur; cur = cur->getIDom()) { if (cur->getBlock()) { ControlDependenceNode *CN = bbMap[cur->getBlock()]; assert(CN); root->addOther(CN); CN->addParent(root); } } }
//Flooding until reach a posdominator node void bSSA::findIR (BasicBlock *bBOring, BasicBlock *bBSuss, PostDominatorTree &PD) { Pred *p; TerminatorInst *ti = bBSuss->getTerminator(); //If the basic block has been processed, do not advance for (unsigned int x=0; x<ProcessedBB.size(); x++) { if (ProcessedBB[x] == bBSuss) { return; } } //Including the basic block in the processed vector ProcessedBB.push_back(bBSuss); //If the basic block is a posdominator and is not the start basic block, just gate the PHI instructions if (PD.dominates(bBSuss, bBOring) && bBSuss != bBOring) { //Find PHI instructions for (BasicBlock::iterator bBIt = bBSuss->begin(), bBEnd = bBSuss->end(); bBIt != bBEnd; ++bBIt) { if (dyn_cast<Instruction>(bBIt)->getOpcode()==Instruction::PHI) { //if there is a PHI's argument gated, gate the PHI instruction p = predicatesVector.back(); for (unsigned int k=0; k<dyn_cast<Instruction>(bBIt)->getNumOperands(); k++) { if (p->isGated(dyn_cast<Instruction>(dyn_cast<Instruction>(bBIt)->getOperand(k)))) { p->addInst(bBIt); break; } } } } return; }else { //Advance the flooding //Instruction will be gated whit the bBOring predicate for (BasicBlock::iterator bBIt = bBSuss->begin(), bBEnd = bBSuss->end(); bBIt != bBEnd; ++bBIt) { p = predicatesVector.back(); //If is a function call which is defined on the same module if (CallInst *CI = dyn_cast<CallInst>(&(*bBIt))) { Function *F = CI->getCalledFunction(); if (F != NULL) if (!F->isDeclaration() && !F->isIntrinsic()) { gateFunction (F, p); } } //Gate the other instructions p->addInst(bBIt); } //If there is successor, go there for (unsigned int i=0; i<ti->getNumSuccessors(); i++) { findIR (bBOring, ti->getSuccessor(i), PD); } } }
void DSWP::checkControlDependence(BasicBlock *a, BasicBlock *b, PostDominatorTree &pdt) { BasicBlock *lca = pdt.findNearestCommonDominator(a, b); cout << a->getNameStr() << " " << b->getNameStr() << " " << lca->getNameStr() << endl; if (lca == pre[a]) { //case 1 BasicBlock *BB = b; while (BB != lca) { addControlDependence(a, BB); BB = pre[BB]; } } else if (lca == a) { //case 2: capture loop dependence BasicBlock *BB = b; while (BB != pre[a]) { cout << "\t" << a->getNameStr() << " " << BB->getNameStr() << endl; addControlDependence(a, BB); BB = pre[BB]; } } else { error("unknow case in checkControlDependence!"); } }
void hammock::findIR (BasicBlock *bBOring, BasicBlock *bBSuss, PostDominatorTree &PD) { TerminatorInst *ti = bBSuss->getTerminator(); if (bBlocks.count(bBSuss)>0) { return; } //Mark BasicBlock bBlocks.insert(bBSuss); //If the basic block is a posdominator and is not the start basic block, just return if (PD.dominates(bBSuss, bBOring) && bBSuss != bBOring) { return; }else { //Advance the flooding //If there is successor, go there for (unsigned int i=0; i<ti->getNumSuccessors(); i++) { findIR (bBOring, ti->getSuccessor(i), PD); } } }
PostDominatorTree PostDominatorTreeAnalysis::run(Function &F, FunctionAnalysisManager &) { PostDominatorTree PDT; PDT.recalculate(F); return PDT; }
void LLVMDependenceGraph::computePostDominators(bool addPostDomFrontiers) { using namespace llvm; // iterate over all functions for (auto& F : getConstructedFunctions()) { analysis::PostDominanceFrontiers<LLVMNode> pdfrontiers; // root of post-dominator tree LLVMBBlock *root = nullptr; Value *val = const_cast<Value *>(F.first); Function& f = *cast<Function>(val); PostDominatorTree *pdtree; #if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR < 9)) pdtree = new PostDominatorTree(); // compute post-dominator tree for this function pdtree->runOnFunction(f); #else PostDominatorTreeWrapperPass wrapper; wrapper.runOnFunction(f); pdtree = &wrapper.getPostDomTree(); #ifndef NDEBUG wrapper.verifyAnalysis(); #endif #endif // add immediate post-dominator edges auto& our_blocks = F.second->getBlocks(); bool built = false; for (auto& it : our_blocks) { LLVMBBlock *BB = it.second; BasicBlock *B = cast<BasicBlock>(const_cast<Value *>(it.first)); DomTreeNode *N = pdtree->getNode(B); // when function contains infinite loop, we're screwed // and we don't have anything // FIXME: just check for the root, // don't iterate over all blocks, stupid... if (!N) continue; DomTreeNode *idom = N->getIDom(); BasicBlock *idomBB = idom ? idom->getBlock() : nullptr; built = true; if (idomBB) { LLVMBBlock *pb = our_blocks[idomBB]; assert(pb && "Do not have constructed BB"); BB->setIPostDom(pb); assert(cast<BasicBlock>(BB->getKey())->getParent() == cast<BasicBlock>(pb->getKey())->getParent() && "BBs are from diferent functions"); // if we do not have idomBB, then the idomBB is a root BB } else { // PostDominatorTree may has special root without BB set // or it is the node without immediate post-dominator if (!root) { root = new LLVMBBlock(); root->setKey(nullptr); F.second->setPostDominatorTreeRoot(root); } BB->setIPostDom(root); } } // well, if we haven't built the pdtree, this is probably infinite loop // that has no pdtree. Until we have anything better, just add sound control // edges that are not so precise - to predecessors. if (!built && addPostDomFrontiers) { for (auto& it : our_blocks) { LLVMBBlock *BB = it.second; for (const LLVMBBlock::BBlockEdge& succ : BB->successors()) { // in this case we add only the control dependencies, // since we have no pd frontiers BB->addControlDependence(succ.target); } } } if (addPostDomFrontiers) { // assert(root && "BUG: must have root"); if (root) pdfrontiers.compute(root, true /* store also control depend. */); } #if ((LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR < 9)) delete pdtree; #endif } }