1*336734acSTobias Grosser //===- RegionInfo.cpp - SESE region detection analysis --------------------===// 2*336734acSTobias Grosser // 3*336734acSTobias Grosser // The LLVM Compiler Infrastructure 4*336734acSTobias Grosser // 5*336734acSTobias Grosser // This file is distributed under the University of Illinois Open Source 6*336734acSTobias Grosser // License. See LICENSE.TXT for details. 7*336734acSTobias Grosser // 8*336734acSTobias Grosser //===----------------------------------------------------------------------===// 9*336734acSTobias Grosser // Detects single entry single exit regions in the control flow graph. 10*336734acSTobias Grosser //===----------------------------------------------------------------------===// 11*336734acSTobias Grosser 12*336734acSTobias Grosser #include "llvm/Analysis/RegionInfo.h" 13*336734acSTobias Grosser #include "llvm/Analysis/RegionIterator.h" 14*336734acSTobias Grosser 15*336734acSTobias Grosser #include "llvm/ADT/PostOrderIterator.h" 16*336734acSTobias Grosser #include "llvm/ADT/Statistic.h" 17*336734acSTobias Grosser #include "llvm/Support/CommandLine.h" 18*336734acSTobias Grosser #include "llvm/Support/ErrorHandling.h" 19*336734acSTobias Grosser #include "llvm/Support/raw_ostream.h" 20*336734acSTobias Grosser 21*336734acSTobias Grosser #define DEBUG_TYPE "region" 22*336734acSTobias Grosser #include "llvm/Support/Debug.h" 23*336734acSTobias Grosser 24*336734acSTobias Grosser #include <set> 25*336734acSTobias Grosser #include <algorithm> 26*336734acSTobias Grosser 27*336734acSTobias Grosser using namespace llvm; 28*336734acSTobias Grosser 29*336734acSTobias Grosser // Always verify if expensive checking is enabled. 30*336734acSTobias Grosser #ifdef XDEBUG 31*336734acSTobias Grosser bool VerifyRegionInfo = true; 32*336734acSTobias Grosser #else 33*336734acSTobias Grosser bool VerifyRegionInfo = false; 34*336734acSTobias Grosser #endif 35*336734acSTobias Grosser 36*336734acSTobias Grosser static cl::opt<bool,true> 37*336734acSTobias Grosser VerifyRegionInfoX("verify-region-info", cl::location(VerifyRegionInfo), 38*336734acSTobias Grosser cl::desc("Verify region info (time consuming)")); 39*336734acSTobias Grosser 40*336734acSTobias Grosser STATISTIC(numRegions, "The # of regions"); 41*336734acSTobias Grosser STATISTIC(numSimpleRegions, "The # of simple regions"); 42*336734acSTobias Grosser 43*336734acSTobias Grosser //===----------------------------------------------------------------------===// 44*336734acSTobias Grosser /// PrintStyle - Print region in difference ways. 45*336734acSTobias Grosser enum PrintStyle { PrintNone, PrintBB, PrintRN }; 46*336734acSTobias Grosser 47*336734acSTobias Grosser cl::opt<enum PrintStyle> printStyle("print-region-style", cl::Hidden, 48*336734acSTobias Grosser cl::desc("style of printing regions"), 49*336734acSTobias Grosser cl::values( 50*336734acSTobias Grosser clEnumValN(PrintNone, "none", "print no details"), 51*336734acSTobias Grosser clEnumValN(PrintBB, "bb", "print regions in detail with block_iterator"), 52*336734acSTobias Grosser clEnumValN(PrintRN, "rn", "print regions in detail with element_iterator"), 53*336734acSTobias Grosser clEnumValEnd)); 54*336734acSTobias Grosser //===----------------------------------------------------------------------===// 55*336734acSTobias Grosser /// Region Implementation 56*336734acSTobias Grosser Region::Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RInfo, 57*336734acSTobias Grosser DominatorTree *dt, Region *Parent) 58*336734acSTobias Grosser : RegionNode(Parent, Entry, 1), RI(RInfo), DT(dt), exit(Exit) {} 59*336734acSTobias Grosser 60*336734acSTobias Grosser Region::~Region() { 61*336734acSTobias Grosser // Only clean the cache for this Region. Caches of child Regions will be 62*336734acSTobias Grosser // cleaned when the child Regions are deleted. 63*336734acSTobias Grosser BBNodeMap.clear(); 64*336734acSTobias Grosser 65*336734acSTobias Grosser for (iterator I = begin(), E = end(); I != E; ++I) 66*336734acSTobias Grosser delete *I; 67*336734acSTobias Grosser } 68*336734acSTobias Grosser 69*336734acSTobias Grosser bool Region::contains(const BasicBlock *B) const { 70*336734acSTobias Grosser BasicBlock *BB = const_cast<BasicBlock*>(B); 71*336734acSTobias Grosser 72*336734acSTobias Grosser assert(DT->getNode(BB) && "BB not part of the dominance tree"); 73*336734acSTobias Grosser 74*336734acSTobias Grosser BasicBlock *entry = getEntry(), *exit = getExit(); 75*336734acSTobias Grosser 76*336734acSTobias Grosser // Toplevel region. 77*336734acSTobias Grosser if (!exit) 78*336734acSTobias Grosser return true; 79*336734acSTobias Grosser 80*336734acSTobias Grosser return (DT->dominates(entry, BB) 81*336734acSTobias Grosser && !(DT->dominates(exit, BB) && DT->dominates(entry, exit))); 82*336734acSTobias Grosser } 83*336734acSTobias Grosser 84*336734acSTobias Grosser bool Region::isSimple() const { 85*336734acSTobias Grosser bool isSimple = true; 86*336734acSTobias Grosser bool found = false; 87*336734acSTobias Grosser 88*336734acSTobias Grosser BasicBlock *entry = getEntry(), *exit = getExit(); 89*336734acSTobias Grosser 90*336734acSTobias Grosser // TopLevelRegion 91*336734acSTobias Grosser if (!exit) 92*336734acSTobias Grosser return false; 93*336734acSTobias Grosser 94*336734acSTobias Grosser for (pred_iterator PI = pred_begin(entry), PE = pred_end(entry); PI != PE; 95*336734acSTobias Grosser ++PI) 96*336734acSTobias Grosser if (!contains(*PI)) { 97*336734acSTobias Grosser if (found) { 98*336734acSTobias Grosser isSimple = false; 99*336734acSTobias Grosser break; 100*336734acSTobias Grosser } 101*336734acSTobias Grosser found = true; 102*336734acSTobias Grosser } 103*336734acSTobias Grosser 104*336734acSTobias Grosser found = false; 105*336734acSTobias Grosser 106*336734acSTobias Grosser for (pred_iterator PI = pred_begin(exit), PE = pred_end(exit); PI != PE; 107*336734acSTobias Grosser ++PI) 108*336734acSTobias Grosser if (contains(*PI)) { 109*336734acSTobias Grosser if (found) { 110*336734acSTobias Grosser isSimple = false; 111*336734acSTobias Grosser break; 112*336734acSTobias Grosser } 113*336734acSTobias Grosser found = true; 114*336734acSTobias Grosser } 115*336734acSTobias Grosser 116*336734acSTobias Grosser return isSimple; 117*336734acSTobias Grosser } 118*336734acSTobias Grosser 119*336734acSTobias Grosser void Region::verifyBBInRegion(BasicBlock *BB) const { 120*336734acSTobias Grosser if (!contains(BB)) 121*336734acSTobias Grosser llvm_unreachable("Broken region found!"); 122*336734acSTobias Grosser 123*336734acSTobias Grosser BasicBlock *entry = getEntry(), *exit = getExit(); 124*336734acSTobias Grosser 125*336734acSTobias Grosser for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI) 126*336734acSTobias Grosser if (!contains(*SI) && exit != *SI) 127*336734acSTobias Grosser llvm_unreachable("Broken region found!"); 128*336734acSTobias Grosser 129*336734acSTobias Grosser if (entry != BB) 130*336734acSTobias Grosser for (pred_iterator SI = pred_begin(BB), SE = pred_end(BB); SI != SE; ++SI) 131*336734acSTobias Grosser if (!contains(*SI)) 132*336734acSTobias Grosser llvm_unreachable("Broken region found!"); 133*336734acSTobias Grosser } 134*336734acSTobias Grosser 135*336734acSTobias Grosser void Region::verifyWalk(BasicBlock *BB, std::set<BasicBlock*> *visited) const { 136*336734acSTobias Grosser BasicBlock *exit = getExit(); 137*336734acSTobias Grosser 138*336734acSTobias Grosser visited->insert(BB); 139*336734acSTobias Grosser 140*336734acSTobias Grosser verifyBBInRegion(BB); 141*336734acSTobias Grosser 142*336734acSTobias Grosser for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI) 143*336734acSTobias Grosser if (*SI != exit && visited->find(*SI) == visited->end()) 144*336734acSTobias Grosser verifyWalk(*SI, visited); 145*336734acSTobias Grosser } 146*336734acSTobias Grosser 147*336734acSTobias Grosser void Region::verifyRegion() const { 148*336734acSTobias Grosser // Only do verification when user wants to, otherwise this expensive 149*336734acSTobias Grosser // check will be invoked by PassManager. 150*336734acSTobias Grosser if (!VerifyRegionInfo) return; 151*336734acSTobias Grosser 152*336734acSTobias Grosser std::set<BasicBlock*> visited; 153*336734acSTobias Grosser verifyWalk(getEntry(), &visited); 154*336734acSTobias Grosser } 155*336734acSTobias Grosser 156*336734acSTobias Grosser void Region::verifyRegionNest() const { 157*336734acSTobias Grosser for (Region::const_iterator RI = begin(), RE = end(); RI != RE; ++RI) 158*336734acSTobias Grosser (*RI)->verifyRegionNest(); 159*336734acSTobias Grosser 160*336734acSTobias Grosser verifyRegion(); 161*336734acSTobias Grosser } 162*336734acSTobias Grosser 163*336734acSTobias Grosser Region::block_iterator Region::block_begin() { 164*336734acSTobias Grosser return GraphTraits<FlatIt<Region*> >::nodes_begin(this); 165*336734acSTobias Grosser } 166*336734acSTobias Grosser 167*336734acSTobias Grosser Region::block_iterator Region::block_end() { 168*336734acSTobias Grosser return GraphTraits<FlatIt<Region*> >::nodes_end(this); 169*336734acSTobias Grosser } 170*336734acSTobias Grosser 171*336734acSTobias Grosser Region::const_block_iterator Region::block_begin() const { 172*336734acSTobias Grosser return GraphTraits<FlatIt<const Region*> >::nodes_begin(this); 173*336734acSTobias Grosser } 174*336734acSTobias Grosser 175*336734acSTobias Grosser Region::const_block_iterator Region::block_end() const { 176*336734acSTobias Grosser return GraphTraits<FlatIt<const Region*> >::nodes_end(this); 177*336734acSTobias Grosser } 178*336734acSTobias Grosser 179*336734acSTobias Grosser Region::element_iterator Region::element_begin() { 180*336734acSTobias Grosser return GraphTraits<Region*>::nodes_begin(this); 181*336734acSTobias Grosser } 182*336734acSTobias Grosser 183*336734acSTobias Grosser Region::element_iterator Region::element_end() { 184*336734acSTobias Grosser return GraphTraits<Region*>::nodes_end(this); 185*336734acSTobias Grosser } 186*336734acSTobias Grosser 187*336734acSTobias Grosser Region::const_element_iterator Region::element_begin() const { 188*336734acSTobias Grosser return GraphTraits<const Region*>::nodes_begin(this); 189*336734acSTobias Grosser } 190*336734acSTobias Grosser 191*336734acSTobias Grosser Region::const_element_iterator Region::element_end() const { 192*336734acSTobias Grosser return GraphTraits<const Region*>::nodes_end(this); 193*336734acSTobias Grosser } 194*336734acSTobias Grosser 195*336734acSTobias Grosser Region* Region::getSubRegionNode(BasicBlock *BB) const { 196*336734acSTobias Grosser Region *R = RI->getRegionFor(BB); 197*336734acSTobias Grosser 198*336734acSTobias Grosser if (!R || R == this) 199*336734acSTobias Grosser return 0; 200*336734acSTobias Grosser 201*336734acSTobias Grosser // If we pass the BB out of this region, that means our code is broken. 202*336734acSTobias Grosser assert(contains(R) && "BB not in current region!"); 203*336734acSTobias Grosser 204*336734acSTobias Grosser while (contains(R->getParent()) && R->getParent() != this) 205*336734acSTobias Grosser R = R->getParent(); 206*336734acSTobias Grosser 207*336734acSTobias Grosser if (R->getEntry() != BB) 208*336734acSTobias Grosser return 0; 209*336734acSTobias Grosser 210*336734acSTobias Grosser return R; 211*336734acSTobias Grosser } 212*336734acSTobias Grosser 213*336734acSTobias Grosser RegionNode* Region::getBBNode(BasicBlock *BB) const { 214*336734acSTobias Grosser assert(contains(BB) && "Can get BB node out of this region!"); 215*336734acSTobias Grosser 216*336734acSTobias Grosser BBNodeMapT::const_iterator at = BBNodeMap.find(BB); 217*336734acSTobias Grosser 218*336734acSTobias Grosser if (at != BBNodeMap.end()) 219*336734acSTobias Grosser return at->second; 220*336734acSTobias Grosser 221*336734acSTobias Grosser RegionNode *NewNode = new RegionNode(const_cast<Region*>(this), BB); 222*336734acSTobias Grosser BBNodeMap.insert(std::make_pair(BB, NewNode)); 223*336734acSTobias Grosser return NewNode; 224*336734acSTobias Grosser } 225*336734acSTobias Grosser 226*336734acSTobias Grosser RegionNode* Region::getNode(BasicBlock *BB) const { 227*336734acSTobias Grosser assert(contains(BB) && "Can get BB node out of this region!"); 228*336734acSTobias Grosser if (Region* Child = getSubRegionNode(BB)) 229*336734acSTobias Grosser return Child->getNode(); 230*336734acSTobias Grosser 231*336734acSTobias Grosser return getBBNode(BB); 232*336734acSTobias Grosser } 233*336734acSTobias Grosser 234*336734acSTobias Grosser void Region::transferChildrenTo(Region *To) { 235*336734acSTobias Grosser for (iterator I = begin(), E = end(); I != E; ++I) { 236*336734acSTobias Grosser (*I)->parent = To; 237*336734acSTobias Grosser To->children.push_back(*I); 238*336734acSTobias Grosser } 239*336734acSTobias Grosser children.clear(); 240*336734acSTobias Grosser } 241*336734acSTobias Grosser 242*336734acSTobias Grosser void Region::addSubRegion(Region *SubRegion) { 243*336734acSTobias Grosser assert(SubRegion->parent == 0 && "SubRegion already has a parent!"); 244*336734acSTobias Grosser SubRegion->parent = this; 245*336734acSTobias Grosser // Set up the region node. 246*336734acSTobias Grosser assert(std::find(children.begin(), children.end(), SubRegion) == children.end() 247*336734acSTobias Grosser && "Node already exist!"); 248*336734acSTobias Grosser children.push_back(SubRegion); 249*336734acSTobias Grosser } 250*336734acSTobias Grosser 251*336734acSTobias Grosser 252*336734acSTobias Grosser Region *Region::removeSubRegion(Region *Child) { 253*336734acSTobias Grosser assert(Child->parent == this && "Child is not a child of this region!"); 254*336734acSTobias Grosser Child->parent = 0; 255*336734acSTobias Grosser RegionSet::iterator I = std::find(children.begin(), children.end(), Child); 256*336734acSTobias Grosser assert(I != children.end() && "Region does not exit. Unable to remove."); 257*336734acSTobias Grosser children.erase(children.begin()+(I-begin())); 258*336734acSTobias Grosser return Child; 259*336734acSTobias Grosser } 260*336734acSTobias Grosser 261*336734acSTobias Grosser unsigned Region::getDepth() const { 262*336734acSTobias Grosser unsigned Depth = 0; 263*336734acSTobias Grosser 264*336734acSTobias Grosser for (Region *R = parent; R != 0; R = R->parent) 265*336734acSTobias Grosser ++Depth; 266*336734acSTobias Grosser 267*336734acSTobias Grosser return Depth; 268*336734acSTobias Grosser } 269*336734acSTobias Grosser 270*336734acSTobias Grosser void Region::print(raw_ostream &OS, bool print_tree, unsigned level) const { 271*336734acSTobias Grosser if (print_tree) 272*336734acSTobias Grosser OS.indent(level*2) << "[" << level << "] " << getNameStr(); 273*336734acSTobias Grosser else 274*336734acSTobias Grosser OS.indent(level*2) << getNameStr(); 275*336734acSTobias Grosser 276*336734acSTobias Grosser OS << "\n"; 277*336734acSTobias Grosser 278*336734acSTobias Grosser 279*336734acSTobias Grosser if (printStyle != PrintNone) { 280*336734acSTobias Grosser OS.indent(level*2) << "{\n"; 281*336734acSTobias Grosser OS.indent(level*2 + 2); 282*336734acSTobias Grosser 283*336734acSTobias Grosser if (printStyle == PrintBB) { 284*336734acSTobias Grosser for (const_block_iterator I = block_begin(), E = block_end(); I!=E; ++I) 285*336734acSTobias Grosser OS << **I << ", "; // TODO: remove the last "," 286*336734acSTobias Grosser } else if (printStyle == PrintRN) { 287*336734acSTobias Grosser for (const_element_iterator I = element_begin(), E = element_end(); I!=E; ++I) 288*336734acSTobias Grosser OS << **I << ", "; // TODO: remove the last ", 289*336734acSTobias Grosser } 290*336734acSTobias Grosser 291*336734acSTobias Grosser OS << "\n"; 292*336734acSTobias Grosser } 293*336734acSTobias Grosser 294*336734acSTobias Grosser if (print_tree) 295*336734acSTobias Grosser for (const_iterator RI = begin(), RE = end(); RI != RE; ++RI) 296*336734acSTobias Grosser (*RI)->print(OS, print_tree, level+1); 297*336734acSTobias Grosser 298*336734acSTobias Grosser if (printStyle != PrintNone) 299*336734acSTobias Grosser OS.indent(level*2) << "} \n"; 300*336734acSTobias Grosser } 301*336734acSTobias Grosser 302*336734acSTobias Grosser void Region::dump() const { 303*336734acSTobias Grosser print(dbgs(), true, getDepth()); 304*336734acSTobias Grosser } 305*336734acSTobias Grosser 306*336734acSTobias Grosser void Region::clearNodeCache() { 307*336734acSTobias Grosser BBNodeMap.clear(); 308*336734acSTobias Grosser for (Region::iterator RI = begin(), RE = end(); RI != RE; ++RI) 309*336734acSTobias Grosser (*RI)->clearNodeCache(); 310*336734acSTobias Grosser } 311*336734acSTobias Grosser 312*336734acSTobias Grosser //===----------------------------------------------------------------------===// 313*336734acSTobias Grosser // RegionInfo implementation 314*336734acSTobias Grosser // 315*336734acSTobias Grosser 316*336734acSTobias Grosser bool RegionInfo::isCommonDomFrontier(BasicBlock *BB, BasicBlock *entry, 317*336734acSTobias Grosser BasicBlock *exit) const { 318*336734acSTobias Grosser for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) 319*336734acSTobias Grosser if (DT->dominates(entry, *PI) && !DT->dominates(exit, *PI)) 320*336734acSTobias Grosser return false; 321*336734acSTobias Grosser 322*336734acSTobias Grosser return true; 323*336734acSTobias Grosser } 324*336734acSTobias Grosser 325*336734acSTobias Grosser bool RegionInfo::isRegion(BasicBlock *entry, BasicBlock *exit) const { 326*336734acSTobias Grosser assert(entry && exit && "entry and exit must not be null!"); 327*336734acSTobias Grosser typedef DominanceFrontier::DomSetType DST; 328*336734acSTobias Grosser 329*336734acSTobias Grosser DST *entrySuccs = &(*DF->find(entry)).second; 330*336734acSTobias Grosser 331*336734acSTobias Grosser // Exit is the header of a loop that contains the entry. In this case, 332*336734acSTobias Grosser // the dominance frontier must only contain the exit. 333*336734acSTobias Grosser if (!DT->dominates(entry, exit)) { 334*336734acSTobias Grosser for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end(); 335*336734acSTobias Grosser SI != SE; ++SI) 336*336734acSTobias Grosser if (*SI != exit && *SI != entry) 337*336734acSTobias Grosser return false; 338*336734acSTobias Grosser 339*336734acSTobias Grosser return true; 340*336734acSTobias Grosser } 341*336734acSTobias Grosser 342*336734acSTobias Grosser DST *exitSuccs = &(*DF->find(exit)).second; 343*336734acSTobias Grosser 344*336734acSTobias Grosser // Do not allow edges leaving the region. 345*336734acSTobias Grosser for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end(); 346*336734acSTobias Grosser SI != SE; ++SI) { 347*336734acSTobias Grosser if (*SI == exit || *SI == entry) 348*336734acSTobias Grosser continue; 349*336734acSTobias Grosser if (exitSuccs->find(*SI) == exitSuccs->end()) 350*336734acSTobias Grosser return false; 351*336734acSTobias Grosser if (!isCommonDomFrontier(*SI, entry, exit)) 352*336734acSTobias Grosser return false; 353*336734acSTobias Grosser } 354*336734acSTobias Grosser 355*336734acSTobias Grosser // Do not allow edges pointing into the region. 356*336734acSTobias Grosser for (DST::iterator SI = exitSuccs->begin(), SE = exitSuccs->end(); 357*336734acSTobias Grosser SI != SE; ++SI) 358*336734acSTobias Grosser if (DT->dominates(entry, *SI) && *SI != entry && *SI != exit) 359*336734acSTobias Grosser return false; 360*336734acSTobias Grosser 361*336734acSTobias Grosser 362*336734acSTobias Grosser return true; 363*336734acSTobias Grosser } 364*336734acSTobias Grosser 365*336734acSTobias Grosser void RegionInfo::insertShortCut(BasicBlock *entry, BasicBlock *exit, 366*336734acSTobias Grosser BBtoBBMap *ShortCut) const { 367*336734acSTobias Grosser assert(entry && exit && "entry and exit must not be null!"); 368*336734acSTobias Grosser 369*336734acSTobias Grosser BBtoBBMap::iterator e = ShortCut->find(exit); 370*336734acSTobias Grosser 371*336734acSTobias Grosser if (e == ShortCut->end()) 372*336734acSTobias Grosser // No further region at exit available. 373*336734acSTobias Grosser (*ShortCut)[entry] = exit; 374*336734acSTobias Grosser else { 375*336734acSTobias Grosser // We found a region e that starts at exit. Therefore (entry, e->second) 376*336734acSTobias Grosser // is also a region, that is larger than (entry, exit). Insert the 377*336734acSTobias Grosser // larger one. 378*336734acSTobias Grosser BasicBlock *BB = e->second; 379*336734acSTobias Grosser (*ShortCut)[entry] = BB; 380*336734acSTobias Grosser } 381*336734acSTobias Grosser } 382*336734acSTobias Grosser 383*336734acSTobias Grosser DomTreeNode* RegionInfo::getNextPostDom(DomTreeNode* N, 384*336734acSTobias Grosser BBtoBBMap *ShortCut) const { 385*336734acSTobias Grosser BBtoBBMap::iterator e = ShortCut->find(N->getBlock()); 386*336734acSTobias Grosser 387*336734acSTobias Grosser if (e == ShortCut->end()) 388*336734acSTobias Grosser return N->getIDom(); 389*336734acSTobias Grosser 390*336734acSTobias Grosser return PDT->getNode(e->second)->getIDom(); 391*336734acSTobias Grosser } 392*336734acSTobias Grosser 393*336734acSTobias Grosser bool RegionInfo::isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const { 394*336734acSTobias Grosser assert(entry && exit && "entry and exit must not be null!"); 395*336734acSTobias Grosser 396*336734acSTobias Grosser unsigned num_successors = succ_end(entry) - succ_begin(entry); 397*336734acSTobias Grosser 398*336734acSTobias Grosser if (num_successors <= 1 && exit == *(succ_begin(entry))) 399*336734acSTobias Grosser return true; 400*336734acSTobias Grosser 401*336734acSTobias Grosser return false; 402*336734acSTobias Grosser } 403*336734acSTobias Grosser 404*336734acSTobias Grosser void RegionInfo::updateStatistics(Region *R) { 405*336734acSTobias Grosser ++numRegions; 406*336734acSTobias Grosser 407*336734acSTobias Grosser // TODO: Slow. Should only be enabled if -stats is used. 408*336734acSTobias Grosser if (R->isSimple()) ++numSimpleRegions; 409*336734acSTobias Grosser } 410*336734acSTobias Grosser 411*336734acSTobias Grosser Region *RegionInfo::createRegion(BasicBlock *entry, BasicBlock *exit) { 412*336734acSTobias Grosser assert(entry && exit && "entry and exit must not be null!"); 413*336734acSTobias Grosser 414*336734acSTobias Grosser if (isTrivialRegion(entry, exit)) 415*336734acSTobias Grosser return 0; 416*336734acSTobias Grosser 417*336734acSTobias Grosser Region *region = new Region(entry, exit, this, DT); 418*336734acSTobias Grosser BBtoRegion.insert(std::make_pair(entry, region)); 419*336734acSTobias Grosser 420*336734acSTobias Grosser #ifdef XDEBUG 421*336734acSTobias Grosser region->verifyRegion(); 422*336734acSTobias Grosser #else 423*336734acSTobias Grosser DEBUG(region->verifyRegion()); 424*336734acSTobias Grosser #endif 425*336734acSTobias Grosser 426*336734acSTobias Grosser updateStatistics(region); 427*336734acSTobias Grosser return region; 428*336734acSTobias Grosser } 429*336734acSTobias Grosser 430*336734acSTobias Grosser void RegionInfo::findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut) { 431*336734acSTobias Grosser assert(entry); 432*336734acSTobias Grosser 433*336734acSTobias Grosser DomTreeNode *N = PDT->getNode(entry); 434*336734acSTobias Grosser 435*336734acSTobias Grosser if (!N) 436*336734acSTobias Grosser return; 437*336734acSTobias Grosser 438*336734acSTobias Grosser Region *lastRegion= 0; 439*336734acSTobias Grosser BasicBlock *lastExit = entry; 440*336734acSTobias Grosser 441*336734acSTobias Grosser // As only a BasicBlock that postdominates entry can finish a region, walk the 442*336734acSTobias Grosser // post dominance tree upwards. 443*336734acSTobias Grosser while ((N = getNextPostDom(N, ShortCut))) { 444*336734acSTobias Grosser BasicBlock *exit = N->getBlock(); 445*336734acSTobias Grosser 446*336734acSTobias Grosser if (!exit) 447*336734acSTobias Grosser break; 448*336734acSTobias Grosser 449*336734acSTobias Grosser if (isRegion(entry, exit)) { 450*336734acSTobias Grosser Region *newRegion = createRegion(entry, exit); 451*336734acSTobias Grosser 452*336734acSTobias Grosser if (lastRegion) 453*336734acSTobias Grosser newRegion->addSubRegion(lastRegion); 454*336734acSTobias Grosser 455*336734acSTobias Grosser lastRegion = newRegion; 456*336734acSTobias Grosser lastExit = exit; 457*336734acSTobias Grosser } 458*336734acSTobias Grosser 459*336734acSTobias Grosser // This can never be a region, so stop the search. 460*336734acSTobias Grosser if (!DT->dominates(entry, exit)) 461*336734acSTobias Grosser break; 462*336734acSTobias Grosser } 463*336734acSTobias Grosser 464*336734acSTobias Grosser // Tried to create regions from entry to lastExit. Next time take a 465*336734acSTobias Grosser // shortcut from entry to lastExit. 466*336734acSTobias Grosser if (lastExit != entry) 467*336734acSTobias Grosser insertShortCut(entry, lastExit, ShortCut); 468*336734acSTobias Grosser } 469*336734acSTobias Grosser 470*336734acSTobias Grosser void RegionInfo::scanForRegions(Function &F, BBtoBBMap *ShortCut) { 471*336734acSTobias Grosser BasicBlock *entry = &(F.getEntryBlock()); 472*336734acSTobias Grosser DomTreeNode *N = DT->getNode(entry); 473*336734acSTobias Grosser 474*336734acSTobias Grosser // Iterate over the dominance tree in post order to start with the small 475*336734acSTobias Grosser // regions from the bottom of the dominance tree. If the small regions are 476*336734acSTobias Grosser // detected first, detection of bigger regions is faster, as we can jump 477*336734acSTobias Grosser // over the small regions. 478*336734acSTobias Grosser for (po_iterator<DomTreeNode*> FI = po_begin(N), FE = po_end(N); FI != FE; 479*336734acSTobias Grosser ++FI) { 480*336734acSTobias Grosser findRegionsWithEntry((*FI)->getBlock(), ShortCut); 481*336734acSTobias Grosser } 482*336734acSTobias Grosser } 483*336734acSTobias Grosser 484*336734acSTobias Grosser Region *RegionInfo::getTopMostParent(Region *region) { 485*336734acSTobias Grosser while (region->parent) 486*336734acSTobias Grosser region = region->getParent(); 487*336734acSTobias Grosser 488*336734acSTobias Grosser return region; 489*336734acSTobias Grosser } 490*336734acSTobias Grosser 491*336734acSTobias Grosser void RegionInfo::buildRegionsTree(DomTreeNode *N, Region *region) { 492*336734acSTobias Grosser BasicBlock *BB = N->getBlock(); 493*336734acSTobias Grosser 494*336734acSTobias Grosser // Passed region exit 495*336734acSTobias Grosser while (BB == region->getExit()) 496*336734acSTobias Grosser region = region->getParent(); 497*336734acSTobias Grosser 498*336734acSTobias Grosser BBtoRegionMap::iterator it = BBtoRegion.find(BB); 499*336734acSTobias Grosser 500*336734acSTobias Grosser // This basic block is a start block of a region. It is already in the 501*336734acSTobias Grosser // BBtoRegion relation. Only the child basic blocks have to be updated. 502*336734acSTobias Grosser if (it != BBtoRegion.end()) { 503*336734acSTobias Grosser Region *newRegion = it->second;; 504*336734acSTobias Grosser region->addSubRegion(getTopMostParent(newRegion)); 505*336734acSTobias Grosser region = newRegion; 506*336734acSTobias Grosser } else { 507*336734acSTobias Grosser BBtoRegion[BB] = region; 508*336734acSTobias Grosser } 509*336734acSTobias Grosser 510*336734acSTobias Grosser for (DomTreeNode::iterator CI = N->begin(), CE = N->end(); CI != CE; ++CI) 511*336734acSTobias Grosser buildRegionsTree(*CI, region); 512*336734acSTobias Grosser } 513*336734acSTobias Grosser 514*336734acSTobias Grosser void RegionInfo::releaseMemory() { 515*336734acSTobias Grosser BBtoRegion.clear(); 516*336734acSTobias Grosser if (TopLevelRegion) 517*336734acSTobias Grosser delete TopLevelRegion; 518*336734acSTobias Grosser TopLevelRegion = 0; 519*336734acSTobias Grosser } 520*336734acSTobias Grosser 521*336734acSTobias Grosser RegionInfo::RegionInfo() : FunctionPass(&ID) { 522*336734acSTobias Grosser TopLevelRegion = 0; 523*336734acSTobias Grosser } 524*336734acSTobias Grosser 525*336734acSTobias Grosser RegionInfo::~RegionInfo() { 526*336734acSTobias Grosser releaseMemory(); 527*336734acSTobias Grosser } 528*336734acSTobias Grosser 529*336734acSTobias Grosser void RegionInfo::Calculate(Function &F) { 530*336734acSTobias Grosser // ShortCut a function where for every BB the exit of the largest region 531*336734acSTobias Grosser // starting with BB is stored. These regions can be threated as single BBS. 532*336734acSTobias Grosser // This improves performance on linear CFGs. 533*336734acSTobias Grosser BBtoBBMap ShortCut; 534*336734acSTobias Grosser 535*336734acSTobias Grosser scanForRegions(F, &ShortCut); 536*336734acSTobias Grosser BasicBlock *BB = &F.getEntryBlock(); 537*336734acSTobias Grosser buildRegionsTree(DT->getNode(BB), TopLevelRegion); 538*336734acSTobias Grosser } 539*336734acSTobias Grosser 540*336734acSTobias Grosser bool RegionInfo::runOnFunction(Function &F) { 541*336734acSTobias Grosser releaseMemory(); 542*336734acSTobias Grosser 543*336734acSTobias Grosser DT = &getAnalysis<DominatorTree>(); 544*336734acSTobias Grosser PDT = &getAnalysis<PostDominatorTree>(); 545*336734acSTobias Grosser DF = &getAnalysis<DominanceFrontier>(); 546*336734acSTobias Grosser 547*336734acSTobias Grosser TopLevelRegion = new Region(&F.getEntryBlock(), 0, this, DT, 0); 548*336734acSTobias Grosser updateStatistics(TopLevelRegion); 549*336734acSTobias Grosser 550*336734acSTobias Grosser Calculate(F); 551*336734acSTobias Grosser 552*336734acSTobias Grosser return false; 553*336734acSTobias Grosser } 554*336734acSTobias Grosser 555*336734acSTobias Grosser void RegionInfo::getAnalysisUsage(AnalysisUsage &AU) const { 556*336734acSTobias Grosser AU.setPreservesAll(); 557*336734acSTobias Grosser AU.addRequiredTransitive<DominatorTree>(); 558*336734acSTobias Grosser AU.addRequired<PostDominatorTree>(); 559*336734acSTobias Grosser AU.addRequired<DominanceFrontier>(); 560*336734acSTobias Grosser } 561*336734acSTobias Grosser 562*336734acSTobias Grosser void RegionInfo::print(raw_ostream &OS, const Module *) const { 563*336734acSTobias Grosser OS << "Region tree:\n"; 564*336734acSTobias Grosser TopLevelRegion->print(OS, true, 0); 565*336734acSTobias Grosser OS << "End region tree\n"; 566*336734acSTobias Grosser } 567*336734acSTobias Grosser 568*336734acSTobias Grosser void RegionInfo::verifyAnalysis() const { 569*336734acSTobias Grosser // Only do verification when user wants to, otherwise this expensive check 570*336734acSTobias Grosser // will be invoked by PMDataManager::verifyPreservedAnalysis when 571*336734acSTobias Grosser // a regionpass (marked PreservedAll) finish. 572*336734acSTobias Grosser if (!VerifyRegionInfo) return; 573*336734acSTobias Grosser 574*336734acSTobias Grosser TopLevelRegion->verifyRegionNest(); 575*336734acSTobias Grosser } 576*336734acSTobias Grosser 577*336734acSTobias Grosser // Region pass manager support. 578*336734acSTobias Grosser Region *RegionInfo::getRegionFor(BasicBlock *BB) const { 579*336734acSTobias Grosser BBtoRegionMap::const_iterator I= 580*336734acSTobias Grosser BBtoRegion.find(BB); 581*336734acSTobias Grosser return I != BBtoRegion.end() ? I->second : 0; 582*336734acSTobias Grosser } 583*336734acSTobias Grosser 584*336734acSTobias Grosser Region *RegionInfo::operator[](BasicBlock *BB) const { 585*336734acSTobias Grosser return getRegionFor(BB); 586*336734acSTobias Grosser } 587*336734acSTobias Grosser 588*336734acSTobias Grosser Region* 589*336734acSTobias Grosser RegionInfo::getCommonRegion(Region *A, Region *B) const { 590*336734acSTobias Grosser assert (A && B && "One of the Regions is NULL"); 591*336734acSTobias Grosser 592*336734acSTobias Grosser if (A->contains(B)) return A; 593*336734acSTobias Grosser 594*336734acSTobias Grosser while (!B->contains(A)) 595*336734acSTobias Grosser B = B->getParent(); 596*336734acSTobias Grosser 597*336734acSTobias Grosser return B; 598*336734acSTobias Grosser } 599*336734acSTobias Grosser 600*336734acSTobias Grosser Region* 601*336734acSTobias Grosser RegionInfo::getCommonRegion(SmallVectorImpl<Region*> &Regions) const { 602*336734acSTobias Grosser Region* ret = Regions.back(); 603*336734acSTobias Grosser Regions.pop_back(); 604*336734acSTobias Grosser 605*336734acSTobias Grosser for (SmallVectorImpl<Region*>::const_iterator I = Regions.begin(), 606*336734acSTobias Grosser E = Regions.end(); I != E; ++I) 607*336734acSTobias Grosser ret = getCommonRegion(ret, *I); 608*336734acSTobias Grosser 609*336734acSTobias Grosser return ret; 610*336734acSTobias Grosser } 611*336734acSTobias Grosser 612*336734acSTobias Grosser Region* 613*336734acSTobias Grosser RegionInfo::getCommonRegion(SmallVectorImpl<BasicBlock*> &BBs) const { 614*336734acSTobias Grosser Region* ret = getRegionFor(BBs.back()); 615*336734acSTobias Grosser BBs.pop_back(); 616*336734acSTobias Grosser 617*336734acSTobias Grosser for (SmallVectorImpl<BasicBlock*>::const_iterator I = BBs.begin(), 618*336734acSTobias Grosser E = BBs.end(); I != E; ++I) 619*336734acSTobias Grosser ret = getCommonRegion(ret, getRegionFor(*I)); 620*336734acSTobias Grosser 621*336734acSTobias Grosser return ret; 622*336734acSTobias Grosser } 623*336734acSTobias Grosser 624*336734acSTobias Grosser char RegionInfo::ID = 0; 625*336734acSTobias Grosser INITIALIZE_PASS(RegionInfo, "regions", 626*336734acSTobias Grosser "Detect single entry single exit regions", true, true); 627*336734acSTobias Grosser 628*336734acSTobias Grosser // Create methods available outside of this file, to use them 629*336734acSTobias Grosser // "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by 630*336734acSTobias Grosser // the link time optimization. 631*336734acSTobias Grosser 632*336734acSTobias Grosser namespace llvm { 633*336734acSTobias Grosser FunctionPass *createRegionInfoPass() { 634*336734acSTobias Grosser return new RegionInfo(); 635*336734acSTobias Grosser } 636*336734acSTobias Grosser } 637*336734acSTobias Grosser 638