Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
6.0 KiB

  1. //===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines the DominanceFrontier class, which calculate and holds the
  11. // dominance frontier for a function.
  12. //
  13. // This should be considered deprecated, don't add any more uses of this data
  14. // structure.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_H
  18. #define LLVM_ANALYSIS_DOMINANCEFRONTIER_H
  19. #include "llvm/Analysis/Dominators.h"
  20. #include <map>
  21. #include <set>
  22. namespace llvm {
  23. //===----------------------------------------------------------------------===//
  24. /// DominanceFrontierBase - Common base class for computing forward and inverse
  25. /// dominance frontiers for a function.
  26. ///
  27. class DominanceFrontierBase : public FunctionPass {
  28. public:
  29. typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb
  30. typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
  31. protected:
  32. DomSetMapType Frontiers;
  33. std::vector<BasicBlock*> Roots;
  34. const bool IsPostDominators;
  35. public:
  36. DominanceFrontierBase(char &ID, bool isPostDom)
  37. : FunctionPass(ID), IsPostDominators(isPostDom) {}
  38. /// getRoots - Return the root blocks of the current CFG. This may include
  39. /// multiple blocks if we are computing post dominators. For forward
  40. /// dominators, this will always be a single block (the entry node).
  41. ///
  42. inline const std::vector<BasicBlock*> &getRoots() const { return Roots; }
  43. /// isPostDominator - Returns true if analysis based of postdoms
  44. ///
  45. bool isPostDominator() const { return IsPostDominators; }
  46. virtual void releaseMemory() { Frontiers.clear(); }
  47. // Accessor interface:
  48. typedef DomSetMapType::iterator iterator;
  49. typedef DomSetMapType::const_iterator const_iterator;
  50. iterator begin() { return Frontiers.begin(); }
  51. const_iterator begin() const { return Frontiers.begin(); }
  52. iterator end() { return Frontiers.end(); }
  53. const_iterator end() const { return Frontiers.end(); }
  54. iterator find(BasicBlock *B) { return Frontiers.find(B); }
  55. const_iterator find(BasicBlock *B) const { return Frontiers.find(B); }
  56. iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
  57. assert(find(BB) == end() && "Block already in DominanceFrontier!");
  58. return Frontiers.insert(std::make_pair(BB, frontier)).first;
  59. }
  60. /// removeBlock - Remove basic block BB's frontier.
  61. void removeBlock(BasicBlock *BB) {
  62. assert(find(BB) != end() && "Block is not in DominanceFrontier!");
  63. for (iterator I = begin(), E = end(); I != E; ++I)
  64. I->second.erase(BB);
  65. Frontiers.erase(BB);
  66. }
  67. void addToFrontier(iterator I, BasicBlock *Node) {
  68. assert(I != end() && "BB is not in DominanceFrontier!");
  69. I->second.insert(Node);
  70. }
  71. void removeFromFrontier(iterator I, BasicBlock *Node) {
  72. assert(I != end() && "BB is not in DominanceFrontier!");
  73. assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
  74. I->second.erase(Node);
  75. }
  76. /// compareDomSet - Return false if two domsets match. Otherwise
  77. /// return true;
  78. bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
  79. std::set<BasicBlock *> tmpSet;
  80. for (DomSetType::const_iterator I = DS2.begin(),
  81. E = DS2.end(); I != E; ++I)
  82. tmpSet.insert(*I);
  83. for (DomSetType::const_iterator I = DS1.begin(),
  84. E = DS1.end(); I != E; ) {
  85. BasicBlock *Node = *I++;
  86. if (tmpSet.erase(Node) == 0)
  87. // Node is in DS1 but not in DS2.
  88. return true;
  89. }
  90. if (!tmpSet.empty())
  91. // There are nodes that are in DS2 but not in DS1.
  92. return true;
  93. // DS1 and DS2 matches.
  94. return false;
  95. }
  96. /// compare - Return true if the other dominance frontier base matches
  97. /// this dominance frontier base. Otherwise return false.
  98. bool compare(DominanceFrontierBase &Other) const {
  99. DomSetMapType tmpFrontiers;
  100. for (DomSetMapType::const_iterator I = Other.begin(),
  101. E = Other.end(); I != E; ++I)
  102. tmpFrontiers.insert(std::make_pair(I->first, I->second));
  103. for (DomSetMapType::iterator I = tmpFrontiers.begin(),
  104. E = tmpFrontiers.end(); I != E; ) {
  105. BasicBlock *Node = I->first;
  106. const_iterator DFI = find(Node);
  107. if (DFI == end())
  108. return true;
  109. if (compareDomSet(I->second, DFI->second))
  110. return true;
  111. ++I;
  112. tmpFrontiers.erase(Node);
  113. }
  114. if (!tmpFrontiers.empty())
  115. return true;
  116. return false;
  117. }
  118. /// print - Convert to human readable form
  119. ///
  120. virtual void print(raw_ostream &OS, const Module* = 0) const;
  121. /// dump - Dump the dominance frontier to dbgs().
  122. void dump() const;
  123. };
  124. //===-------------------------------------
  125. /// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
  126. /// used to compute a forward dominator frontiers.
  127. ///
  128. class DominanceFrontier : public DominanceFrontierBase {
  129. virtual void anchor();
  130. public:
  131. static char ID; // Pass ID, replacement for typeid
  132. DominanceFrontier() :
  133. DominanceFrontierBase(ID, false) {
  134. initializeDominanceFrontierPass(*PassRegistry::getPassRegistry());
  135. }
  136. BasicBlock *getRoot() const {
  137. assert(Roots.size() == 1 && "Should always have entry node!");
  138. return Roots[0];
  139. }
  140. virtual bool runOnFunction(Function &) {
  141. Frontiers.clear();
  142. DominatorTree &DT = getAnalysis<DominatorTree>();
  143. Roots = DT.getRoots();
  144. assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
  145. calculate(DT, DT[Roots[0]]);
  146. return false;
  147. }
  148. virtual void getAnalysisUsage(AnalysisUsage &AU) const {
  149. AU.setPreservesAll();
  150. AU.addRequired<DominatorTree>();
  151. }
  152. const DomSetType &calculate(const DominatorTree &DT,
  153. const DomTreeNode *Node);
  154. };
  155. } // End llvm namespace
  156. #endif