LLVM API Documentation

DominanceFrontier.h
Go to the documentation of this file.
00001 //===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the DominanceFrontier class, which calculate and holds the
00011 // dominance frontier for a function.
00012 //
00013 // This should be considered deprecated, don't add any more uses of this data
00014 // structure.
00015 //
00016 //===----------------------------------------------------------------------===//
00017 
00018 #ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_H
00019 #define LLVM_ANALYSIS_DOMINANCEFRONTIER_H
00020 
00021 #include "llvm/Analysis/Dominators.h"
00022 #include <map>
00023 #include <set>
00024 
00025 namespace llvm {
00026   
00027 //===----------------------------------------------------------------------===//
00028 /// DominanceFrontierBase - Common base class for computing forward and inverse
00029 /// dominance frontiers for a function.
00030 ///
00031 class DominanceFrontierBase : public FunctionPass {
00032 public:
00033   typedef std::set<BasicBlock*>             DomSetType;    // Dom set for a bb
00034   typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
00035 protected:
00036   DomSetMapType Frontiers;
00037   std::vector<BasicBlock*> Roots;
00038   const bool IsPostDominators;
00039 
00040 public:
00041   DominanceFrontierBase(char &ID, bool isPostDom)
00042     : FunctionPass(ID), IsPostDominators(isPostDom) {}
00043 
00044   /// getRoots - Return the root blocks of the current CFG.  This may include
00045   /// multiple blocks if we are computing post dominators.  For forward
00046   /// dominators, this will always be a single block (the entry node).
00047   ///
00048   inline const std::vector<BasicBlock*> &getRoots() const { return Roots; }
00049 
00050   /// isPostDominator - Returns true if analysis based of postdoms
00051   ///
00052   bool isPostDominator() const { return IsPostDominators; }
00053 
00054   virtual void releaseMemory() { Frontiers.clear(); }
00055 
00056   // Accessor interface:
00057   typedef DomSetMapType::iterator iterator;
00058   typedef DomSetMapType::const_iterator const_iterator;
00059   iterator       begin()       { return Frontiers.begin(); }
00060   const_iterator begin() const { return Frontiers.begin(); }
00061   iterator       end()         { return Frontiers.end(); }
00062   const_iterator end()   const { return Frontiers.end(); }
00063   iterator       find(BasicBlock *B)       { return Frontiers.find(B); }
00064   const_iterator find(BasicBlock *B) const { return Frontiers.find(B); }
00065 
00066   iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
00067     assert(find(BB) == end() && "Block already in DominanceFrontier!");
00068     return Frontiers.insert(std::make_pair(BB, frontier)).first;
00069   }
00070 
00071   /// removeBlock - Remove basic block BB's frontier.
00072   void removeBlock(BasicBlock *BB) {
00073     assert(find(BB) != end() && "Block is not in DominanceFrontier!");
00074     for (iterator I = begin(), E = end(); I != E; ++I)
00075       I->second.erase(BB);
00076     Frontiers.erase(BB);
00077   }
00078 
00079   void addToFrontier(iterator I, BasicBlock *Node) {
00080     assert(I != end() && "BB is not in DominanceFrontier!");
00081     I->second.insert(Node);
00082   }
00083 
00084   void removeFromFrontier(iterator I, BasicBlock *Node) {
00085     assert(I != end() && "BB is not in DominanceFrontier!");
00086     assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
00087     I->second.erase(Node);
00088   }
00089 
00090   /// compareDomSet - Return false if two domsets match. Otherwise
00091   /// return true;
00092   bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
00093     std::set<BasicBlock *> tmpSet;
00094     for (DomSetType::const_iterator I = DS2.begin(),
00095            E = DS2.end(); I != E; ++I)
00096       tmpSet.insert(*I);
00097 
00098     for (DomSetType::const_iterator I = DS1.begin(),
00099            E = DS1.end(); I != E; ) {
00100       BasicBlock *Node = *I++;
00101 
00102       if (tmpSet.erase(Node) == 0)
00103         // Node is in DS1 but not in DS2.
00104         return true;
00105     }
00106 
00107     if (!tmpSet.empty())
00108       // There are nodes that are in DS2 but not in DS1.
00109       return true;
00110 
00111     // DS1 and DS2 matches.
00112     return false;
00113   }
00114 
00115   /// compare - Return true if the other dominance frontier base matches
00116   /// this dominance frontier base. Otherwise return false.
00117   bool compare(DominanceFrontierBase &Other) const {
00118     DomSetMapType tmpFrontiers;
00119     for (DomSetMapType::const_iterator I = Other.begin(),
00120            E = Other.end(); I != E; ++I)
00121       tmpFrontiers.insert(std::make_pair(I->first, I->second));
00122 
00123     for (DomSetMapType::iterator I = tmpFrontiers.begin(),
00124            E = tmpFrontiers.end(); I != E; ) {
00125       BasicBlock *Node = I->first;
00126       const_iterator DFI = find(Node);
00127       if (DFI == end())
00128         return true;
00129 
00130       if (compareDomSet(I->second, DFI->second))
00131         return true;
00132 
00133       ++I;
00134       tmpFrontiers.erase(Node);
00135     }
00136 
00137     if (!tmpFrontiers.empty())
00138       return true;
00139 
00140     return false;
00141   }
00142 
00143   /// print - Convert to human readable form
00144   ///
00145   virtual void print(raw_ostream &OS, const Module* = 0) const;
00146 
00147   /// dump - Dump the dominance frontier to dbgs().
00148   void dump() const;
00149 };
00150 
00151 
00152 //===-------------------------------------
00153 /// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
00154 /// used to compute a forward dominator frontiers.
00155 ///
00156 class DominanceFrontier : public DominanceFrontierBase {
00157   virtual void anchor();
00158 public:
00159   static char ID; // Pass ID, replacement for typeid
00160   DominanceFrontier() :
00161     DominanceFrontierBase(ID, false) {
00162       initializeDominanceFrontierPass(*PassRegistry::getPassRegistry());
00163     }
00164 
00165   BasicBlock *getRoot() const {
00166     assert(Roots.size() == 1 && "Should always have entry node!");
00167     return Roots[0];
00168   }
00169 
00170   virtual bool runOnFunction(Function &) {
00171     Frontiers.clear();
00172     DominatorTree &DT = getAnalysis<DominatorTree>();
00173     Roots = DT.getRoots();
00174     assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
00175     calculate(DT, DT[Roots[0]]);
00176     return false;
00177   }
00178 
00179   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
00180     AU.setPreservesAll();
00181     AU.addRequired<DominatorTree>();
00182   }
00183 
00184   const DomSetType &calculate(const DominatorTree &DT,
00185                               const DomTreeNode *Node);
00186 };
00187 
00188 } // End llvm namespace
00189 
00190 #endif