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