[WinEH] Disable most forms of demotion
Now that the register allocator knows about the barriers on funclet
entry and exit, testing has shown that this is unnecessary.
We still demote PHIs on unsplittable blocks due to the differences
between the IR CFG and the Machine CFG.
llvm-svn: 253619
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index 87713f6..f3f4e3b 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -69,8 +69,6 @@
AllocaInst *insertPHILoads(PHINode *PN, Function &F);
void replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
DenseMap<BasicBlock *, Value *> &Loads, Function &F);
- void demoteNonlocalUses(Value *V, SetVector<BasicBlock *> &ColorsForBB,
- Function &F);
bool prepareExplicitEH(Function &F,
SmallVectorImpl<BasicBlock *> &EntryBlocks);
void replaceTerminatePadWithCleanup(Function &F);
@@ -90,8 +88,6 @@
std::map<BasicBlock *, BasicBlock *> &Orig2Clone);
void demotePHIsOnFunclets(Function &F);
- void demoteUsesBetweenFunclets(Function &F);
- void demoteArgumentUses(Function &F);
void cloneCommonBlocks(Function &F,
SmallVectorImpl<BasicBlock *> &EntryBlocks);
void removeImplausibleTerminators(Function &F);
@@ -1588,30 +1584,6 @@
}
}
-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++;
- SetVector<BasicBlock *> &ColorsForBB = BlockColors[BB];
- for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
- Instruction *I = &*BI++;
- // Funclets are permitted to use static allocas.
- if (auto *AI = dyn_cast<AllocaInst>(I))
- if (AI->isStaticAlloca())
- continue;
-
- demoteNonlocalUses(I, ColorsForBB, F);
- }
- }
-}
-
-void WinEHPrepare::demoteArgumentUses(Function &F) {
- // Also demote function parameters used in funclets.
- SetVector<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
@@ -1914,12 +1886,10 @@
report_fatal_error("Uncolored BB!");
if (NumColors > 1)
report_fatal_error("Multicolor BB!");
- if (!DisableDemotion) {
- bool EHPadHasPHI = BB.isEHPad() && isa<PHINode>(BB.begin());
- assert(!EHPadHasPHI && "EH Pad still has a PHI!");
- if (EHPadHasPHI)
- report_fatal_error("EH Pad still has a PHI!");
- }
+ bool EHPadHasPHI = BB.isEHPad() && isa<PHINode>(BB.begin());
+ assert(!EHPadHasPHI && "EH Pad still has a PHI!");
+ if (EHPadHasPHI)
+ report_fatal_error("EH Pad still has a PHI!");
}
}
@@ -1930,14 +1900,9 @@
// Determine which blocks are reachable from which funclet entries.
colorFunclets(F, EntryBlocks);
- if (!DisableDemotion) {
+ if (!DisableDemotion)
demotePHIsOnFunclets(F);
- demoteUsesBetweenFunclets(F);
-
- demoteArgumentUses(F);
- }
-
cloneCommonBlocks(F, EntryBlocks);
resolveFuncletAncestry(F, EntryBlocks);
@@ -2050,83 +2015,6 @@
new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator());
}
-// The SetVector == operator uses the std::vector == operator, so it doesn't
-// actually tell us whether or not the two sets contain the same colors. This
-// function does that.
-// FIXME: Would it be better to add a isSetEquivalent() method to SetVector?
-static bool isBlockColorSetEquivalent(SetVector<BasicBlock *> &SetA,
- SetVector<BasicBlock *> &SetB) {
- if (SetA.size() != SetB.size())
- return false;
- for (auto *Color : SetA)
- if (!SetB.count(Color))
- return false;
- return true;
-}
-
-// TODO: Share loads for same-funclet uses (requires dominators if funclets
-// aren't properly nested).
-void WinEHPrepare::demoteNonlocalUses(Value *V,
- SetVector<BasicBlock *> &ColorsForBB,
- Function &F) {
- // Tokens can only be used non-locally due to control flow involving
- // unreachable edges. Don't try to demote the token usage, we'll simply
- // delete the cloned user later.
- if (isa<CatchPadInst>(V) || isa<CleanupPadInst>(V))
- return;
-
- DenseMap<BasicBlock *, Value *> Loads;
- AllocaInst *SpillSlot = nullptr;
- for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE;) {
- Use &U = *UI++;
- auto *UsingInst = cast<Instruction>(U.getUser());
- BasicBlock *UsingBB = UsingInst->getParent();
-
- // Is the Use inside a block which is colored the same as the Def?
- // If so, we don't need to escape the Def because we will clone
- // ourselves our own private copy.
- SetVector<BasicBlock *> &ColorsForUsingBB = BlockColors[UsingBB];
- if (isBlockColorSetEquivalent(ColorsForUsingBB, ColorsForBB))
- continue;
-
- replaceUseWithLoad(V, U, SpillSlot, Loads, F);
- }
- if (SpillSlot) {
- // Insert stores of the computed value into the stack slot.
- // We have to be careful if I is an invoke instruction,
- // because we can't insert the store AFTER the terminator instruction.
- BasicBlock::iterator InsertPt;
- if (isa<Argument>(V)) {
- InsertPt = F.getEntryBlock().getTerminator()->getIterator();
- } else if (isa<TerminatorInst>(V)) {
- auto *II = cast<InvokeInst>(V);
- // We cannot demote invoke instructions to the stack if their normal
- // edge is critical. Therefore, split the critical edge and create a
- // basic block into which the store can be inserted.
- if (!II->getNormalDest()->getSinglePredecessor()) {
- unsigned SuccNum =
- GetSuccessorNumber(II->getParent(), II->getNormalDest());
- assert(isCriticalEdge(II, SuccNum) && "Expected a critical edge!");
- BasicBlock *NewBlock = SplitCriticalEdge(II, SuccNum);
- assert(NewBlock && "Unable to split critical edge.");
- // Update the color mapping for the newly split edge.
- SetVector<BasicBlock *> &ColorsForUsingBB = BlockColors[II->getParent()];
- BlockColors[NewBlock] = ColorsForUsingBB;
- for (BasicBlock *FuncletPad : ColorsForUsingBB)
- FuncletBlocks[FuncletPad].insert(NewBlock);
- }
- InsertPt = II->getNormalDest()->getFirstInsertionPt();
- } else {
- InsertPt = cast<Instruction>(V)->getIterator();
- ++InsertPt;
- // Don't insert before PHI nodes or EH pad instrs.
- for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt)
- ;
- }
- new StoreInst(V, SpillSlot, &*InsertPt);
- }
-}
-
void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
DenseMap<BasicBlock *, Value *> &Loads,
Function &F) {