119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- RegionInfo.cpp - SESE region detection analysis --------------------===//
219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//                     The LLVM Compiler Infrastructure
419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source
619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details.
719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Detects single entry single exit regions in the control flow graph.
1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Analysis/RegionInfo.h"
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Analysis/RegionIterator.h"
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/PostOrderIterator.h"
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Statistic.h"
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/CommandLine.h"
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ErrorHandling.h"
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Analysis/LoopInfo.h"
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Assembly/Writer.h"
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define DEBUG_TYPE "region"
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Debug.h"
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <set>
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <algorithm>
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm;
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Always verify if expensive checking is enabled.
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef XDEBUG
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool VerifyRegionInfo = true;
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#else
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool VerifyRegionInfo = false;
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<bool,true>
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanVerifyRegionInfoX("verify-region-info", cl::location(VerifyRegionInfo),
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                cl::desc("Verify region info (time consuming)"));
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(numRegions,       "The # of regions");
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(numSimpleRegions, "The # of simple regions");
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<enum Region::PrintStyle> printStyle("print-region-style",
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  cl::Hidden,
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  cl::desc("style of printing regions"),
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  cl::values(
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    clEnumValN(Region::PrintNone, "none",  "print no details"),
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    clEnumValN(Region::PrintBB, "bb",
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               "print regions in detail with block_iterator"),
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    clEnumValN(Region::PrintRN, "rn",
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               "print regions in detail with element_iterator"),
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    clEnumValEnd));
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// Region Implementation
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion::Region(BasicBlock *Entry, BasicBlock *Exit, RegionInfo* RInfo,
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               DominatorTree *dt, Region *Parent)
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               : RegionNode(Parent, Entry, 1), RI(RInfo), DT(dt), exit(Exit) {}
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion::~Region() {
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Free the cached nodes.
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (BBNodeMapT::iterator it = BBNodeMap.begin(),
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ie = BBNodeMap.end(); it != ie; ++it)
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    delete it->second;
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Only clean the cache for this Region. Caches of child Regions will be
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // cleaned when the child Regions are deleted.
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBNodeMap.clear();
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (iterator I = begin(), E = end(); I != E; ++I)
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    delete *I;
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Region::replaceEntry(BasicBlock *BB) {
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  entry.setPointer(BB);
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Region::replaceExit(BasicBlock *BB) {
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(exit && "No exit to replace!");
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  exit = BB;
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool Region::contains(const BasicBlock *B) const {
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *BB = const_cast<BasicBlock*>(B);
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(DT->getNode(BB) && "BB not part of the dominance tree");
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *entry = getEntry(), *exit = getExit();
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Toplevel region.
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!exit)
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return (DT->dominates(entry, BB)
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    && !(DT->dominates(exit, BB) && DT->dominates(entry, exit)));
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool Region::contains(const Loop *L) const {
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // BBs that are not part of any loop are element of the Loop
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // described by the NULL pointer. This loop is not part of any region,
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // except if the region describes the whole function.
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (L == 0)
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return getExit() == 0;
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!contains(L->getHeader()))
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<BasicBlock *, 8> ExitingBlocks;
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  L->getExitingBlocks(ExitingBlocks);
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (SmallVectorImpl<BasicBlock*>::iterator BI = ExitingBlocks.begin(),
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       BE = ExitingBlocks.end(); BI != BE; ++BI)
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!contains(*BI))
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanLoop *Region::outermostLoopInRegion(Loop *L) const {
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!contains(L))
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 0;
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (L && contains(L->getParentLoop())) {
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    L = L->getParentLoop();
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return L;
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanLoop *Region::outermostLoopInRegion(LoopInfo *LI, BasicBlock* BB) const {
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(LI && BB && "LI and BB cannot be null!");
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Loop *L = LI->getLoopFor(BB);
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return outermostLoopInRegion(L);
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanBasicBlock *Region::getEnteringBlock() const {
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *entry = getEntry();
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *Pred;
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *enteringBlock = 0;
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (pred_iterator PI = pred_begin(entry), PE = pred_end(entry); PI != PE;
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       ++PI) {
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Pred = *PI;
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (DT->getNode(Pred) && !contains(Pred)) {
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (enteringBlock)
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return 0;
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      enteringBlock = Pred;
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return enteringBlock;
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanBasicBlock *Region::getExitingBlock() const {
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *exit = getExit();
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *Pred;
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *exitingBlock = 0;
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!exit)
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 0;
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (pred_iterator PI = pred_begin(exit), PE = pred_end(exit); PI != PE;
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       ++PI) {
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Pred = *PI;
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (contains(Pred)) {
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (exitingBlock)
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return 0;
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      exitingBlock = Pred;
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return exitingBlock;
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool Region::isSimple() const {
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return !isTopLevelRegion() && getEnteringBlock() && getExitingBlock();
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstd::string Region::getNameStr() const {
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::string exitName;
18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::string entryName;
18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getEntry()->getName().empty()) {
18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    raw_string_ostream OS(entryName);
18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    WriteAsOperand(OS, getEntry(), false);
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    entryName = OS.str();
19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    entryName = getEntry()->getNameStr();
19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (getExit()) {
19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (getExit()->getName().empty()) {
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      raw_string_ostream OS(exitName);
19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      WriteAsOperand(OS, getExit(), false);
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      exitName = OS.str();
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      exitName = getExit()->getNameStr();
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    exitName = "<Function Return>";
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return entryName + " => " + exitName;
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Region::verifyBBInRegion(BasicBlock *BB) const {
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!contains(BB))
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    llvm_unreachable("Broken region found!");
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *entry = getEntry(), *exit = getExit();
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!contains(*SI) && exit != *SI)
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      llvm_unreachable("Broken region found!");
21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (entry != BB)
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (pred_iterator SI = pred_begin(BB), SE = pred_end(BB); SI != SE; ++SI)
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!contains(*SI))
22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        llvm_unreachable("Broken region found!");
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Region::verifyWalk(BasicBlock *BB, std::set<BasicBlock*> *visited) const {
22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *exit = getExit();
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  visited->insert(BB);
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  verifyBBInRegion(BB);
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (*SI != exit && visited->find(*SI) == visited->end())
23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        verifyWalk(*SI, visited);
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Region::verifyRegion() const {
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Only do verification when user wants to, otherwise this expensive
23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // check will be invoked by PassManager.
23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!VerifyRegionInfo) return;
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::set<BasicBlock*> visited;
24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  verifyWalk(getEntry(), &visited);
24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Region::verifyRegionNest() const {
24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (Region::const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    (*RI)->verifyRegionNest();
24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  verifyRegion();
24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion::block_iterator Region::block_begin() {
25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return GraphTraits<FlatIt<Region*> >::nodes_begin(this);
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion::block_iterator Region::block_end() {
25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return GraphTraits<FlatIt<Region*> >::nodes_end(this);
25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion::const_block_iterator Region::block_begin() const {
26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return GraphTraits<FlatIt<const Region*> >::nodes_begin(this);
26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion::const_block_iterator Region::block_end() const {
26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return GraphTraits<FlatIt<const Region*> >::nodes_end(this);
26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion::element_iterator Region::element_begin() {
26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return GraphTraits<Region*>::nodes_begin(this);
26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion::element_iterator Region::element_end() {
27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return GraphTraits<Region*>::nodes_end(this);
27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion::const_element_iterator Region::element_begin() const {
27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return GraphTraits<const Region*>::nodes_begin(this);
27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion::const_element_iterator Region::element_end() const {
28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return GraphTraits<const Region*>::nodes_end(this);
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion* Region::getSubRegionNode(BasicBlock *BB) const {
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Region *R = RI->getRegionFor(BB);
28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!R || R == this)
28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 0;
28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If we pass the BB out of this region, that means our code is broken.
29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(contains(R) && "BB not in current region!");
29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (contains(R->getParent()) && R->getParent() != this)
29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    R = R->getParent();
29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (R->getEntry() != BB)
29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 0;
29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return R;
29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegionNode* Region::getBBNode(BasicBlock *BB) const {
30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(contains(BB) && "Can get BB node out of this region!");
30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBNodeMapT::const_iterator at = BBNodeMap.find(BB);
30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (at != BBNodeMap.end())
30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return at->second;
30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RegionNode *NewNode = new RegionNode(const_cast<Region*>(this), BB);
31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBNodeMap.insert(std::make_pair(BB, NewNode));
31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return NewNode;
31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegionNode* Region::getNode(BasicBlock *BB) const {
31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(contains(BB) && "Can get BB node out of this region!");
31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Region* Child = getSubRegionNode(BB))
31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Child->getNode();
31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return getBBNode(BB);
32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Region::transferChildrenTo(Region *To) {
32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (iterator I = begin(), E = end(); I != E; ++I) {
32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    (*I)->parent = To;
32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    To->children.push_back(*I);
32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  children.clear();
32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Region::addSubRegion(Region *SubRegion, bool moveChildren) {
33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(SubRegion->parent == 0 && "SubRegion already has a parent!");
33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(std::find(begin(), end(), SubRegion) == children.end()
33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         && "Subregion already exists!");
33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SubRegion->parent = this;
33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  children.push_back(SubRegion);
33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!moveChildren)
33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return;
34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(SubRegion->children.size() == 0
34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         && "SubRegions that contain children are not supported");
34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (element_iterator I = element_begin(), E = element_end(); I != E; ++I)
34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!(*I)->isSubRegion()) {
34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BasicBlock *BB = (*I)->getNodeAs<BasicBlock>();
34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (SubRegion->contains(BB))
34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        RI->setRegionFor(BB, SubRegion);
35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::vector<Region*> Keep;
35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (iterator I = begin(), E = end(); I != E; ++I)
35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (SubRegion->contains(*I) && *I != SubRegion) {
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      SubRegion->children.push_back(*I);
35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      (*I)->parent = SubRegion;
35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else
35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Keep.push_back(*I);
35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  children.clear();
36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  children.insert(children.begin(), Keep.begin(), Keep.end());
36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion *Region::removeSubRegion(Region *Child) {
36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(Child->parent == this && "Child is not a child of this region!");
36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Child->parent = 0;
36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RegionSet::iterator I = std::find(children.begin(), children.end(), Child);
36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(I != children.end() && "Region does not exit. Unable to remove.");
37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  children.erase(children.begin()+(I-begin()));
37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Child;
37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned Region::getDepth() const {
37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Depth = 0;
37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (Region *R = parent; R != 0; R = R->parent)
37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ++Depth;
37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Depth;
38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion *Region::getExpandedRegion() const {
38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned NumSuccessors = exit->getTerminator()->getNumSuccessors();
38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (NumSuccessors == 0)
38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return NULL;
38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (pred_iterator PI = pred_begin(getExit()), PE = pred_end(getExit());
39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       PI != PE; ++PI)
39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!DT->dominates(getEntry(), *PI))
39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return NULL;
39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Region *R = RI->getRegionFor(exit);
39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (R->getEntry() != exit) {
39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (exit->getTerminator()->getNumSuccessors() == 1)
39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return new Region(getEntry(), *succ_begin(exit), RI, DT);
39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return NULL;
40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (R->getParent() && R->getParent()->getEntry() == exit)
40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    R = R->getParent();
40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!DT->dominates(getEntry(), R->getExit()))
40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (pred_iterator PI = pred_begin(getExit()), PE = pred_end(getExit());
40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         PI != PE; ++PI)
40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!DT->dominates(R->getExit(), *PI))
41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return NULL;
41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return new Region(getEntry(), R->getExit(), RI, DT);
41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Region::print(raw_ostream &OS, bool print_tree, unsigned level,
41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   enum PrintStyle Style) const {
41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (print_tree)
41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS.indent(level*2) << "[" << level << "] " << getNameStr();
41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS.indent(level*2) << getNameStr();
42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  OS << "\n";
42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Style != PrintNone) {
42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS.indent(level*2) << "{\n";
42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS.indent(level*2 + 2);
42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Style == PrintBB) {
43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (const_block_iterator I = block_begin(), E = block_end(); I!=E; ++I)
43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        OS << **I << ", "; // TODO: remove the last ","
43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else if (Style == PrintRN) {
43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (const_element_iterator I = element_begin(), E = element_end(); I!=E; ++I)
43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        OS << **I << ", "; // TODO: remove the last ",
43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS << "\n";
43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (print_tree)
44119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (const_iterator RI = begin(), RE = end(); RI != RE; ++RI)
44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      (*RI)->print(OS, print_tree, level+1, Style);
44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Style != PrintNone)
44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OS.indent(level*2) << "} \n";
44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Region::dump() const {
44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  print(dbgs(), true, getDepth(), printStyle.getValue());
45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Region::clearNodeCache() {
45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Free the cached nodes.
45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (BBNodeMapT::iterator I = BBNodeMap.begin(),
45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       IE = BBNodeMap.end(); I != IE; ++I)
45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    delete I->second;
45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBNodeMap.clear();
45919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (Region::iterator RI = begin(), RE = end(); RI != RE; ++RI)
46019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    (*RI)->clearNodeCache();
46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// RegionInfo implementation
46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool RegionInfo::isCommonDomFrontier(BasicBlock *BB, BasicBlock *entry,
46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                     BasicBlock *exit) const {
46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) {
47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BasicBlock *P = *PI;
47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (DT->dominates(entry, P) && !DT->dominates(exit, P))
47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool RegionInfo::isRegion(BasicBlock *entry, BasicBlock *exit) const {
47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(entry && exit && "entry and exit must not be null!");
47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  typedef DominanceFrontier::DomSetType DST;
48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DST *entrySuccs = &DF->find(entry)->second;
48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Exit is the header of a loop that contains the entry. In this case,
48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // the dominance frontier must only contain the exit.
48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!DT->dominates(entry, exit)) {
48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         SI != SE; ++SI)
48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (*SI != exit && *SI != entry)
48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return false;
49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DST *exitSuccs = &DF->find(exit)->second;
49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Do not allow edges leaving the region.
49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (DST::iterator SI = entrySuccs->begin(), SE = entrySuccs->end();
49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       SI != SE; ++SI) {
49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (*SI == exit || *SI == entry)
50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (exitSuccs->find(*SI) == exitSuccs->end())
50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!isCommonDomFrontier(*SI, entry, exit))
50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Do not allow edges pointing into the region.
50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (DST::iterator SI = exitSuccs->begin(), SE = exitSuccs->end();
50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       SI != SE; ++SI)
51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (DT->properlyDominates(entry, *SI) && *SI != exit)
51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
51419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::insertShortCut(BasicBlock *entry, BasicBlock *exit,
51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             BBtoBBMap *ShortCut) const {
51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(entry && exit && "entry and exit must not be null!");
52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBtoBBMap::iterator e = ShortCut->find(exit);
52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (e == ShortCut->end())
52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // No further region at exit available.
52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    (*ShortCut)[entry] = exit;
52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else {
52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // We found a region e that starts at exit. Therefore (entry, e->second)
52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // is also a region, that is larger than (entry, exit). Insert the
52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // larger one.
53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BasicBlock *BB = e->second;
53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    (*ShortCut)[entry] = BB;
53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanDomTreeNode* RegionInfo::getNextPostDom(DomTreeNode* N,
53619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                        BBtoBBMap *ShortCut) const {
53719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBtoBBMap::iterator e = ShortCut->find(N->getBlock());
53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (e == ShortCut->end())
54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return N->getIDom();
54119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return PDT->getNode(e->second)->getIDom();
54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool RegionInfo::isTrivialRegion(BasicBlock *entry, BasicBlock *exit) const {
54619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(entry && exit && "entry and exit must not be null!");
54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned num_successors = succ_end(entry) - succ_begin(entry);
54919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (num_successors <= 1 && exit == *(succ_begin(entry)))
55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
55219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::updateStatistics(Region *R) {
55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++numRegions;
55819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // TODO: Slow. Should only be enabled if -stats is used.
56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (R->isSimple()) ++numSimpleRegions;
56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion *RegionInfo::createRegion(BasicBlock *entry, BasicBlock *exit) {
56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(entry && exit && "entry and exit must not be null!");
56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (isTrivialRegion(entry, exit))
56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return 0;
56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Region *region = new Region(entry, exit, this, DT);
57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBtoRegion.insert(std::make_pair(entry, region));
57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman #ifdef XDEBUG
57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    region->verifyRegion();
57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman #else
57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DEBUG(region->verifyRegion());
57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman #endif
57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  updateStatistics(region);
57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return region;
58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::findRegionsWithEntry(BasicBlock *entry, BBtoBBMap *ShortCut) {
58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(entry);
58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DomTreeNode *N = PDT->getNode(entry);
58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!N)
58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return;
58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Region *lastRegion= 0;
59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *lastExit = entry;
59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // As only a BasicBlock that postdominates entry can finish a region, walk the
59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // post dominance tree upwards.
59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while ((N = getNextPostDom(N, ShortCut))) {
59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BasicBlock *exit = N->getBlock();
59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!exit)
59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (isRegion(entry, exit)) {
60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Region *newRegion = createRegion(entry, exit);
60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (lastRegion)
60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        newRegion->addSubRegion(lastRegion);
60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      lastRegion = newRegion;
60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      lastExit = exit;
60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // This can never be a region, so stop the search.
61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!DT->dominates(entry, exit))
61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Tried to create regions from entry to lastExit.  Next time take a
61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // shortcut from entry to lastExit.
61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (lastExit != entry)
61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    insertShortCut(entry, lastExit, ShortCut);
62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::scanForRegions(Function &F, BBtoBBMap *ShortCut) {
62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *entry = &(F.getEntryBlock());
62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DomTreeNode *N = DT->getNode(entry);
62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Iterate over the dominance tree in post order to start with the small
62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // regions from the bottom of the dominance tree.  If the small regions are
62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // detected first, detection of bigger regions is faster, as we can jump
62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // over the small regions.
63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (po_iterator<DomTreeNode*> FI = po_begin(N), FE = po_end(N); FI != FE;
63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ++FI) {
63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    findRegionsWithEntry(FI->getBlock(), ShortCut);
63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion *RegionInfo::getTopMostParent(Region *region) {
63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (region->parent)
63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    region = region->getParent();
63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return region;
64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::buildRegionsTree(DomTreeNode *N, Region *region) {
64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *BB = N->getBlock();
64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Passed region exit
64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (BB == region->getExit())
64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    region = region->getParent();
64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBtoRegionMap::iterator it = BBtoRegion.find(BB);
65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // This basic block is a start block of a region. It is already in the
65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // BBtoRegion relation. Only the child basic blocks have to be updated.
65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (it != BBtoRegion.end()) {
65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Region *newRegion = it->second;;
65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    region->addSubRegion(getTopMostParent(newRegion));
65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    region = newRegion;
65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBtoRegion[BB] = region;
66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (DomTreeNode::iterator CI = N->begin(), CE = N->end(); CI != CE; ++CI)
66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    buildRegionsTree(*CI, region);
66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::releaseMemory() {
66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBtoRegion.clear();
66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TopLevelRegion)
66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    delete TopLevelRegion;
67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TopLevelRegion = 0;
67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
67219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
67319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegionInfo::RegionInfo() : FunctionPass(ID) {
67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  initializeRegionInfoPass(*PassRegistry::getPassRegistry());
67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TopLevelRegion = 0;
67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
67719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegionInfo::~RegionInfo() {
67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  releaseMemory();
68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
68119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
68219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::Calculate(Function &F) {
68319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ShortCut a function where for every BB the exit of the largest region
68419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // starting with BB is stored. These regions can be threated as single BBS.
68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // This improves performance on linear CFGs.
68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBtoBBMap ShortCut;
68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  scanForRegions(F, &ShortCut);
68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *BB = &F.getEntryBlock();
69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  buildRegionsTree(DT->getNode(BB), TopLevelRegion);
69119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
69219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool RegionInfo::runOnFunction(Function &F) {
69419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  releaseMemory();
69519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
69619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DT = &getAnalysis<DominatorTree>();
69719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PDT = &getAnalysis<PostDominatorTree>();
69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DF = &getAnalysis<DominanceFrontier>();
69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TopLevelRegion = new Region(&F.getEntryBlock(), 0, this, DT, 0);
70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  updateStatistics(TopLevelRegion);
70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
70319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Calculate(F);
70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::getAnalysisUsage(AnalysisUsage &AU) const {
70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.setPreservesAll();
71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.addRequiredTransitive<DominatorTree>();
71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.addRequired<PostDominatorTree>();
71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.addRequired<DominanceFrontier>();
71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::print(raw_ostream &OS, const Module *) const {
71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  OS << "Region tree:\n";
71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TopLevelRegion->print(OS, true, 0, printStyle.getValue());
71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  OS << "End region tree\n";
71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::verifyAnalysis() const {
72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Only do verification when user wants to, otherwise this expensive check
72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // will be invoked by PMDataManager::verifyPreservedAnalysis when
72419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // a regionpass (marked PreservedAll) finish.
72519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!VerifyRegionInfo) return;
72619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TopLevelRegion->verifyRegionNest();
72819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
72919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
73019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Region pass manager support.
73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion *RegionInfo::getRegionFor(BasicBlock *BB) const {
73219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBtoRegionMap::const_iterator I=
73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBtoRegion.find(BB);
73419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return I != BBtoRegion.end() ? I->second : 0;
73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
73719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::setRegionFor(BasicBlock *BB, Region *R) {
73819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBtoRegion[BB] = R;
73919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
74119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion *RegionInfo::operator[](BasicBlock *BB) const {
74219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return getRegionFor(BB);
74319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
74419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
74519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanBasicBlock *RegionInfo::getMaxRegionExit(BasicBlock *BB) const {
74619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *Exit = NULL;
74719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
74819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (true) {
74919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Get largest region that starts at BB.
75019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Region *R = getRegionFor(BB);
75119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    while (R && R->getParent() && R->getParent()->getEntry() == BB)
75219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      R = R->getParent();
75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
75419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Get the single exit of BB.
75519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (R && R->getEntry() == BB)
75619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Exit = R->getExit();
75719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else if (++succ_begin(BB) == succ_end(BB))
75819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Exit = *succ_begin(BB);
75919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else // No single exit exists.
76019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Exit;
76119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
76219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Get largest region that starts at Exit.
76319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Region *ExitR = getRegionFor(Exit);
76419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    while (ExitR && ExitR->getParent()
76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           && ExitR->getParent()->getEntry() == Exit)
76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ExitR = ExitR->getParent();
76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
76819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (pred_iterator PI = pred_begin(Exit), PE = pred_end(Exit); PI != PE;
76919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ++PI)
77019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!R->contains(*PI) && !ExitR->contains(*PI))
77119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
77219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
77319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // This stops infinite cycles.
77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (DT->dominates(Exit, BB))
77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
77619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
77719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BB = Exit;
77819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
78019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Exit;
78119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
78219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
78319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion*
78419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegionInfo::getCommonRegion(Region *A, Region *B) const {
78519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert (A && B && "One of the Regions is NULL");
78619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (A->contains(B)) return A;
78819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
78919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (!B->contains(A))
79019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    B = B->getParent();
79119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
79219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return B;
79319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
79419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion*
79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegionInfo::getCommonRegion(SmallVectorImpl<Region*> &Regions) const {
79719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Region* ret = Regions.back();
79819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Regions.pop_back();
79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (SmallVectorImpl<Region*>::const_iterator I = Regions.begin(),
80119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       E = Regions.end(); I != E; ++I)
80219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ret = getCommonRegion(ret, *I);
80319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return ret;
80519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
80619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegion*
80819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRegionInfo::getCommonRegion(SmallVectorImpl<BasicBlock*> &BBs) const {
80919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Region* ret = getRegionFor(BBs.back());
81019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBs.pop_back();
81119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
81219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (SmallVectorImpl<BasicBlock*>::const_iterator I = BBs.begin(),
81319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       E = BBs.end(); I != E; ++I)
81419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ret = getCommonRegion(ret, getRegionFor(*I));
81519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
81619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return ret;
81719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
81819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
81919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RegionInfo::splitBlock(BasicBlock* NewBB, BasicBlock *OldBB)
82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{
82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Region *R = getRegionFor(OldBB);
82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
82319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  setRegionFor(NewBB, R);
82419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
82519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (R->getEntry() == OldBB && !R->isTopLevelRegion()) {
82619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    R->replaceEntry(NewBB);
82719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    R = R->getParent();
82819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
82919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
83019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  setRegionFor(OldBB, R);
83119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
83219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
83319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanchar RegionInfo::ID = 0;
83419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_BEGIN(RegionInfo, "regions",
83519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                "Detect single entry single exit regions", true, true)
83619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_DEPENDENCY(DominatorTree)
83719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_DEPENDENCY(PostDominatorTree)
83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_DEPENDENCY(DominanceFrontier)
83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_END(RegionInfo, "regions",
84019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                "Detect single entry single exit regions", true, true)
84119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Create methods available outside of this file, to use them
84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
84419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// the link time optimization.
84519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
84619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace llvm {
84719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FunctionPass *createRegionInfoPass() {
84819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return new RegionInfo();
84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
852