00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef LLVM_ANALYSIS_REGION_INFO_H
00028 #define LLVM_ANALYSIS_REGION_INFO_H
00029
00030 #include "llvm/ADT/PointerUnion.h"
00031 #include "llvm/Analysis/Dominators.h"
00032 #include "llvm/Analysis/PostDominators.h"
00033 #include "llvm/Support/raw_ostream.h"
00034
00035 namespace llvm {
00036
00037 class Region;
00038 class RegionInfo;
00039
00040
00041 template <class GraphType>
00042 struct FlatIt {
00043 const GraphType &Graph;
00044
00045 inline FlatIt(const GraphType &G) : Graph(G) {}
00046 };
00047
00048
00049 template<class> class RNSuccIterator;
00050
00053 class RegionNode {
00054 protected:
00056 Region* parent;
00057
00063 BasicBlock* BB;
00064
00066 PointerUnion<const Region*, BasicBlock*> SubclassData;
00067
00070 inline RegionNode(Region* r, BasicBlock* entry, BasicBlock* exit)
00071 : parent(r), BB(entry), SubclassData(exit) {}
00072
00073 public:
00075 inline RegionNode(Region* r, BasicBlock *bb)
00076 : parent(r), BB(bb), SubclassData(r){}
00077
00078 virtual ~RegionNode() {}
00079
00081 inline Region* getParent() const { return parent; }
00082
00086 inline const Region* getItRegion() const {
00087 assert(!isRegionNode() && "this is not a BB node!");
00088 return SubclassData.get<const Region*>();
00089 }
00090
00091 inline void setItRegion(const Region* R) {
00092 assert(!isRegionNode() && "this is not a BB node!");
00093 SubclassData = R;
00094 }
00095
00098 inline void propItRegionTo(RegionNode *Node) const {
00099 Node->setItRegion(getItRegion());
00100 }
00101
00104 inline BasicBlock* getBB() const { return BB; }
00105
00107 template<class T>
00108 inline T* getNodeAs() const;
00109
00110 inline bool isRegionNode() const {
00111
00112
00113 return SubclassData.is<BasicBlock*>();
00114 }
00115 };
00116
00117
00118
00119
00120
00121 template<>
00122 inline BasicBlock* RegionNode::getNodeAs<BasicBlock>() const {
00123 assert(!isRegionNode() && "this is not a BB node!");
00124 return BB;
00125 }
00126
00127 template<>
00128 inline Region* RegionNode::getNodeAs<Region>() const {
00129 assert(isRegionNode() && "this is not a region node!");
00130 return reinterpret_cast<Region*>(const_cast<RegionNode*>(this));
00131 }
00132
00133
00136 template<class BaseIt>
00137 class RegionSetIt : public std::iterator<std::forward_iterator_tag,
00138 Region, ptrdiff_t>
00139 {
00140 typedef std::iterator<std::forward_iterator_tag, Region, ptrdiff_t> super;
00141
00142 BaseIt I, E;
00143
00144 public:
00145 typedef RegionSetIt _Self;
00146 typedef super::pointer pointer;
00147
00148 inline RegionSetIt(BaseIt& i, BaseIt& e) : I(i), E(e) {
00149 while( I!= E && !I->second->isRegionNode())
00150 ++I;
00151 }
00152
00153 inline RegionSetIt(BaseIt& e) : I(e), E(e) {}
00154
00155 inline bool operator==(const _Self& x) const {
00156 return I == x.I && E == x.E;
00157 }
00158
00159 inline bool operator!=(const _Self& x) const { return !operator==(x); }
00160
00161 inline pointer operator*() const {
00162 assert(I != E && "RegionSetIt not dereferencable!");
00163 assert(I->second->isRegionNode() && "expect a region node!");
00164 return I->second->template getNodeAs<Region>();
00165 }
00166
00167 inline pointer operator->() const {
00168 assert(I != E && "RegionSetIt not dereferencable!");
00169 assert(I->second->isRegionNode() && "expect a region node!");
00170 return I->second->template getNodeAs<Region>();
00171 }
00172
00173 inline _Self& operator++() {
00174 ++I;
00175 while( I!= E && !I->second->isRegionNode())
00176 ++I;
00177
00178 return *this;
00179 }
00180
00181 inline _Self operator++(int) {
00182 _Self tmp = *this;
00183 ++*this;
00184 return tmp;
00185 }
00186
00187 inline const _Self &operator=(const _Self &X) {
00188 if (this != &X) {
00189 assert(E == X.E &&"Cannot assign iterators to two different Regionset!");
00190 E = X.E;
00191 I = X.I;
00192 }
00193 return *this;
00194 }
00195 };
00196
00197
00241
00242
00243
00244
00245
00246
00247 class Region : private RegionNode {
00248 friend class RegionInfo;
00249
00250 RegionInfo* RI;
00251 DominatorTree *DT;
00252 PostDominatorTree *PDT;
00253
00254 typedef std::map<BasicBlock*, RegionNode*> NodeMapT;
00255 typedef std::map<BasicBlock*, RegionNode*>::iterator nodemap_iterator;
00256 std::map<BasicBlock*, RegionNode*> RNodeMap;
00257
00259 RegionNode* getNode() {
00260 return static_cast<RegionNode*>(this);
00261 }
00262
00263 const RegionNode* getNode() const {
00264 return static_cast<const RegionNode* const>(this);
00265 }
00266
00268 bool contains(const Region *other) const {
00269 return DT->dominates(getEntry(), other->getEntry())
00270 && PDT->dominates(getExit(), other->getExit());
00271 }
00272
00273
00276
00279 void verifyBBInRegion(BasicBlock* BB) const;
00280
00283 void verifyWalk(BasicBlock* BB, std::set<BasicBlock*>* visitedBB) const;
00284
00287 void verifyRegionNest() const;
00288
00289 public:
00290 Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RI,
00291 DominatorTree *DT, PostDominatorTree *PDT,
00292 Region *Parent = 0);
00293
00294 ~Region();
00295
00300 bool contains(BasicBlock *BB) const;
00301
00304 BasicBlock *getEntry() const { return BB; }
00305
00308 BasicBlock *getExit() const { return SubclassData.get<BasicBlock*>(); }
00309
00313 using RegionNode::getParent;
00314
00315 std::string getName() const {
00316 return getEntry()->getName().str() + " => " + getExit()->getName().str();
00317 }
00318
00321 typedef RegionSetIt<std::map<BasicBlock*, RegionNode*>::iterator> iterator;
00322 typedef RegionSetIt<std::map<BasicBlock*, RegionNode*>::const_iterator>
00323 const_iterator;
00324
00325 iterator begin() {
00326 std::map<BasicBlock*, RegionNode*>::iterator i = RNodeMap.begin(),
00327 e = RNodeMap.end();
00328 return iterator(i, e);
00329 }
00330
00331 iterator end() {
00332 std::map<BasicBlock*, RegionNode*>::iterator e = RNodeMap.end();
00333 return iterator(e);
00334 }
00335
00336 const_iterator begin() const {
00337 std::map<BasicBlock*, RegionNode*>::const_iterator i = RNodeMap.begin(),
00338 e = RNodeMap.end();
00339 return const_iterator(i, e);
00340 }
00341
00342 const_iterator end() const {
00343 std::map<BasicBlock*, RegionNode*>::const_iterator e = RNodeMap.end();
00344 return const_iterator(e);
00345 }
00346
00348 RegionNode* getChildNode(BasicBlock* BB) const {
00349
00350 NodeMapT::const_iterator at = RNodeMap.find(BB);
00351 return at != RNodeMap.end() ? at->second : 0;
00352 }
00353
00355 RegionNode* getBBNode(BasicBlock* BB) const;
00356
00358 RegionNode* getGraphEntry() const;
00359 RegionNode* getFlatGraphEntry() const;
00360
00363 typedef df_iterator<RegionNode*, SmallPtrSet<RegionNode*, 8>, false,
00364 GraphTraits<FlatIt<RegionNode*> > > block_iterator;
00365
00366 block_iterator block_begin();
00367 block_iterator block_end();
00368
00369 typedef df_iterator<const RegionNode*, SmallPtrSet<const RegionNode*, 8>,
00370 false, GraphTraits<FlatIt<const RegionNode*> > > const_block_iterator;
00371
00372 const_block_iterator block_begin() const;
00373 const_block_iterator block_end() const;
00374
00376 void print(raw_ostream& os, bool printtree = true, unsigned level = 0) const;
00377
00379 void verifyRegion() const;
00380
00388 unsigned getRegionDepth() const;
00389
00393 Region *removeChildRegion(Region *Child);
00394
00397 void addChildRegion(Region *NewChild);
00398
00400 void transferChildrenTo(Region *To);
00401 void transferChildrenTo(RegionInfo *To);
00402
00406 void removeBlock(BasicBlock *BB);
00407
00411 void addBlock(BasicBlock *BB);
00412 };
00413
00414
00415
00417 inline raw_ostream &operator<<(raw_ostream &o, const RegionNode &Node) {
00418 if (Node.isRegionNode())
00419 return o << Node.getNodeAs<Region>()->getName();
00420 else
00421 return o << Node.getNodeAs<BasicBlock>()->getNameStr();
00422 }
00423
00424
00427 class RegionInfo : public FunctionPass {
00428 typedef DenseMap<BasicBlock*,BasicBlock*> BBtoBBMap;
00429 typedef DenseMap<BasicBlock*, Region*> BBtoRegionMap;
00430 typedef SmallPtrSet<Region*, 4> RegionSet;
00431
00432 DominatorTree *DT;
00433 PostDominatorTree *PDT;
00434 DominanceFrontier *DF;
00435
00437 RegionSet topLevelRegions;
00438
00440 BBtoRegionMap BBtoRegion;
00441
00442
00443
00445
00449 bool isCommonDomFrontier(BasicBlock* BB, BasicBlock* entry,
00450 BasicBlock* exit) const;
00451
00454 bool isRegion(BasicBlock* entry, BasicBlock* exit) const;
00455
00458 void insertShortCut(BasicBlock* entry, BasicBlock* exit,
00459 BBtoBBMap* ShortCut) const;
00460
00463 DomTreeNode *getNextPostDom(DomTreeNode* N, BBtoBBMap *ShortCut) const;
00464
00466 bool isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const;
00467
00469 Region *createRegion(BasicBlock *entry, BasicBlock *exit,
00470 BBtoBBMap *ShortCut);
00471
00473 void findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut);
00474
00476 void scanForRegions(Function &F, BBtoBBMap *ShortCut);
00477
00479 Region *getTopMostParent(Region *region);
00480
00482 void buildRegionsTree(DomTreeNode *N, Region *region = 0);
00483
00485 void Calculate(Function& F);
00486
00487 void releaseMemory();
00488
00490 void updateStatistics(Region *R);
00491
00494 bool isSimple(Region* R) const;
00495
00496 public:
00497 static char ID;
00498 explicit RegionInfo();
00499
00500 ~RegionInfo();
00501
00502 virtual bool runOnFunction(Function &F);
00503 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
00504 virtual void print(raw_ostream &OS, const Module *) const;
00505 virtual void verifyAnalysis() const;
00506
00508 typedef RegionSet::iterator iterator;
00510 typedef RegionSet::const_iterator const_iterator;
00511
00512 iterator begin() { return topLevelRegions.begin(); }
00513 iterator end() { return topLevelRegions.end(); }
00514 const_iterator begin() const { return topLevelRegions.begin(); }
00515 const_iterator end() const { return topLevelRegions.end(); }
00516
00522 Region *getRegionFor(const BasicBlock *BB) const;
00523
00529 Region *operator[](const BasicBlock *BB) const;
00530
00536 const Region*
00537 findSmallestCommonRegion(const Region* A, const Region *B) const;
00538
00544 const Region* findSmallestCommonRegion(const BasicBlock* A,
00545 const BasicBlock *B) const {
00546 return findSmallestCommonRegion(getRegionFor(A), getRegionFor(B));
00547 }
00548
00553 const Region*
00554 findSmallestCommonRegion(SmallVectorImpl<Region*> &Regions) const;
00555
00560 const Region*
00561 findSmallestCommonRegion(SmallVectorImpl<BasicBlock*> &BBs) const;
00562
00569 void removeRegion(Region *R);
00570
00574 void changeRegionFor(BasicBlock *BB, Region *R);
00575
00578 void changeTopLevelRegion(Region *OldRegion, Region *NewRegion);
00579
00582 void addTopLevelRegion(Region *New) {
00583 assert(New->getParent() == 0 && "Region already in subregion!");
00584 topLevelRegions.insert(New);
00585 }
00586
00588 void removeBBFromMap(BasicBlock *BB);
00589
00590 };
00591
00592 }
00593 #endif
00594