From: David Majnemer Date: Wed, 16 Sep 2015 18:40:24 +0000 (+0000) Subject: [WinEHPrepare] Refactor explicit EH preparation X-Git-Tag: android-x86-7.1-r4~43522 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=6badbab39a30eb1529541a96f9e1d1b526c10199;p=android-x86%2Fexternal-llvm.git [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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247834 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/WinEHPrepare.cpp b/lib/CodeGen/WinEHPrepare.cpp index bbf61a14bf1..044cbe0df20 100644 --- a/lib/CodeGen/WinEHPrepare.cpp +++ b/lib/CodeGen/WinEHPrepare.cpp @@ -133,6 +133,14 @@ private: bool prepareExplicitEH(Function &F, SmallVectorImpl &EntryBlocks); void colorFunclets(Function &F, SmallVectorImpl &EntryBlocks); + void demotePHIsOnFunclets(Function &F); + void demoteUsesBetweenFunclets(Function &F); + void demoteArgumentUses(Function &F); + void cloneCommonBlocks(Function &F, + SmallVectorImpl &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 &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 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 &ColorsForEntry = BlockColors[&F.getEntryBlock()]; for (Argument &Arg : F.args()) demoteNonlocalUses(&Arg, ColorsForEntry, F); +} +void WinEHPrepare::cloneCommonBlocks( + Function &F, SmallVectorImpl &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 &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();