forked from OSchip/llvm-project
223 lines
6.8 KiB
C++
223 lines
6.8 KiB
C++
//===- RegionSimplify.cpp -------------------------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file converts refined regions detected by the RegionInfo analysis
|
|
// into simple regions.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "polly/LinkAllPasses.h"
|
|
|
|
#include "llvm/Instructions.h"
|
|
#include "llvm/ADT/Statistic.h"
|
|
#include "llvm/Analysis/AliasAnalysis.h"
|
|
#include "llvm/Analysis/Dominators.h"
|
|
#include "llvm/Analysis/LoopInfo.h"
|
|
#include "llvm/Analysis/RegionPass.h"
|
|
#include "llvm/Analysis/RegionInfo.h"
|
|
#include "llvm/Transforms/Scalar.h"
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
|
|
|
#define DEBUG_TYPE "region-simplify"
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
using namespace llvm;
|
|
|
|
STATISTIC(NumEntries, "The # of created entry edges");
|
|
STATISTIC(NumExits, "The # of created exit edges");
|
|
|
|
namespace {
|
|
class RegionSimplify: public RegionPass {
|
|
// Remember the modified region.
|
|
Region *r;
|
|
void createSingleEntryEdge(Region *R);
|
|
void createSingleExitEdge(Region *R);
|
|
public:
|
|
static char ID;
|
|
explicit RegionSimplify() : RegionPass(ID), r(0) {}
|
|
|
|
virtual void print(raw_ostream &O, const Module *M) const;
|
|
|
|
virtual bool runOnRegion(Region *R, RGPassManager &RGM);
|
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
|
};
|
|
}
|
|
|
|
char RegionSimplify::ID = 0;
|
|
|
|
INITIALIZE_PASS_BEGIN(RegionSimplify, "polly-region-simplify",
|
|
"Transform refined regions into simple regions", false,
|
|
false)
|
|
INITIALIZE_PASS_DEPENDENCY(RegionInfo)
|
|
INITIALIZE_PASS_END(RegionSimplify, "polly-region-simplify",
|
|
"Transform refined regions into simple regions", false,
|
|
false)
|
|
namespace polly {
|
|
Pass *createRegionSimplifyPass() {
|
|
return new RegionSimplify();
|
|
}
|
|
}
|
|
|
|
void RegionSimplify::print(raw_ostream &O, const Module *M) const {
|
|
if (r == 0) return;
|
|
|
|
BasicBlock *enteringBlock = r->getEnteringBlock();
|
|
BasicBlock *exitingBlock = r->getExitingBlock();
|
|
|
|
O << "Region: " << r->getNameStr() << " Edges:\t";
|
|
|
|
if (enteringBlock)
|
|
O << "Entering: [" << enteringBlock->getName() << " -> "
|
|
<< r->getEntry()->getName() << "], ";
|
|
|
|
if (exitingBlock) {
|
|
O << "Exiting: [" << exitingBlock->getName() << " -> ";
|
|
if (r->getExit())
|
|
O << r->getExit()->getName();
|
|
else
|
|
O << "<return>";
|
|
O << "]";
|
|
}
|
|
|
|
O << "\n";
|
|
}
|
|
|
|
void RegionSimplify::getAnalysisUsage(AnalysisUsage &AU) const {
|
|
// Function SplitBlockPredecessors currently updates/preserves AliasAnalysis,
|
|
/// DominatorTree, LoopInfo, and LCCSA but no other analyses.
|
|
//AU.addPreserved<AliasAnalysis>(); Break SCEV-AA
|
|
AU.addPreserved<DominatorTree> ();
|
|
AU.addPreserved<LoopInfo>();
|
|
AU.addPreservedID(LCSSAID);
|
|
|
|
AU.addPreserved<RegionInfo> ();
|
|
AU.addRequired<RegionInfo> ();
|
|
}
|
|
|
|
// createSingleEntryEdge - Split the entry basic block of the given
|
|
// region after the last PHINode to form a single entry edge.
|
|
void RegionSimplify::createSingleEntryEdge(Region *R) {
|
|
BasicBlock *oldEntry = R->getEntry();
|
|
SmallVector<BasicBlock*, 4> Preds;
|
|
for (pred_iterator PI = pred_begin(oldEntry), PE = pred_end(oldEntry);
|
|
PI != PE; ++PI)
|
|
if (!R->contains(*PI))
|
|
Preds.push_back(*PI);
|
|
|
|
assert(Preds.size() && "This region has already a single entry edge");
|
|
|
|
BasicBlock *newEntry = SplitBlockPredecessors(oldEntry, Preds,
|
|
".single_entry", this);
|
|
|
|
RegionInfo *RI = &getAnalysis<RegionInfo> ();
|
|
// We do not update entry node for children of this region.
|
|
// This make it easier to extract children regions because they do not share
|
|
// the entry node with their parents.
|
|
// all parent regions whose entry is oldEntry are updated with newEntry
|
|
Region *r = R->getParent();
|
|
|
|
// Put the new entry to R's parent.
|
|
RI->setRegionFor(newEntry,r);
|
|
|
|
while (r->getEntry() == oldEntry && !r->isTopLevelRegion()) {
|
|
r->replaceEntry(newEntry);
|
|
r = r->getParent();
|
|
}
|
|
|
|
// We do not update exit node for children of this region for the same reason
|
|
// of not updating entry node.
|
|
// All other regions whose exit is oldEntry are updated with new exit node
|
|
r = RI->getTopLevelRegion();
|
|
std::vector<Region *> RQ;
|
|
RQ.push_back(r);
|
|
|
|
while (!RQ.empty()){
|
|
r = RQ.back();
|
|
RQ.pop_back();
|
|
|
|
for (Region::const_iterator RI = r->begin(), RE = r->end(); RI!=RE; ++RI)
|
|
RQ.push_back(*RI);
|
|
|
|
if (r->getExit() == oldEntry && !R->contains(r))
|
|
r->replaceExit(newEntry);
|
|
}
|
|
|
|
}
|
|
|
|
// createSingleExitEdge - Split the exit basic of the given region
|
|
// to form a single exit edge.
|
|
void RegionSimplify::createSingleExitEdge(Region *R) {
|
|
BasicBlock *oldExit = R->getExit();
|
|
|
|
SmallVector<BasicBlock*, 4> Preds;
|
|
for (pred_iterator PI = pred_begin(oldExit), PE = pred_end(oldExit);
|
|
PI != PE; ++PI)
|
|
if (R->contains(*PI))
|
|
Preds.push_back(*PI);
|
|
|
|
DEBUG(dbgs() << "Going to create single exit for:\n");
|
|
DEBUG(R->print(dbgs(), true, 0, Region::PrintRN));
|
|
BasicBlock *newExit = SplitBlockPredecessors(oldExit, Preds,
|
|
".single_exit", this);
|
|
RegionInfo *RI = &getAnalysis<RegionInfo>();
|
|
|
|
// We do not need to update entry nodes because this split happens inside
|
|
// this region and it affects only this region and all of its children.
|
|
// The new split node belongs to this region
|
|
RI->setRegionFor(newExit,R);
|
|
DEBUG(dbgs() << "Adding new exiting block: " << newExit->getName() << '\n');
|
|
|
|
// all children of this region whose exit is oldExit is changed to newExit
|
|
std::vector<Region *> RQ;
|
|
for (Region::const_iterator RI = R->begin(), RE = R->end(); RI!=RE; ++RI)
|
|
RQ.push_back(*RI);
|
|
|
|
while (!RQ.empty()){
|
|
R = RQ.back();
|
|
RQ.pop_back();
|
|
|
|
if (R->getExit() != oldExit)
|
|
continue;
|
|
|
|
for (Region::const_iterator RI = R->begin(), RE = R->end(); RI!=RE; ++RI)
|
|
RQ.push_back(*RI);
|
|
|
|
R->replaceExit(newExit);
|
|
DEBUG(dbgs() << "Replacing exit for:\n");
|
|
DEBUG(R->print(dbgs(), true, 0, Region::PrintRN));
|
|
}
|
|
|
|
DEBUG(dbgs() << "After split exit:\n");
|
|
DEBUG(R->print(dbgs(), true, 0, Region::PrintRN));
|
|
}
|
|
|
|
bool RegionSimplify::runOnRegion(Region *R, RGPassManager &RGM) {
|
|
r = 0;
|
|
|
|
if (!R->isTopLevelRegion()) {
|
|
|
|
// split entry node if the region has multiple entry edges
|
|
if (!(R->getEnteringBlock())
|
|
&& (pred_begin(R->getEntry()) != pred_end(R->getEntry()))) {
|
|
createSingleEntryEdge(R);
|
|
r = R;
|
|
++NumEntries;
|
|
}
|
|
|
|
// split exit node if the region has multiple exit edges
|
|
if (!(R->getExitingBlock())) {
|
|
createSingleExitEdge(R);
|
|
r = R;
|
|
++NumExits;
|
|
}
|
|
}
|
|
|
|
return r != 0;
|
|
}
|