RegionInfo.cpp revision 67be08a2f186d8262781f0d1ef67cab3cd2a0d2b
1f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//===- RegionInfo.cpp - SESE region detection analysis --------------------===//
2f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//
3f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//                     The LLVM Compiler Infrastructure
4f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//
5f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// This file is distributed under the University of Illinois Open Source
6f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// License. See LICENSE.TXT for details.
7f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//
8f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//===----------------------------------------------------------------------===//
9f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// Detects single entry single exit regions in the control flow graph.
10f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//===----------------------------------------------------------------------===//
11f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
12f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/Analysis/RegionInfo.h"
13f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/Analysis/RegionIterator.h"
14f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
15f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/ADT/PostOrderIterator.h"
16f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/ADT/Statistic.h"
17f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/Support/CommandLine.h"
18f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/Support/ErrorHandling.h"
19f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/Support/raw_ostream.h"
20082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser#include "llvm/Analysis/LoopInfo.h"
21f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
22f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#define DEBUG_TYPE "region"
23f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/Support/Debug.h"
24f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
25f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include <set>
26f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include <algorithm>
27f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
28f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserusing namespace llvm;
29f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
30f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// Always verify if expensive checking is enabled.
31f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#ifdef XDEBUG
32811edc1f1a0672d28cd7c938e478a92543e68a51Dan Gohmanstatic bool VerifyRegionInfo = true;
33f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#else
34811edc1f1a0672d28cd7c938e478a92543e68a51Dan Gohmanstatic bool VerifyRegionInfo = false;
35f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#endif
36f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
37f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserstatic cl::opt<bool,true>
38f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserVerifyRegionInfoX("verify-region-info", cl::location(VerifyRegionInfo),
39f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                cl::desc("Verify region info (time consuming)"));
40f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
41f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserSTATISTIC(numRegions,       "The # of regions");
42f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserSTATISTIC(numSimpleRegions, "The # of simple regions");
43f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
44f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//===----------------------------------------------------------------------===//
45f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser/// PrintStyle - Print region in difference ways.
46f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserenum PrintStyle { PrintNone, PrintBB, PrintRN  };
47f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
48f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grossercl::opt<enum PrintStyle> printStyle("print-region-style", cl::Hidden,
49f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  cl::desc("style of printing regions"),
50f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  cl::values(
51f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    clEnumValN(PrintNone, "none",  "print no details"),
52f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    clEnumValN(PrintBB, "bb",  "print regions in detail with block_iterator"),
53f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    clEnumValN(PrintRN, "rn",  "print regions in detail with element_iterator"),
54f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    clEnumValEnd));
55f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//===----------------------------------------------------------------------===//
56f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser/// Region Implementation
57f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion::Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RInfo,
58f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser               DominatorTree *dt, Region *Parent)
59f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser               : RegionNode(Parent, Entry, 1), RI(RInfo), DT(dt), exit(Exit) {}
60f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
61f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion::~Region() {
62329878f4ddd72c6f2d2d6acfa48d7e1447ed88c0Daniel Dunbar  // Free the cached nodes.
63329878f4ddd72c6f2d2d6acfa48d7e1447ed88c0Daniel Dunbar  for (BBNodeMapT::iterator it = BBNodeMap.begin(),
64329878f4ddd72c6f2d2d6acfa48d7e1447ed88c0Daniel Dunbar         ie = BBNodeMap.end(); it != ie; ++it)
65329878f4ddd72c6f2d2d6acfa48d7e1447ed88c0Daniel Dunbar    delete it->second;
66329878f4ddd72c6f2d2d6acfa48d7e1447ed88c0Daniel Dunbar
67f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Only clean the cache for this Region. Caches of child Regions will be
68f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // cleaned when the child Regions are deleted.
69f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBNodeMap.clear();
70f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
71f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (iterator I = begin(), E = end(); I != E; ++I)
72f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    delete *I;
73f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
74f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
75f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserbool Region::contains(const BasicBlock *B) const {
76f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BasicBlock *BB = const_cast<BasicBlock*>(B);
77f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
78f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(DT->getNode(BB) && "BB not part of the dominance tree");
79f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
80f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BasicBlock *entry = getEntry(), *exit = getExit();
81f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
82f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Toplevel region.
83f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (!exit)
84f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return true;
85f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
86f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return (DT->dominates(entry, BB)
87f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    && !(DT->dominates(exit, BB) && DT->dominates(entry, exit)));
88f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
89f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
90082d587d35a41ee06985d7867b72fb2632962281Tobias Grosserbool Region::contains(const Loop *L) const {
91082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  // BBs that are not part of any loop are element of the Loop
92082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  // described by the NULL pointer. This loop is not part of any region,
93082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  // except if the region describes the whole function.
94082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  if (L == 0)
95082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    return getExit() == 0;
96082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
97082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  if (!contains(L->getHeader()))
98082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    return false;
99082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
100082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  SmallVector<BasicBlock *, 8> ExitingBlocks;
101082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  L->getExitingBlocks(ExitingBlocks);
102082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
103082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  for (SmallVectorImpl<BasicBlock*>::iterator BI = ExitingBlocks.begin(),
104082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser       BE = ExitingBlocks.end(); BI != BE; ++BI)
105082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    if (!contains(*BI))
106082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser      return false;
107082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
108082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  return true;
109082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser}
110082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
111082d587d35a41ee06985d7867b72fb2632962281Tobias GrosserLoop *Region::outermostLoopInRegion(Loop *L) const {
112082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  if (!contains(L))
113082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    return 0;
114082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
115082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  while (L && contains(L->getParentLoop())) {
116082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    L = L->getParentLoop();
117082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  }
118082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
119082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  return L;
120082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser}
121082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
122082d587d35a41ee06985d7867b72fb2632962281Tobias GrosserLoop *Region::outermostLoopInRegion(LoopInfo *LI, BasicBlock* BB) const {
123082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  assert(LI && BB && "LI and BB cannot be null!");
124082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  Loop *L = LI->getLoopFor(BB);
125082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  return outermostLoopInRegion(L);
126082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser}
127082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
128f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserbool Region::isSimple() const {
129f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  bool isSimple = true;
130f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  bool found = false;
131f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
132f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BasicBlock *entry = getEntry(), *exit = getExit();
133f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
134f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // TopLevelRegion
135f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (!exit)
136f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return false;
137f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
138f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (pred_iterator PI = pred_begin(entry), PE = pred_end(entry); PI != PE;
13973362c820bad20e545d37b8a2414c35c0d3d583cTobias Grosser       ++PI) {
14073362c820bad20e545d37b8a2414c35c0d3d583cTobias Grosser    BasicBlock *Pred = *PI;
14173362c820bad20e545d37b8a2414c35c0d3d583cTobias Grosser    if (DT->getNode(Pred) && !contains(Pred)) {
142f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      if (found) {
143f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        isSimple = false;
144f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        break;
145f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      }
146f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      found = true;
147f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    }
14873362c820bad20e545d37b8a2414c35c0d3d583cTobias Grosser  }
149f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
150f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  found = false;
151f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
152f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (pred_iterator PI = pred_begin(exit), PE = pred_end(exit); PI != PE;
153f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser       ++PI)
154f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (contains(*PI)) {
155f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      if (found) {
156f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        isSimple = false;
157f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        break;
158f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      }
159f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      found = true;
160f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    }
161f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
162f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return isSimple;
163f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
164f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
165082d587d35a41ee06985d7867b72fb2632962281Tobias Grosserstd::string Region::getNameStr() const {
166082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  std::string exitName;
167082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  std::string entryName;
168082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
169082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  if (getEntry()->getName().empty()) {
170082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    raw_string_ostream OS(entryName);
171082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
172082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    WriteAsOperand(OS, getEntry(), false);
173082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    entryName = OS.str();
174082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  } else
175082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    entryName = getEntry()->getNameStr();
176082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
177082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  if (getExit()) {
178082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    if (getExit()->getName().empty()) {
179082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser      raw_string_ostream OS(exitName);
180082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
181082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser      WriteAsOperand(OS, getExit(), false);
182082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser      exitName = OS.str();
183082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    } else
184082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser      exitName = getExit()->getNameStr();
185082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  } else
186082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser    exitName = "<Function Return>";
187082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
188082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser  return entryName + " => " + exitName;
189082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser}
190082d587d35a41ee06985d7867b72fb2632962281Tobias Grosser
191f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid Region::verifyBBInRegion(BasicBlock *BB) const {
192f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (!contains(BB))
193f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    llvm_unreachable("Broken region found!");
194f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
195f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BasicBlock *entry = getEntry(), *exit = getExit();
196f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
197f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
198f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (!contains(*SI) && exit != *SI)
199f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      llvm_unreachable("Broken region found!");
200f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
201f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (entry != BB)
202f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    for (pred_iterator SI = pred_begin(BB), SE = pred_end(BB); SI != SE; ++SI)
203f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      if (!contains(*SI))
204f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        llvm_unreachable("Broken region found!");
205f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
206f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
207f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid Region::verifyWalk(BasicBlock *BB, std::set<BasicBlock*> *visited) const {
208f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BasicBlock *exit = getExit();
209f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
210f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  visited->insert(BB);
211f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
212f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  verifyBBInRegion(BB);
213f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
214f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
215f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (*SI != exit && visited->find(*SI) == visited->end())
216f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        verifyWalk(*SI, visited);
217f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
218f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
219f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid Region::verifyRegion() const {
220f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Only do verification when user wants to, otherwise this expensive
221f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // check will be invoked by PassManager.
222f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (!VerifyRegionInfo) return;
223f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
224f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  std::set<BasicBlock*> visited;
225f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  verifyWalk(getEntry(), &visited);
226f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
227f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
228f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid Region::verifyRegionNest() const {
229f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (Region::const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
230f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    (*RI)->verifyRegionNest();
231f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
232f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  verifyRegion();
233f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
234f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
235f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion::block_iterator Region::block_begin() {
236f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return GraphTraits<FlatIt<Region*> >::nodes_begin(this);
237f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
238f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
239f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion::block_iterator Region::block_end() {
240f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return GraphTraits<FlatIt<Region*> >::nodes_end(this);
241f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
242f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
243f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion::const_block_iterator Region::block_begin() const {
244f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return GraphTraits<FlatIt<const Region*> >::nodes_begin(this);
245f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
246f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
247f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion::const_block_iterator Region::block_end() const {
248f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return GraphTraits<FlatIt<const Region*> >::nodes_end(this);
249f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
250f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
251f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion::element_iterator Region::element_begin() {
252f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return GraphTraits<Region*>::nodes_begin(this);
253f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
254f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
255f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion::element_iterator Region::element_end() {
256f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return GraphTraits<Region*>::nodes_end(this);
257f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
258f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
259f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion::const_element_iterator Region::element_begin() const {
260f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return GraphTraits<const Region*>::nodes_begin(this);
261f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
262f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
263f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion::const_element_iterator Region::element_end() const {
264f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return GraphTraits<const Region*>::nodes_end(this);
265f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
266f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
267f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion* Region::getSubRegionNode(BasicBlock *BB) const {
268f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  Region *R = RI->getRegionFor(BB);
269f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
270f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (!R || R == this)
271f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return 0;
272f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
273f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // If we pass the BB out of this region, that means our code is broken.
274f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(contains(R) && "BB not in current region!");
275f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
276f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  while (contains(R->getParent()) && R->getParent() != this)
277f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    R = R->getParent();
278f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
279f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (R->getEntry() != BB)
280f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return 0;
281f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
282f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return R;
283f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
284f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
285f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegionNode* Region::getBBNode(BasicBlock *BB) const {
286f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(contains(BB) && "Can get BB node out of this region!");
287f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
288f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBNodeMapT::const_iterator at = BBNodeMap.find(BB);
289f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
290f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (at != BBNodeMap.end())
291f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return at->second;
292f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
293f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  RegionNode *NewNode = new RegionNode(const_cast<Region*>(this), BB);
294f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBNodeMap.insert(std::make_pair(BB, NewNode));
295f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return NewNode;
296f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
297f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
298f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegionNode* Region::getNode(BasicBlock *BB) const {
299f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(contains(BB) && "Can get BB node out of this region!");
300f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (Region* Child = getSubRegionNode(BB))
301f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return Child->getNode();
302f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
303f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return getBBNode(BB);
304f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
305f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
306f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid Region::transferChildrenTo(Region *To) {
307f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (iterator I = begin(), E = end(); I != E; ++I) {
308f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    (*I)->parent = To;
309f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    To->children.push_back(*I);
310f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
311f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  children.clear();
312f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
313f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
314f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid Region::addSubRegion(Region *SubRegion) {
315f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(SubRegion->parent == 0 && "SubRegion already has a parent!");
316f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  SubRegion->parent = this;
317f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Set up the region node.
318f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(std::find(children.begin(), children.end(), SubRegion) == children.end()
319f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser         && "Node already exist!");
320f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  children.push_back(SubRegion);
321f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
322f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
323f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
324f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion *Region::removeSubRegion(Region *Child) {
325f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(Child->parent == this && "Child is not a child of this region!");
326f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  Child->parent = 0;
327f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  RegionSet::iterator I = std::find(children.begin(), children.end(), Child);
328f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(I != children.end() && "Region does not exit. Unable to remove.");
329f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  children.erase(children.begin()+(I-begin()));
330f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return Child;
331f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
332f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
333f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserunsigned Region::getDepth() const {
334f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  unsigned Depth = 0;
335f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
336f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (Region *R = parent; R != 0; R = R->parent)
337f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    ++Depth;
338f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
339f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return Depth;
340f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
341f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
342f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid Region::print(raw_ostream &OS, bool print_tree, unsigned level) const {
343f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (print_tree)
344f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    OS.indent(level*2) << "[" << level << "] " << getNameStr();
345f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  else
346f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    OS.indent(level*2) << getNameStr();
347f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
348f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  OS << "\n";
349f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
350f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
351f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (printStyle != PrintNone) {
352f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    OS.indent(level*2) << "{\n";
353f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    OS.indent(level*2 + 2);
354f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
355f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (printStyle == PrintBB) {
356f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      for (const_block_iterator I = block_begin(), E = block_end(); I!=E; ++I)
357f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        OS << **I << ", "; // TODO: remove the last ","
358f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    } else if (printStyle == PrintRN) {
359f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      for (const_element_iterator I = element_begin(), E = element_end(); I!=E; ++I)
360f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        OS << **I << ", "; // TODO: remove the last ",
361f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    }
362f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
363f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    OS << "\n";
364f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
365f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
366f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (print_tree)
367f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    for (const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
368f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      (*RI)->print(OS, print_tree, level+1);
369f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
370f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (printStyle != PrintNone)
371f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    OS.indent(level*2) << "} \n";
372f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
373f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
374f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid Region::dump() const {
375f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  print(dbgs(), true, getDepth());
376f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
377f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
378f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid Region::clearNodeCache() {
37967be08a2f186d8262781f0d1ef67cab3cd2a0d2bTobias Grosser  // Free the cached nodes.
38067be08a2f186d8262781f0d1ef67cab3cd2a0d2bTobias Grosser  for (BBNodeMapT::iterator I = BBNodeMap.begin(),
38167be08a2f186d8262781f0d1ef67cab3cd2a0d2bTobias Grosser       IE = BBNodeMap.end(); I != IE; ++IE)
38267be08a2f186d8262781f0d1ef67cab3cd2a0d2bTobias Grosser    delete I->second;
38367be08a2f186d8262781f0d1ef67cab3cd2a0d2bTobias Grosser
384f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBNodeMap.clear();
385f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (Region::iterator RI = begin(), RE = end(); RI != RE; ++RI)
386f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    (*RI)->clearNodeCache();
387f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
388f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
389f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//===----------------------------------------------------------------------===//
390f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// RegionInfo implementation
391f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//
392f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
393f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserbool RegionInfo::isCommonDomFrontier(BasicBlock *BB, BasicBlock *entry,
394f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                                     BasicBlock *exit) const {
3953d8586eb6384f22984e8c519ea9742eac68c9724Gabor Greif  for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
3963d8586eb6384f22984e8c519ea9742eac68c9724Gabor Greif    BasicBlock *P = *PI;
3973d8586eb6384f22984e8c519ea9742eac68c9724Gabor Greif    if (DT->dominates(entry, P) && !DT->dominates(exit, P))
398f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      return false;
3993d8586eb6384f22984e8c519ea9742eac68c9724Gabor Greif  }
400f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return true;
401f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
402f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
403f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserbool RegionInfo::isRegion(BasicBlock *entry, BasicBlock *exit) const {
404f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(entry && exit && "entry and exit must not be null!");
405f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  typedef DominanceFrontier::DomSetType DST;
406f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
40711aa60d05ac3a26a547022f574fa09dfeec2e0ccGabor Greif  DST *entrySuccs = &DF->find(entry)->second;
408f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
409f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Exit is the header of a loop that contains the entry. In this case,
410f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // the dominance frontier must only contain the exit.
411f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (!DT->dominates(entry, exit)) {
412f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
413f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser         SI != SE; ++SI)
414f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      if (*SI != exit && *SI != entry)
415f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        return false;
416f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
417f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return true;
418f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
419f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
42011aa60d05ac3a26a547022f574fa09dfeec2e0ccGabor Greif  DST *exitSuccs = &DF->find(exit)->second;
421f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
422f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Do not allow edges leaving the region.
423f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
424f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser       SI != SE; ++SI) {
425f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (*SI == exit || *SI == entry)
426f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      continue;
427f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (exitSuccs->find(*SI) == exitSuccs->end())
428f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      return false;
429f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (!isCommonDomFrontier(*SI, entry, exit))
430f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      return false;
431f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
432f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
433f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Do not allow edges pointing into the region.
434f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (DST::iterator SI = exitSuccs->begin(), SE = exitSuccs->end();
435f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser       SI != SE; ++SI)
436a29dbd2dcc04c8d07dd9e1e49b4e54debbc23996Dan Gohman    if (DT->properlyDominates(entry, *SI) && *SI != exit)
437f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      return false;
438f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
439f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
440f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return true;
441f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
442f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
443f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid RegionInfo::insertShortCut(BasicBlock *entry, BasicBlock *exit,
444f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                             BBtoBBMap *ShortCut) const {
445f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(entry && exit && "entry and exit must not be null!");
446f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
447f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBtoBBMap::iterator e = ShortCut->find(exit);
448f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
449f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (e == ShortCut->end())
450f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    // No further region at exit available.
451f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    (*ShortCut)[entry] = exit;
452f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  else {
453f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    // We found a region e that starts at exit. Therefore (entry, e->second)
454f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    // is also a region, that is larger than (entry, exit). Insert the
455f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    // larger one.
456f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    BasicBlock *BB = e->second;
457f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    (*ShortCut)[entry] = BB;
458f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
459f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
460f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
461f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserDomTreeNode* RegionInfo::getNextPostDom(DomTreeNode* N,
462f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                                        BBtoBBMap *ShortCut) const {
463f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBtoBBMap::iterator e = ShortCut->find(N->getBlock());
464f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
465f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (e == ShortCut->end())
466f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return N->getIDom();
467f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
468f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return PDT->getNode(e->second)->getIDom();
469f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
470f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
471f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserbool RegionInfo::isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const {
472f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(entry && exit && "entry and exit must not be null!");
473f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
474f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  unsigned num_successors = succ_end(entry) - succ_begin(entry);
475f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
476f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (num_successors <= 1 && exit == *(succ_begin(entry)))
477f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return true;
478f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
479f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return false;
480f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
481f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
482f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid RegionInfo::updateStatistics(Region *R) {
483f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  ++numRegions;
484f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
485f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // TODO: Slow. Should only be enabled if -stats is used.
486f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (R->isSimple()) ++numSimpleRegions;
487f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
488f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
489f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion *RegionInfo::createRegion(BasicBlock *entry, BasicBlock *exit) {
490f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(entry && exit && "entry and exit must not be null!");
491f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
492f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (isTrivialRegion(entry, exit))
493f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return 0;
494f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
495f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  Region *region = new Region(entry, exit, this, DT);
496f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBtoRegion.insert(std::make_pair(entry, region));
497f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
498f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser #ifdef XDEBUG
499f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    region->verifyRegion();
500f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser #else
501f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    DEBUG(region->verifyRegion());
502f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser #endif
503f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
504f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  updateStatistics(region);
505f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return region;
506f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
507f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
508f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid RegionInfo::findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut) {
509f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert(entry);
510f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
511f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  DomTreeNode *N = PDT->getNode(entry);
512f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
513f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (!N)
514f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return;
515f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
516f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  Region *lastRegion= 0;
517f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BasicBlock *lastExit = entry;
518f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
519f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // As only a BasicBlock that postdominates entry can finish a region, walk the
520f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // post dominance tree upwards.
521f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  while ((N = getNextPostDom(N, ShortCut))) {
522f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    BasicBlock *exit = N->getBlock();
523f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
524f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (!exit)
525f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      break;
526f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
527f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (isRegion(entry, exit)) {
528f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      Region *newRegion = createRegion(entry, exit);
529f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
530f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      if (lastRegion)
531f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        newRegion->addSubRegion(lastRegion);
532f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
533f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      lastRegion = newRegion;
534f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      lastExit = exit;
535f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    }
536f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
537f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    // This can never be a region, so stop the search.
538f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (!DT->dominates(entry, exit))
539f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      break;
540f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
541f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
542f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Tried to create regions from entry to lastExit.  Next time take a
543f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // shortcut from entry to lastExit.
544f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (lastExit != entry)
545f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    insertShortCut(entry, lastExit, ShortCut);
546f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
547f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
548f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid RegionInfo::scanForRegions(Function &F, BBtoBBMap *ShortCut) {
549f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BasicBlock *entry = &(F.getEntryBlock());
550f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  DomTreeNode *N = DT->getNode(entry);
551f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
552f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Iterate over the dominance tree in post order to start with the small
553f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // regions from the bottom of the dominance tree.  If the small regions are
554f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // detected first, detection of bigger regions is faster, as we can jump
555f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // over the small regions.
556f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (po_iterator<DomTreeNode*> FI = po_begin(N), FE = po_end(N); FI != FE;
557f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    ++FI) {
558f95eef695d35cac832dfd1ff2b2e3081f7d0e24aGabor Greif    findRegionsWithEntry(FI->getBlock(), ShortCut);
559f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
560f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
561f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
562f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion *RegionInfo::getTopMostParent(Region *region) {
563f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  while (region->parent)
564f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    region = region->getParent();
565f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
566f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return region;
567f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
568f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
569f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid RegionInfo::buildRegionsTree(DomTreeNode *N, Region *region) {
570f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BasicBlock *BB = N->getBlock();
571f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
572f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Passed region exit
573f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  while (BB == region->getExit())
574f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    region = region->getParent();
575f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
576f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBtoRegionMap::iterator it = BBtoRegion.find(BB);
577f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
578f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // This basic block is a start block of a region. It is already in the
579f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // BBtoRegion relation. Only the child basic blocks have to be updated.
580f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (it != BBtoRegion.end()) {
581f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    Region *newRegion = it->second;;
582f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    region->addSubRegion(getTopMostParent(newRegion));
583f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    region = newRegion;
584f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  } else {
585f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    BBtoRegion[BB] = region;
586f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
587f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
588f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (DomTreeNode::iterator CI = N->begin(), CE = N->end(); CI != CE; ++CI)
589f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    buildRegionsTree(*CI, region);
590f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
591f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
592f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid RegionInfo::releaseMemory() {
593f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBtoRegion.clear();
594f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (TopLevelRegion)
595f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    delete TopLevelRegion;
596f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  TopLevelRegion = 0;
597f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
598f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
59990c579de5a383cee278acc3f7e7b9d0a656e6a35Owen AndersonRegionInfo::RegionInfo() : FunctionPass(ID) {
600f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  TopLevelRegion = 0;
601f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
602f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
603f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegionInfo::~RegionInfo() {
604f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  releaseMemory();
605f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
606f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
607f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid RegionInfo::Calculate(Function &F) {
608f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // ShortCut a function where for every BB the exit of the largest region
609f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // starting with BB is stored. These regions can be threated as single BBS.
610f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // This improves performance on linear CFGs.
611f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBtoBBMap ShortCut;
612f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
613f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  scanForRegions(F, &ShortCut);
614f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BasicBlock *BB = &F.getEntryBlock();
615f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  buildRegionsTree(DT->getNode(BB), TopLevelRegion);
616f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
617f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
618f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserbool RegionInfo::runOnFunction(Function &F) {
619f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  releaseMemory();
620f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
621f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  DT = &getAnalysis<DominatorTree>();
622f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  PDT = &getAnalysis<PostDominatorTree>();
623f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  DF = &getAnalysis<DominanceFrontier>();
624f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
625f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  TopLevelRegion = new Region(&F.getEntryBlock(), 0, this, DT, 0);
626f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  updateStatistics(TopLevelRegion);
627f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
628f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  Calculate(F);
629f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
630f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return false;
631f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
632f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
633f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid RegionInfo::getAnalysisUsage(AnalysisUsage &AU) const {
634f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  AU.setPreservesAll();
635f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  AU.addRequiredTransitive<DominatorTree>();
636f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  AU.addRequired<PostDominatorTree>();
637f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  AU.addRequired<DominanceFrontier>();
638f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
639f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
640f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid RegionInfo::print(raw_ostream &OS, const Module *) const {
641f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  OS << "Region tree:\n";
642f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  TopLevelRegion->print(OS, true, 0);
643f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  OS << "End region tree\n";
644f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
645f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
646f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosservoid RegionInfo::verifyAnalysis() const {
647f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Only do verification when user wants to, otherwise this expensive check
648f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // will be invoked by PMDataManager::verifyPreservedAnalysis when
649f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // a regionpass (marked PreservedAll) finish.
650f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (!VerifyRegionInfo) return;
651f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
652f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  TopLevelRegion->verifyRegionNest();
653f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
654f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
655f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// Region pass manager support.
656f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion *RegionInfo::getRegionFor(BasicBlock *BB) const {
657f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBtoRegionMap::const_iterator I=
658f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    BBtoRegion.find(BB);
659f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return I != BBtoRegion.end() ? I->second : 0;
660f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
661f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
662f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion *RegionInfo::operator[](BasicBlock *BB) const {
663f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return getRegionFor(BB);
664f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
665f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
6660e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser
6670e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias GrosserBasicBlock *RegionInfo::getMaxRegionExit(BasicBlock *BB) const {
6680e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser  BasicBlock *Exit = NULL;
6690e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser
6700e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser  while (true) {
6710e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    // Get largest region that starts at BB.
6720e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    Region *R = getRegionFor(BB);
6730e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    while (R && R->getParent() && R->getParent()->getEntry() == BB)
6740e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser      R = R->getParent();
6750e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser
6760e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    // Get the single exit of BB.
6770e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    if (R && R->getEntry() == BB)
6780e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser      Exit = R->getExit();
6790e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    else if (++succ_begin(BB) == succ_end(BB))
6800e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser      Exit = *succ_begin(BB);
6810e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    else // No single exit exists.
6820e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser      return Exit;
6830e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser
6840e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    // Get largest region that starts at Exit.
6850e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    Region *ExitR = getRegionFor(Exit);
6860e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    while (ExitR && ExitR->getParent()
6870e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser           && ExitR->getParent()->getEntry() == Exit)
6880e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser      ExitR = ExitR->getParent();
6890e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser
6900e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    for (pred_iterator PI = pred_begin(Exit), PE = pred_end(Exit); PI != PE;
6910e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser         ++PI)
6920e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser      if (!R->contains(*PI) && !ExitR->contains(*PI))
6930e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser        break;
6940e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser
6950e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    // This stops infinite cycles.
6960e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    if (DT->dominates(Exit, BB))
6970e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser      break;
6980e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser
6990e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser    BB = Exit;
7000e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser  }
7010e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser
7020e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser  return Exit;
7030e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser}
7040e6fcf4be360f5d73685c213e3b4af1bb9ce2b5dTobias Grosser
705f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion*
706f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegionInfo::getCommonRegion(Region *A, Region *B) const {
707f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  assert (A && B && "One of the Regions is NULL");
708f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
709f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  if (A->contains(B)) return A;
710f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
711f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  while (!B->contains(A))
712f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    B = B->getParent();
713f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
714f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return B;
715f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
716f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
717f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion*
718f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegionInfo::getCommonRegion(SmallVectorImpl<Region*> &Regions) const {
719f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  Region* ret = Regions.back();
720f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  Regions.pop_back();
721f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
722f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (SmallVectorImpl<Region*>::const_iterator I = Regions.begin(),
723f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser       E = Regions.end(); I != E; ++I)
724f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      ret = getCommonRegion(ret, *I);
725f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
726f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return ret;
727f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
728f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
729f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegion*
730f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserRegionInfo::getCommonRegion(SmallVectorImpl<BasicBlock*> &BBs) const {
731f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  Region* ret = getRegionFor(BBs.back());
732f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  BBs.pop_back();
733f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
734f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  for (SmallVectorImpl<BasicBlock*>::const_iterator I = BBs.begin(),
735f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser       E = BBs.end(); I != E; ++I)
736f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      ret = getCommonRegion(ret, getRegionFor(*I));
737f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
738f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return ret;
739f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
740f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
741f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserchar RegionInfo::ID = 0;
7422ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_BEGIN(RegionInfo, "regions",
7432ab36d350293c77fc8941ce1023e4899df7e3a82Owen Anderson                "Detect single entry single exit regions", true, true)
7442ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_DEPENDENCY(DominatorTree)
7452ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_DEPENDENCY(PostDominatorTree)
7462ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_DEPENDENCY(DominanceFrontier)
7472ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_END(RegionInfo, "regions",
748ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson                "Detect single entry single exit regions", true, true)
749f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
750f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// Create methods available outside of this file, to use them
751f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
752f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// the link time optimization.
753f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
754f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grossernamespace llvm {
755f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  FunctionPass *createRegionInfoPass() {
756f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return new RegionInfo();
757f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
758f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
759f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
760