summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-09-16 18:40:24 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-09-16 18:40:24 +0000
commitb3d9b960ea1e675f2cc2a9d9e7ea3ad43020de86 (patch)
tree5029e9b4a05e7f835d1f9d5cc65ad832b0270acc /llvm/lib/CodeGen
parent672311b368d16a589c93ca0cc85580b976ed284d (diff)
downloadbcm5719-llvm-b3d9b960ea1e675f2cc2a9d9e7ea3ad43020de86.tar.gz
bcm5719-llvm-b3d9b960ea1e675f2cc2a9d9e7ea3ad43020de86.zip
[WinEHPrepare] Refactor explicit EH preparation
Split the preparation machinery into several functions, we will want to selectively enable/disable different parts of it for an alternative mechanism for dealing with cross-funclet uses. llvm-svn: 247834
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/WinEHPrepare.cpp58
1 files changed, 48 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index bbf61a14bf1..044cbe0df20 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -133,6 +133,14 @@ private:
bool prepareExplicitEH(Function &F,
SmallVectorImpl<BasicBlock *> &EntryBlocks);
void colorFunclets(Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks);
+ void demotePHIsOnFunclets(Function &F);
+ void demoteUsesBetweenFunclets(Function &F);
+ void demoteArgumentUses(Function &F);
+ void cloneCommonBlocks(Function &F,
+ SmallVectorImpl<BasicBlock *> &EntryBlocks);
+ void removeImplausibleTerminators(Function &F);
+ void cleanupPreparedFunclets(Function &F);
+ void verifyPreparedFunclets(Function &F);
Triple TheTriple;
@@ -3288,16 +3296,7 @@ void WinEHPrepare::colorFunclets(Function &F,
}
}
-bool WinEHPrepare::prepareExplicitEH(
- Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks) {
- // Remove unreachable blocks. It is not valuable to assign them a color and
- // their existence can trick us into thinking values are alive when they are
- // not.
- removeUnreachableBlocks(F);
-
- // Determine which blocks are reachable from which funclet entries.
- colorFunclets(F, EntryBlocks);
-
+void WinEHPrepare::demotePHIsOnFunclets(Function &F) {
// Strip PHI nodes off of EH pads.
SmallVector<PHINode *, 16> PHINodes;
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
@@ -3324,7 +3323,9 @@ bool WinEHPrepare::prepareExplicitEH(
PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
PN->eraseFromParent();
}
+}
+void WinEHPrepare::demoteUsesBetweenFunclets(Function &F) {
// Turn all inter-funclet uses of a Value into loads and stores.
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
BasicBlock *BB = FI++;
@@ -3339,11 +3340,17 @@ bool WinEHPrepare::prepareExplicitEH(
demoteNonlocalUses(I, ColorsForBB, F);
}
}
+}
+
+void WinEHPrepare::demoteArgumentUses(Function &F) {
// Also demote function parameters used in funclets.
std::set<BasicBlock *> &ColorsForEntry = BlockColors[&F.getEntryBlock()];
for (Argument &Arg : F.args())
demoteNonlocalUses(&Arg, ColorsForEntry, F);
+}
+void WinEHPrepare::cloneCommonBlocks(
+ Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks) {
// We need to clone all blocks which belong to multiple funclets. Values are
// remapped throughout the funclet to propogate both the new instructions
// *and* the new basic blocks themselves.
@@ -3393,7 +3400,9 @@ bool WinEHPrepare::prepareExplicitEH(
for (Instruction &I : *BB)
RemapInstruction(&I, VMap, RF_IgnoreMissingEntries);
}
+}
+void WinEHPrepare::removeImplausibleTerminators(Function &F) {
// Remove implausible terminators and replace them with UnreachableInst.
for (auto &Funclet : FuncletBlocks) {
BasicBlock *FuncletPadBB = Funclet.first;
@@ -3425,7 +3434,9 @@ bool WinEHPrepare::prepareExplicitEH(
}
}
}
+}
+void WinEHPrepare::cleanupPreparedFunclets(Function &F) {
// Clean-up some of the mess we made by removing useles PHI nodes, trivial
// branches, etc.
for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
@@ -3438,7 +3449,9 @@ bool WinEHPrepare::prepareExplicitEH(
// We might have some unreachable blocks after cleaning up some impossible
// control flow.
removeUnreachableBlocks(F);
+}
+void WinEHPrepare::verifyPreparedFunclets(Function &F) {
// Recolor the CFG to verify that all is well.
for (BasicBlock &BB : F) {
size_t NumColors = BlockColors[&BB].size();
@@ -3452,6 +3465,31 @@ bool WinEHPrepare::prepareExplicitEH(
if (EHPadHasPHI)
report_fatal_error("EH Pad still has a PHI!");
}
+}
+
+bool WinEHPrepare::prepareExplicitEH(
+ Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks) {
+ // Remove unreachable blocks. It is not valuable to assign them a color and
+ // their existence can trick us into thinking values are alive when they are
+ // not.
+ removeUnreachableBlocks(F);
+
+ // Determine which blocks are reachable from which funclet entries.
+ colorFunclets(F, EntryBlocks);
+
+ demotePHIsOnFunclets(F);
+
+ demoteUsesBetweenFunclets(F);
+
+ demoteArgumentUses(F);
+
+ cloneCommonBlocks(F, EntryBlocks);
+
+ removeImplausibleTerminators(F);
+
+ cleanupPreparedFunclets(F);
+
+ verifyPreparedFunclets(F);
BlockColors.clear();
FuncletBlocks.clear();
OpenPOWER on IntegriCloud