//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines the DominanceFrontier class, which calculate and holds the // dominance frontier for a function. // // This should be considered deprecated, don't add any more uses of this data // structure. // //===----------------------------------------------------------------------===// #ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_H #define LLVM_ANALYSIS_DOMINANCEFRONTIER_H #include "llvm/Analysis/Dominators.h" #include <map> #include <set> namespace llvm { //===----------------------------------------------------------------------===// /// DominanceFrontierBase - Common base class for computing forward and inverse /// dominance frontiers for a function. /// class DominanceFrontierBase : public FunctionPass { public: typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map protected: DomSetMapType Frontiers; std::vector<BasicBlock*> Roots; const bool IsPostDominators; public: DominanceFrontierBase(char &ID, bool isPostDom) : FunctionPass(ID), IsPostDominators(isPostDom) {} /// getRoots - Return the root blocks of the current CFG. This may include /// multiple blocks if we are computing post dominators. For forward /// dominators, this will always be a single block (the entry node). /// inline const std::vector<BasicBlock*> &getRoots() const { return Roots; } /// isPostDominator - Returns true if analysis based of postdoms /// bool isPostDominator() const { return IsPostDominators; } virtual void releaseMemory() { Frontiers.clear(); } // Accessor interface: typedef DomSetMapType::iterator iterator; typedef DomSetMapType::const_iterator const_iterator; iterator begin() { return Frontiers.begin(); } const_iterator begin() const { return Frontiers.begin(); } iterator end() { return Frontiers.end(); } const_iterator end() const { return Frontiers.end(); } iterator find(BasicBlock *B) { return Frontiers.find(B); } const_iterator find(BasicBlock *B) const { return Frontiers.find(B); } iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) { assert(find(BB) == end() && "Block already in DominanceFrontier!"); return Frontiers.insert(std::make_pair(BB, frontier)).first; } /// removeBlock - Remove basic block BB's frontier. void removeBlock(BasicBlock *BB) { assert(find(BB) != end() && "Block is not in DominanceFrontier!"); for (iterator I = begin(), E = end(); I != E; ++I) I->second.erase(BB); Frontiers.erase(BB); } void addToFrontier(iterator I, BasicBlock *Node) { assert(I != end() && "BB is not in DominanceFrontier!"); I->second.insert(Node); } void removeFromFrontier(iterator I, BasicBlock *Node) { assert(I != end() && "BB is not in DominanceFrontier!"); assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB"); I->second.erase(Node); } /// compareDomSet - Return false if two domsets match. Otherwise /// return true; bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const { std::set<BasicBlock *> tmpSet; for (DomSetType::const_iterator I = DS2.begin(), E = DS2.end(); I != E; ++I) tmpSet.insert(*I); for (DomSetType::const_iterator I = DS1.begin(), E = DS1.end(); I != E; ) { BasicBlock *Node = *I++; if (tmpSet.erase(Node) == 0) // Node is in DS1 but not in DS2. return true; } if (!tmpSet.empty()) // There are nodes that are in DS2 but not in DS1. return true; // DS1 and DS2 matches. return false; } /// compare - Return true if the other dominance frontier base matches /// this dominance frontier base. Otherwise return false. bool compare(DominanceFrontierBase &Other) const { DomSetMapType tmpFrontiers; for (DomSetMapType::const_iterator I = Other.begin(), E = Other.end(); I != E; ++I) tmpFrontiers.insert(std::make_pair(I->first, I->second)); for (DomSetMapType::iterator I = tmpFrontiers.begin(), E = tmpFrontiers.end(); I != E; ) { BasicBlock *Node = I->first; const_iterator DFI = find(Node); if (DFI == end()) return true; if (compareDomSet(I->second, DFI->second)) return true; ++I; tmpFrontiers.erase(Node); } if (!tmpFrontiers.empty()) return true; return false; } /// print - Convert to human readable form /// virtual void print(raw_ostream &OS, const Module* = 0) const; /// dump - Dump the dominance frontier to dbgs(). void dump() const; }; //===------------------------------------- /// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is /// used to compute a forward dominator frontiers. /// class DominanceFrontier : public DominanceFrontierBase { public: static char ID; // Pass ID, replacement for typeid DominanceFrontier() : DominanceFrontierBase(ID, false) { initializeDominanceFrontierPass(*PassRegistry::getPassRegistry()); } BasicBlock *getRoot() const { assert(Roots.size() == 1 && "Should always have entry node!"); return Roots[0]; } virtual bool runOnFunction(Function &) { Frontiers.clear(); DominatorTree &DT = getAnalysis<DominatorTree>(); Roots = DT.getRoots(); assert(Roots.size() == 1 && "Only one entry block for forward domfronts!"); calculate(DT, DT[Roots[0]]); return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired<DominatorTree>(); } const DomSetType &calculate(const DominatorTree &DT, const DomTreeNode *Node); }; } // End llvm namespace #endif