183 changes: 183 additions & 0 deletions llvm/include/llvm/CodeGen/MachineRegionInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
//===- llvm/CodeGen/MachineRegionInfo.h -------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_MACHINEREGIONINFO_H
#define LLVM_CODEGEN_MACHINEREGIONINFO_H

#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Analysis/RegionIterator.h"
#include "llvm/CodeGen/MachineDominanceFrontier.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineLoopInfo.h"


namespace llvm {

class MachineDominatorTree;
struct MachinePostDominatorTree;
class MachineRegion;
class MachineRegionNode;
class MachineRegionInfo;

template<>
struct RegionTraits<MachineFunction> {
typedef MachineFunction FuncT;
typedef MachineBasicBlock BlockT;
typedef MachineRegion RegionT;
typedef MachineRegionNode RegionNodeT;
typedef MachineRegionInfo RegionInfoT;
typedef MachineDominatorTree DomTreeT;
typedef MachineDomTreeNode DomTreeNodeT;
typedef MachinePostDominatorTree PostDomTreeT;
typedef MachineDominanceFrontier DomFrontierT;
typedef MachineInstr InstT;
typedef MachineLoop LoopT;
typedef MachineLoopInfo LoopInfoT;

static unsigned getNumSuccessors(MachineBasicBlock *BB) {
return BB->succ_size();
}
};


class MachineRegionNode : public RegionNodeBase<RegionTraits<MachineFunction>> {
public:
inline MachineRegionNode(MachineRegion *Parent,
MachineBasicBlock *Entry,
bool isSubRegion = false)
: RegionNodeBase<RegionTraits<MachineFunction>>(Parent, Entry, isSubRegion) {

}

~MachineRegionNode() { }

bool operator==(const MachineRegion &RN) const {
return this == reinterpret_cast<const MachineRegionNode*>(&RN);
}
};

class MachineRegion : public RegionBase<RegionTraits<MachineFunction>> {
public:
MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
MachineRegionInfo* RI,
MachineDominatorTree *DT, MachineRegion *Parent = nullptr);
~MachineRegion();

bool operator==(const MachineRegionNode &RN) const {
return &RN == reinterpret_cast<const MachineRegionNode*>(this);
}
};

class MachineRegionInfo : public RegionInfoBase<RegionTraits<MachineFunction>> {
public:
explicit MachineRegionInfo();

virtual ~MachineRegionInfo();

// updateStatistics - Update statistic about created regions.
void updateStatistics(MachineRegion *R) final;

void recalculate(MachineFunction &F,
MachineDominatorTree *DT,
MachinePostDominatorTree *PDT,
MachineDominanceFrontier *DF);
};

class MachineRegionInfoPass : public MachineFunctionPass {
MachineRegionInfo RI;

public:
static char ID;
explicit MachineRegionInfoPass();

~MachineRegionInfoPass();

MachineRegionInfo &getRegionInfo() {
return RI;
}

const MachineRegionInfo &getRegionInfo() const {
return RI;
}

/// @name MachineFunctionPass interface
//@{
bool runOnMachineFunction(MachineFunction &F) override;
void releaseMemory() override;
void verifyAnalysis() const override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
void print(raw_ostream &OS, const Module *) const override;
void dump() const;
//@}
};


template <>
template <>
inline MachineBasicBlock* RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineBasicBlock>() const {
assert(!isSubRegion() && "This is not a MachineBasicBlock RegionNode!");
return getEntry();
}

template<>
template<>
inline MachineRegion* RegionNodeBase<RegionTraits<MachineFunction>>::getNodeAs<MachineRegion>() const {
assert(isSubRegion() && "This is not a subregion RegionNode!");
auto Unconst = const_cast<RegionNodeBase<RegionTraits<MachineFunction>>*>(this);
return reinterpret_cast<MachineRegion*>(Unconst);
}


RegionNodeGraphTraits(MachineRegionNode, MachineBasicBlock, MachineRegion);
RegionNodeGraphTraits(const MachineRegionNode, MachineBasicBlock, MachineRegion);

RegionGraphTraits(MachineRegion, MachineRegionNode);
RegionGraphTraits(const MachineRegion, const MachineRegionNode);

template <> struct GraphTraits<MachineRegionInfo*>
: public GraphTraits<FlatIt<MachineRegionNode*> > {
typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
GraphTraits<FlatIt<NodeType*> > > nodes_iterator;

static NodeType *getEntryNode(MachineRegionInfo *RI) {
return GraphTraits<FlatIt<MachineRegion*> >::getEntryNode(RI->getTopLevelRegion());
}
static nodes_iterator nodes_begin(MachineRegionInfo* RI) {
return nodes_iterator::begin(getEntryNode(RI));
}
static nodes_iterator nodes_end(MachineRegionInfo *RI) {
return nodes_iterator::end(getEntryNode(RI));
}
};

template <> struct GraphTraits<MachineRegionInfoPass*>
: public GraphTraits<MachineRegionInfo *> {
typedef df_iterator<NodeType*, SmallPtrSet<NodeType*, 8>, false,
GraphTraits<FlatIt<NodeType*> > > nodes_iterator;

static NodeType *getEntryNode(MachineRegionInfoPass *RI) {
return GraphTraits<MachineRegionInfo*>::getEntryNode(&RI->getRegionInfo());
}
static nodes_iterator nodes_begin(MachineRegionInfoPass* RI) {
return GraphTraits<MachineRegionInfo*>::nodes_begin(&RI->getRegionInfo());
}
static nodes_iterator nodes_end(MachineRegionInfoPass *RI) {
return GraphTraits<MachineRegionInfo*>::nodes_end(&RI->getRegionInfo());
}
};

EXTERN_TEMPLATE_INSTANTIATION(class RegionBase<RegionTraits<MachineFunction>>);
EXTERN_TEMPLATE_INSTANTIATION(class RegionNodeBase<RegionTraits<MachineFunction>>);
EXTERN_TEMPLATE_INSTANTIATION(class RegionInfoBase<RegionTraits<MachineFunction>>);

}

#endif
3 changes: 2 additions & 1 deletion llvm/include/llvm/InitializePasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ void initializeMachinePostDominatorTreePass(PassRegistry&);
void initializeMachineLICMPass(PassRegistry&);
void initializeMachineLoopInfoPass(PassRegistry&);
void initializeMachineModuleInfoPass(PassRegistry&);
void initializeMachineRegionInfoPassPass(PassRegistry&);
void initializeMachineSchedulerPass(PassRegistry&);
void initializeMachineSinkingPass(PassRegistry&);
void initializeMachineTraceMetricsPass(PassRegistry&);
Expand Down Expand Up @@ -227,7 +228,7 @@ void initializePromotePassPass(PassRegistry&);
void initializePruneEHPass(PassRegistry&);
void initializeReassociatePass(PassRegistry&);
void initializeRegToMemPass(PassRegistry&);
void initializeRegionInfoPass(PassRegistry&);
void initializeRegionInfoPassPass(PassRegistry&);
void initializeRegionOnlyPrinterPass(PassRegistry&);
void initializeRegionOnlyViewerPass(PassRegistry&);
void initializeRegionPrinterPass(PassRegistry&);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Analysis/Analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeMemoryDependenceAnalysisPass(Registry);
initializeModuleDebugInfoPrinterPass(Registry);
initializePostDominatorTreePass(Registry);
initializeRegionInfoPass(Registry);
initializeRegionInfoPassPass(Registry);
initializeRegionViewerPass(Registry);
initializeRegionPrinterPass(Registry);
initializeRegionOnlyViewerPass(Registry);
Expand Down
828 changes: 66 additions & 762 deletions llvm/lib/Analysis/RegionInfo.cpp

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions llvm/lib/Analysis/RegionPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ static void addRegionIntoQueue(Region &R, std::deque<Region *> &RQ) {

/// Pass Manager itself does not invalidate any analysis info.
void RGPassManager::getAnalysisUsage(AnalysisUsage &Info) const {
Info.addRequired<RegionInfo>();
Info.addRequired<RegionInfoPass>();
Info.setPreservesAll();
}

/// run - Execute all of the passes scheduled for execution. Keep track of
/// whether any of the passes modifies the function, and if so, return true.
bool RGPassManager::runOnFunction(Function &F) {
RI = &getAnalysis<RegionInfo>();
RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
bool Changed = false;

// Collect inherited analysis from Module level pass manager.
Expand Down
51 changes: 27 additions & 24 deletions llvm/lib/Analysis/RegionPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,24 @@ struct DOTGraphTraits<RegionNode*> : public DefaultDOTGraphTraits {
};

template<>
struct DOTGraphTraits<RegionInfo*> : public DOTGraphTraits<RegionNode*> {
struct DOTGraphTraits<RegionInfoPass*> : public DOTGraphTraits<RegionNode*> {

DOTGraphTraits (bool isSimple=false)
DOTGraphTraits (bool isSimple = false)
: DOTGraphTraits<RegionNode*>(isSimple) {}

static std::string getGraphName(RegionInfo *DT) {
static std::string getGraphName(RegionInfoPass *DT) {
return "Region Graph";
}

std::string getNodeLabel(RegionNode *Node, RegionInfo *G) {
std::string getNodeLabel(RegionNode *Node, RegionInfoPass *G) {
RegionInfo &RI = G->getRegionInfo();
return DOTGraphTraits<RegionNode*>::getNodeLabel(Node,
G->getTopLevelRegion());
reinterpret_cast<RegionNode*>(RI.getTopLevelRegion()));
}

std::string getEdgeAttributes(RegionNode *srcNode,
GraphTraits<RegionInfo*>::ChildIteratorType CI, RegionInfo *RI) {

GraphTraits<RegionInfo*>::ChildIteratorType CI, RegionInfoPass *G) {
RegionInfo &RI = G->getRegionInfo();
RegionNode *destNode = *CI;

if (srcNode->isSubRegion() || destNode->isSubRegion())
Expand All @@ -82,7 +83,7 @@ struct DOTGraphTraits<RegionInfo*> : public DOTGraphTraits<RegionNode*> {
BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();

Region *R = RI->getRegionFor(destBB);
Region *R = RI.getRegionFor(destBB);

while (R && R->getParent())
if (R->getParent()->getEntry() == destBB)
Expand All @@ -98,7 +99,8 @@ struct DOTGraphTraits<RegionInfo*> : public DOTGraphTraits<RegionNode*> {

// Print the cluster of the subregions. This groups the single basic blocks
// and adds a different background color for each group.
static void printRegionCluster(const Region &R, GraphWriter<RegionInfo*> &GW,
static void printRegionCluster(const Region &R,
GraphWriter<RegionInfoPass*> &GW,
unsigned depth = 0) {
raw_ostream &O = GW.getOStream();
O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(&R)
Expand All @@ -119,51 +121,52 @@ struct DOTGraphTraits<RegionInfo*> : public DOTGraphTraits<RegionNode*> {
for (Region::const_iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI)
printRegionCluster(**RI, GW, depth + 1);

RegionInfo *RI = R.getRegionInfo();
const RegionInfo &RI = *static_cast<const RegionInfo*>(R.getRegionInfo());

for (const auto &BB : R.blocks())
if (RI->getRegionFor(BB) == &R)
if (RI.getRegionFor(BB) == &R)
O.indent(2 * (depth + 1)) << "Node"
<< static_cast<const void*>(RI->getTopLevelRegion()->getBBNode(BB))
<< static_cast<const void*>(RI.getTopLevelRegion()->getBBNode(BB))
<< ";\n";

O.indent(2 * depth) << "}\n";
}

static void addCustomGraphFeatures(const RegionInfo* RI,
GraphWriter<RegionInfo*> &GW) {
static void addCustomGraphFeatures(const RegionInfoPass* RIP,
GraphWriter<RegionInfoPass*> &GW) {
const RegionInfo &RI = RIP->getRegionInfo();
raw_ostream &O = GW.getOStream();
O << "\tcolorscheme = \"paired12\"\n";
printRegionCluster(*RI->getTopLevelRegion(), GW, 4);
printRegionCluster(*RI.getTopLevelRegion(), GW, 4);
}
};
} //end namespace llvm

namespace {

struct RegionViewer
: public DOTGraphTraitsViewer<RegionInfo, false> {
: public DOTGraphTraitsViewer<RegionInfoPass, false> {
static char ID;
RegionViewer() : DOTGraphTraitsViewer<RegionInfo, false>("reg", ID){
RegionViewer() : DOTGraphTraitsViewer<RegionInfoPass, false>("reg", ID){
initializeRegionViewerPass(*PassRegistry::getPassRegistry());
}
};
char RegionViewer::ID = 0;

struct RegionOnlyViewer
: public DOTGraphTraitsViewer<RegionInfo, true> {
: public DOTGraphTraitsViewer<RegionInfoPass, true> {
static char ID;
RegionOnlyViewer() : DOTGraphTraitsViewer<RegionInfo, true>("regonly", ID) {
RegionOnlyViewer() : DOTGraphTraitsViewer<RegionInfoPass, true>("regonly", ID) {
initializeRegionOnlyViewerPass(*PassRegistry::getPassRegistry());
}
};
char RegionOnlyViewer::ID = 0;

struct RegionPrinter
: public DOTGraphTraitsPrinter<RegionInfo, false> {
: public DOTGraphTraitsPrinter<RegionInfoPass, false> {
static char ID;
RegionPrinter() :
DOTGraphTraitsPrinter<RegionInfo, false>("reg", ID) {
DOTGraphTraitsPrinter<RegionInfoPass, false>("reg", ID) {
initializeRegionPrinterPass(*PassRegistry::getPassRegistry());
}
};
Expand All @@ -175,18 +178,18 @@ INITIALIZE_PASS(RegionPrinter, "dot-regions",

INITIALIZE_PASS(RegionViewer, "view-regions", "View regions of function",
true, true)

INITIALIZE_PASS(RegionOnlyViewer, "view-regions-only",
"View regions of function (with no function bodies)",
true, true)

namespace {

struct RegionOnlyPrinter
: public DOTGraphTraitsPrinter<RegionInfo, true> {
: public DOTGraphTraitsPrinter<RegionInfoPass, true> {
static char ID;
RegionOnlyPrinter() :
DOTGraphTraitsPrinter<RegionInfo, true>("reg", ID) {
DOTGraphTraitsPrinter<RegionInfoPass, true>("reg", ID) {
initializeRegionOnlyPrinterPass(*PassRegistry::getPassRegistry());
}
};
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ add_llvm_library(LLVMCodeGen
MachinePassRegistry.cpp
MachinePostDominators.cpp
MachineRegisterInfo.cpp
MachineRegionInfo.cpp
MachineSSAUpdater.cpp
MachineScheduler.cpp
MachineSink.cpp
Expand Down
137 changes: 137 additions & 0 deletions llvm/lib/CodeGen/MachineRegionInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@

#include "llvm/CodeGen/MachineRegionInfo.h"
#include "llvm/CodeGen/MachinePostDominators.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/RegionInfoImpl.h"

using namespace llvm;

STATISTIC(numMachineRegions, "The # of machine regions");
STATISTIC(numMachineSimpleRegions, "The # of simple machine regions");

namespace llvm {
template class RegionBase<RegionTraits<MachineFunction>>;
template class RegionNodeBase<RegionTraits<MachineFunction>>;
template class RegionInfoBase<RegionTraits<MachineFunction>>;
}

//===----------------------------------------------------------------------===//
// MachineRegion implementation
//

MachineRegion::MachineRegion(MachineBasicBlock *Entry, MachineBasicBlock *Exit,
MachineRegionInfo* RI,
MachineDominatorTree *DT, MachineRegion *Parent) :
RegionBase<RegionTraits<MachineFunction>>(Entry, Exit, RI, DT, Parent) {

}

MachineRegion::~MachineRegion() { }

//===----------------------------------------------------------------------===//
// MachineRegionInfo implementation
//

MachineRegionInfo::MachineRegionInfo() :
RegionInfoBase<RegionTraits<MachineFunction>>() {

}

MachineRegionInfo::~MachineRegionInfo() {

}

void MachineRegionInfo::updateStatistics(MachineRegion *R) {
++numMachineRegions;

// TODO: Slow. Should only be enabled if -stats is used.
if (R->isSimple())
++numMachineSimpleRegions;
}

void MachineRegionInfo::MachineRegionInfo::recalculate(
MachineFunction &F,
MachineDominatorTree *DT_,
MachinePostDominatorTree *PDT_,
MachineDominanceFrontier *DF_) {
DT = DT_;
PDT = PDT_;
DF = DF_;

MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&F);

TopLevelRegion = new MachineRegion(Entry, nullptr, this, DT, nullptr);
updateStatistics(TopLevelRegion);
calculate(F);
}

//===----------------------------------------------------------------------===//
// MachineRegionInfoPass implementation
//

MachineRegionInfoPass::MachineRegionInfoPass() : MachineFunctionPass(ID) {
initializeMachineRegionInfoPassPass(*PassRegistry::getPassRegistry());
}

MachineRegionInfoPass::~MachineRegionInfoPass() {

}

bool MachineRegionInfoPass::runOnMachineFunction(MachineFunction &F) {
releaseMemory();

auto DT = &getAnalysis<MachineDominatorTree>();
auto PDT = &getAnalysis<MachinePostDominatorTree>();
auto DF = &getAnalysis<MachineDominanceFrontier>();

RI.recalculate(F, DT, PDT, DF);
return false;
}

void MachineRegionInfoPass::releaseMemory() {
RI.releaseMemory();
}

void MachineRegionInfoPass::verifyAnalysis() const {
// Only do verification when user wants to, otherwise this expensive check
// will be invoked by PMDataManager::verifyPreservedAnalysis when
// a regionpass (marked PreservedAll) finish.
if (MachineRegionInfo::VerifyRegionInfo)
RI.verifyAnalysis();
}

void MachineRegionInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequiredTransitive<DominatorTreeWrapperPass>();
AU.addRequired<PostDominatorTree>();
AU.addRequired<DominanceFrontier>();
}

void MachineRegionInfoPass::print(raw_ostream &OS, const Module *) const {
RI.print(OS);
}

void MachineRegionInfoPass::dump() const {
RI.dump();
}

char MachineRegionInfoPass::ID = 0;

INITIALIZE_PASS_BEGIN(MachineRegionInfoPass, "regions",
"Detect single entry single exit regions", true, true)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
INITIALIZE_PASS_END(MachineRegionInfoPass, "regions",
"Detect single entry single exit regions", true, true)

// Create methods available outside of this file, to use them
// "include/llvm/LinkAllPasses.h". Otherwise the pass would be deleted by
// the link time optimization.

namespace llvm {
FunctionPass *createMachineRegionInfoPass() {
return new MachineRegionInfoPass();
}
}

6 changes: 3 additions & 3 deletions llvm/lib/Transforms/Scalar/StructurizeCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ INITIALIZE_PASS_BEGIN(StructurizeCFG, "structurizecfg", "Structurize the CFG",
false, false)
INITIALIZE_PASS_DEPENDENCY(LowerSwitch)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(RegionInfo)
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
INITIALIZE_PASS_END(StructurizeCFG, "structurizecfg", "Structurize the CFG",
false, false)

Expand Down Expand Up @@ -406,11 +406,11 @@ void StructurizeCFG::gatherPredicates(RegionNode *N) {
} else {

// It's an exit from a sub region
while(R->getParent() != ParentRegion)
while (R->getParent() != ParentRegion)
R = R->getParent();

// Edge from inside a subregion to its entry, ignore it
if (R == N)
if (*R == *N)
continue;

BasicBlock *Entry = R->getEntry();
Expand Down