+
+// TODO: Share loads when one use dominates another, or when a catchpad exit
+// dominates uses (needs dominators).
+AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) {
+ BasicBlock *PHIBlock = PN->getParent();
+ AllocaInst *SpillSlot = nullptr;
+
+ if (isa<CleanupPadInst>(PHIBlock->getFirstNonPHI())) {
+ // Insert a load in place of the PHI and replace all uses.
+ SpillSlot = new AllocaInst(PN->getType(), nullptr,
+ Twine(PN->getName(), ".wineh.spillslot"),
+ F.getEntryBlock().begin());
+ Value *V = new LoadInst(SpillSlot, Twine(PN->getName(), ".wineh.reload"),
+ PHIBlock->getFirstInsertionPt());
+ PN->replaceAllUsesWith(V);
+ return SpillSlot;
+ }
+
+ DenseMap<BasicBlock *, Value *> Loads;
+ for (Value::use_iterator UI = PN->use_begin(), UE = PN->use_end();
+ UI != UE;) {
+ Use &U = *UI++;
+ auto *UsingInst = cast<Instruction>(U.getUser());
+ BasicBlock *UsingBB = UsingInst->getParent();
+ if (UsingBB->isEHPad()) {
+ // Use is on an EH pad phi. Leave it alone; we'll insert loads and
+ // stores for it separately.
+ assert(isa<PHINode>(UsingInst));
+ continue;
+ }
+ replaceUseWithLoad(PN, U, SpillSlot, Loads, F);
+ }
+ return SpillSlot;
+}
+
+// TODO: improve store placement. Inserting at def is probably good, but need
+// to be careful not to introduce interfering stores (needs liveness analysis).
+// TODO: identify related phi nodes that can share spill slots, and share them
+// (also needs liveness).
+void WinEHPrepare::insertPHIStores(PHINode *OriginalPHI,
+ AllocaInst *SpillSlot) {
+ // Use a worklist of (Block, Value) pairs -- the given Value needs to be
+ // stored to the spill slot by the end of the given Block.
+ SmallVector<std::pair<BasicBlock *, Value *>, 4> Worklist;
+
+ Worklist.push_back({OriginalPHI->getParent(), OriginalPHI});
+
+ while (!Worklist.empty()) {
+ BasicBlock *EHBlock;
+ Value *InVal;
+ std::tie(EHBlock, InVal) = Worklist.pop_back_val();
+
+ PHINode *PN = dyn_cast<PHINode>(InVal);
+ if (PN && PN->getParent() == EHBlock) {
+ // The value is defined by another PHI we need to remove, with no room to
+ // insert a store after the PHI, so each predecessor needs to store its
+ // incoming value.
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
+ Value *PredVal = PN->getIncomingValue(i);
+
+ // Undef can safely be skipped.
+ if (isa<UndefValue>(PredVal))
+ continue;
+
+ insertPHIStore(PN->getIncomingBlock(i), PredVal, SpillSlot, Worklist);
+ }
+ } else {
+ // We need to store InVal, which dominates EHBlock, but can't put a store
+ // in EHBlock, so need to put stores in each predecessor.
+ for (BasicBlock *PredBlock : predecessors(EHBlock)) {
+ insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
+ }
+ }
+ }
+}
+
+void WinEHPrepare::insertPHIStore(
+ BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
+ SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist) {
+
+ if (PredBlock->isEHPad() &&
+ !isa<CleanupPadInst>(PredBlock->getFirstNonPHI())) {
+ // Pred is unsplittable, so we need to queue it on the worklist.
+ Worklist.push_back({PredBlock, PredVal});
+ return;
+ }
+
+ // Otherwise, insert the store at the end of the basic block.
+ new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator());
+}
+
+// TODO: Share loads for same-funclet uses (requires dominators if funclets
+// aren't properly nested).
+void WinEHPrepare::demoteNonlocalUses(Value *V,
+ std::set<BasicBlock *> &ColorsForBB,
+ Function &F) {
+ 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 with a subset of the Def?
+ // If so, we don't need to escape the Def because we will clone
+ // ourselves our own private copy.
+ std::set<BasicBlock *> &ColorsForUsingBB = BlockColors[UsingBB];
+ if (std::includes(ColorsForBB.begin(), ColorsForBB.end(),
+ ColorsForUsingBB.begin(), ColorsForUsingBB.end()))
+ 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();
+ } 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.
+ std::set<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);
+ ++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) {
+ // Lazilly create the spill slot.
+ if (!SpillSlot)
+ SpillSlot = new AllocaInst(V->getType(), nullptr,
+ Twine(V->getName(), ".wineh.spillslot"),
+ F.getEntryBlock().begin());
+
+ auto *UsingInst = cast<Instruction>(U.getUser());
+ if (auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
+ // If this is a PHI node, we can't insert a load of the value before
+ // the use. Instead insert the load in the predecessor block
+ // corresponding to the incoming value.
+ //
+ // Note that if there are multiple edges from a basic block to this
+ // PHI node that we cannot have multiple loads. The problem is that
+ // the resulting PHI node will have multiple values (from each load)
+ // coming in from the same block, which is illegal SSA form.
+ // For this reason, we keep track of and reuse loads we insert.
+ BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
+ Value *&Load = Loads[IncomingBlock];
+ // Insert the load into the predecessor block
+ if (!Load)
+ Load = new LoadInst(SpillSlot, Twine(V->getName(), ".wineh.reload"),
+ /*Volatile=*/false, IncomingBlock->getTerminator());
+
+ U.set(Load);
+ } else {
+ // Reload right before the old use.
+ auto *Load = new LoadInst(SpillSlot, Twine(V->getName(), ".wineh.reload"),
+ /*Volatile=*/false, UsingInst);
+ U.set(Load);
+ }
+}