blob: 957064891d7189d44dc35a9e8e801b86bce11618 [file] [log] [blame]
Andrew Kaylor1476e6d2015-02-24 20:49:35 +00001//===-- WinEHPrepare - Prepare exception handling for code generation ---===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This pass lowers LLVM IR exception handling into something closer to what the
Reid Kleckner0738a9c2015-05-05 17:44:16 +000011// backend wants for functions using a personality function from a runtime
12// provided by MSVC. Functions with other personality functions are left alone
13// and may be prepared by other passes. In particular, all supported MSVC
14// personality functions require cleanup code to be outlined, and the C++
15// personality requires catch handler code to be outlined.
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000016//
17//===----------------------------------------------------------------------===//
18
19#include "llvm/CodeGen/Passes.h"
David Majnemerfd9f4772015-08-11 01:15:26 +000020#include "llvm/Analysis/CFG.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000021#include "llvm/Analysis/LibCallSemantics.h"
David Majnemercde33032015-03-30 22:58:10 +000022#include "llvm/CodeGen/WinEHFuncInfo.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000023#include "llvm/Pass.h"
Andrew Kaylor6b67d422015-03-11 23:22:06 +000024#include "llvm/Support/Debug.h"
Benjamin Kramera8d61b12015-03-23 18:57:17 +000025#include "llvm/Support/raw_ostream.h"
Andrew Kaylor6b67d422015-03-11 23:22:06 +000026#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000027#include "llvm/Transforms/Utils/Cloning.h"
28#include "llvm/Transforms/Utils/Local.h"
David Majnemer459a64a2015-09-16 18:40:37 +000029#include "llvm/Transforms/Utils/SSAUpdater.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000030
31using namespace llvm;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000032
33#define DEBUG_TYPE "winehprepare"
34
David Majnemer459a64a2015-09-16 18:40:37 +000035static cl::opt<bool> DisableDemotion(
36 "disable-demotion", cl::Hidden,
37 cl::desc(
38 "Clone multicolor basic blocks but do not demote cross funclet values"),
39 cl::init(false));
40
41static cl::opt<bool> DisableCleanups(
42 "disable-cleanups", cl::Hidden,
43 cl::desc("Do not remove implausible terminators or other similar cleanups"),
44 cl::init(false));
45
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000046namespace {
47
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000048class WinEHPrepare : public FunctionPass {
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000049public:
50 static char ID; // Pass identification, replacement for typeid.
David Majnemere6965832015-10-16 19:59:52 +000051 WinEHPrepare(const TargetMachine *TM = nullptr) : FunctionPass(ID) {}
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000052
53 bool runOnFunction(Function &Fn) override;
54
55 bool doFinalization(Module &M) override;
56
57 void getAnalysisUsage(AnalysisUsage &AU) const override;
58
59 const char *getPassName() const override {
60 return "Windows exception handling preparation";
61 }
62
63private:
Joseph Tremouletc9ff9142015-08-13 14:30:10 +000064 void insertPHIStores(PHINode *OriginalPHI, AllocaInst *SpillSlot);
65 void
66 insertPHIStore(BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
67 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist);
68 AllocaInst *insertPHILoads(PHINode *PN, Function &F);
69 void replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
70 DenseMap<BasicBlock *, Value *> &Loads, Function &F);
71 void demoteNonlocalUses(Value *V, std::set<BasicBlock *> &ColorsForBB,
72 Function &F);
Joseph Tremouletec182852015-08-28 01:12:35 +000073 bool prepareExplicitEH(Function &F,
74 SmallVectorImpl<BasicBlock *> &EntryBlocks);
David Majnemer67bff0d2015-09-16 20:42:16 +000075 void replaceTerminatePadWithCleanup(Function &F);
Joseph Tremouletec182852015-08-28 01:12:35 +000076 void colorFunclets(Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks);
David Majnemerb3d9b962015-09-16 18:40:24 +000077 void demotePHIsOnFunclets(Function &F);
78 void demoteUsesBetweenFunclets(Function &F);
79 void demoteArgumentUses(Function &F);
80 void cloneCommonBlocks(Function &F,
81 SmallVectorImpl<BasicBlock *> &EntryBlocks);
82 void removeImplausibleTerminators(Function &F);
83 void cleanupPreparedFunclets(Function &F);
84 void verifyPreparedFunclets(Function &F);
David Majnemerfd9f4772015-08-11 01:15:26 +000085
Reid Kleckner0f9e27a2015-03-18 20:26:53 +000086 // All fields are reset by runOnFunction.
Reid Kleckner582786b2015-04-30 18:17:12 +000087 EHPersonality Personality = EHPersonality::Unknown;
David Majnemerfd9f4772015-08-11 01:15:26 +000088
89 std::map<BasicBlock *, std::set<BasicBlock *>> BlockColors;
90 std::map<BasicBlock *, std::set<BasicBlock *>> FuncletBlocks;
Joseph Tremouletec182852015-08-28 01:12:35 +000091 std::map<BasicBlock *, std::set<BasicBlock *>> FuncletChildren;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000092};
93
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000094} // end anonymous namespace
95
96char WinEHPrepare::ID = 0;
Reid Kleckner47c8e7a2015-03-12 00:36:20 +000097INITIALIZE_TM_PASS(WinEHPrepare, "winehprepare", "Prepare Windows exceptions",
98 false, false)
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000099
100FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
101 return new WinEHPrepare(TM);
102}
103
Reid Kleckner14e77352015-10-09 23:34:53 +0000104static void findFuncletEntryPoints(Function &Fn,
105 SmallVectorImpl<BasicBlock *> &EntryBlocks) {
106 EntryBlocks.push_back(&Fn.getEntryBlock());
David Majnemerf828a0c2015-10-01 18:44:59 +0000107 for (BasicBlock &BB : Fn) {
108 Instruction *First = BB.getFirstNonPHI();
Reid Kleckner14e77352015-10-09 23:34:53 +0000109 if (!First->isEHPad())
110 continue;
111 assert(!isa<LandingPadInst>(First) &&
112 "landingpad cannot be used with funclet EH personality");
113 // Find EH pad blocks that represent funclet start points.
114 if (!isa<CatchEndPadInst>(First) && !isa<CleanupEndPadInst>(First))
115 EntryBlocks.push_back(&BB);
David Majnemerf828a0c2015-10-01 18:44:59 +0000116 }
David Majnemerf828a0c2015-10-01 18:44:59 +0000117}
118
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000119bool WinEHPrepare::runOnFunction(Function &Fn) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000120 if (!Fn.hasPersonalityFn())
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000121 return false;
122
123 // Classify the personality to see what kind of preparation we need.
David Majnemer7fddecc2015-06-17 20:52:32 +0000124 Personality = classifyEHPersonality(Fn.getPersonalityFn());
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000125
Joseph Tremoulet2afea542015-10-06 20:28:16 +0000126 // Do nothing if this is not a funclet-based personality.
127 if (!isFuncletEHPersonality(Personality))
Reid Kleckner47c8e7a2015-03-12 00:36:20 +0000128 return false;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000129
David Majnemerc289c9f2015-10-07 21:08:25 +0000130 // Remove unreachable blocks. It is not valuable to assign them a color and
131 // their existence can trick us into thinking values are alive when they are
132 // not.
133 removeUnreachableBlocks(Fn);
134
Joseph Tremouletec182852015-08-28 01:12:35 +0000135 SmallVector<BasicBlock *, 4> EntryBlocks;
Reid Kleckner14e77352015-10-09 23:34:53 +0000136 findFuncletEntryPoints(Fn, EntryBlocks);
137 return prepareExplicitEH(Fn, EntryBlocks);
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000138}
139
Andrew Kayloraa92ab02015-04-03 19:37:50 +0000140bool WinEHPrepare::doFinalization(Module &M) { return false; }
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000141
David Majnemere6965832015-10-16 19:59:52 +0000142void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {}
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000143
David Majnemer0ad363e2015-08-18 19:07:12 +0000144static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState,
David Majnemerbfa5b982015-10-10 00:04:29 +0000145 const BasicBlock *BB) {
Reid Kleckner14e77352015-10-09 23:34:53 +0000146 CxxUnwindMapEntry UME;
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000147 UME.ToState = ToState;
David Majnemerbfa5b982015-10-10 00:04:29 +0000148 UME.Cleanup = BB;
Reid Kleckner14e77352015-10-09 23:34:53 +0000149 FuncInfo.CxxUnwindMap.push_back(UME);
David Majnemer0ad363e2015-08-18 19:07:12 +0000150 return FuncInfo.getLastStateNumber();
151}
152
153static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
154 int TryHigh, int CatchHigh,
155 ArrayRef<const CatchPadInst *> Handlers) {
156 WinEHTryBlockMapEntry TBME;
157 TBME.TryLow = TryLow;
158 TBME.TryHigh = TryHigh;
159 TBME.CatchHigh = CatchHigh;
160 assert(TBME.TryLow <= TBME.TryHigh);
161 for (const CatchPadInst *CPI : Handlers) {
162 WinEHHandlerType HT;
163 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
Reid Klecknerb005d282015-09-16 20:16:27 +0000164 if (TypeInfo->isNullValue())
David Majnemer0ad363e2015-08-18 19:07:12 +0000165 HT.TypeDescriptor = nullptr;
Reid Klecknerb005d282015-09-16 20:16:27 +0000166 else
167 HT.TypeDescriptor = cast<GlobalVariable>(TypeInfo->stripPointerCasts());
168 HT.Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
David Majnemer7735a6d2015-10-06 23:31:59 +0000169 HT.Handler = CPI->getParent();
Reid Klecknerb005d282015-09-16 20:16:27 +0000170 if (isa<ConstantPointerNull>(CPI->getArgOperand(2)))
171 HT.CatchObj.Alloca = nullptr;
172 else
173 HT.CatchObj.Alloca = cast<AllocaInst>(CPI->getArgOperand(2));
David Majnemer0ad363e2015-08-18 19:07:12 +0000174 TBME.HandlerArray.push_back(HT);
175 }
176 FuncInfo.TryBlockMap.push_back(TBME);
177}
178
Reid Kleckner94b704c2015-09-09 21:10:03 +0000179static const CatchPadInst *getSingleCatchPadPredecessor(const BasicBlock *BB) {
180 for (const BasicBlock *PredBlock : predecessors(BB))
181 if (auto *CPI = dyn_cast<CatchPadInst>(PredBlock->getFirstNonPHI()))
182 return CPI;
David Majnemer0ad363e2015-08-18 19:07:12 +0000183 return nullptr;
184}
185
Reid Kleckner94b704c2015-09-09 21:10:03 +0000186/// Find all the catchpads that feed directly into the catchendpad. Frontends
187/// using this personality should ensure that each catchendpad and catchpad has
188/// one or zero catchpad predecessors.
189///
190/// The following C++ generates the IR after it:
191/// try {
192/// } catch (A) {
193/// } catch (B) {
194/// }
195///
196/// IR:
197/// %catchpad.A
198/// catchpad [i8* A typeinfo]
199/// to label %catch.A unwind label %catchpad.B
200/// %catchpad.B
201/// catchpad [i8* B typeinfo]
202/// to label %catch.B unwind label %endcatches
203/// %endcatches
204/// catchendblock unwind to caller
Benjamin Kramer3c96f0a2015-09-22 14:34:57 +0000205static void
206findCatchPadsForCatchEndPad(const BasicBlock *CatchEndBB,
207 SmallVectorImpl<const CatchPadInst *> &Handlers) {
Reid Kleckner94b704c2015-09-09 21:10:03 +0000208 const CatchPadInst *CPI = getSingleCatchPadPredecessor(CatchEndBB);
209 while (CPI) {
210 Handlers.push_back(CPI);
211 CPI = getSingleCatchPadPredecessor(CPI->getParent());
212 }
213 // We've pushed these back into reverse source order. Reverse them to get
214 // the list back into source order.
215 std::reverse(Handlers.begin(), Handlers.end());
216}
217
David Majnemer0ad363e2015-08-18 19:07:12 +0000218// Given BB which ends in an unwind edge, return the EHPad that this BB belongs
219// to. If the unwind edge came from an invoke, return null.
220static const BasicBlock *getEHPadFromPredecessor(const BasicBlock *BB) {
221 const TerminatorInst *TI = BB->getTerminator();
222 if (isa<InvokeInst>(TI))
223 return nullptr;
Reid Kleckner7bb20bd2015-09-10 21:46:36 +0000224 if (TI->isEHPad())
David Majnemer0ad363e2015-08-18 19:07:12 +0000225 return BB;
Joseph Tremoulet8220bcc2015-08-23 00:26:33 +0000226 return cast<CleanupReturnInst>(TI)->getCleanupPad()->getParent();
David Majnemer0ad363e2015-08-18 19:07:12 +0000227}
228
Reid Kleckner94b704c2015-09-09 21:10:03 +0000229static void calculateExplicitCXXStateNumbers(WinEHFuncInfo &FuncInfo,
230 const BasicBlock &BB,
231 int ParentState) {
David Majnemer0ad363e2015-08-18 19:07:12 +0000232 assert(BB.isEHPad());
233 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
234 // All catchpad instructions will be handled when we process their
235 // respective catchendpad instruction.
236 if (isa<CatchPadInst>(FirstNonPHI))
237 return;
238
239 if (isa<CatchEndPadInst>(FirstNonPHI)) {
David Majnemer0ad363e2015-08-18 19:07:12 +0000240 SmallVector<const CatchPadInst *, 2> Handlers;
Reid Kleckner94b704c2015-09-09 21:10:03 +0000241 findCatchPadsForCatchEndPad(&BB, Handlers);
242 const BasicBlock *FirstTryPad = Handlers.front()->getParent();
David Majnemer0ad363e2015-08-18 19:07:12 +0000243 int TryLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
244 FuncInfo.EHPadStateMap[Handlers.front()] = TryLow;
Reid Kleckner94b704c2015-09-09 21:10:03 +0000245 for (const BasicBlock *PredBlock : predecessors(FirstTryPad))
David Majnemer0ad363e2015-08-18 19:07:12 +0000246 if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
Reid Kleckner94b704c2015-09-09 21:10:03 +0000247 calculateExplicitCXXStateNumbers(FuncInfo, *PredBlock, TryLow);
David Majnemer0ad363e2015-08-18 19:07:12 +0000248 int CatchLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000249
250 // catchpads are separate funclets in C++ EH due to the way rethrow works.
251 // In SEH, they aren't, so no invokes will unwind to the catchendpad.
David Majnemer0ad363e2015-08-18 19:07:12 +0000252 FuncInfo.EHPadStateMap[FirstNonPHI] = CatchLow;
253 int TryHigh = CatchLow - 1;
254 for (const BasicBlock *PredBlock : predecessors(&BB))
255 if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
Reid Kleckner94b704c2015-09-09 21:10:03 +0000256 calculateExplicitCXXStateNumbers(FuncInfo, *PredBlock, CatchLow);
David Majnemer0ad363e2015-08-18 19:07:12 +0000257 int CatchHigh = FuncInfo.getLastStateNumber();
258 addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchHigh, Handlers);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000259 DEBUG(dbgs() << "TryLow[" << FirstTryPad->getName() << "]: " << TryLow
David Majnemer0ad363e2015-08-18 19:07:12 +0000260 << '\n');
Reid Kleckner94b704c2015-09-09 21:10:03 +0000261 DEBUG(dbgs() << "TryHigh[" << FirstTryPad->getName() << "]: " << TryHigh
David Majnemer0ad363e2015-08-18 19:07:12 +0000262 << '\n');
Reid Kleckner94b704c2015-09-09 21:10:03 +0000263 DEBUG(dbgs() << "CatchHigh[" << FirstTryPad->getName() << "]: " << CatchHigh
David Majnemer0ad363e2015-08-18 19:07:12 +0000264 << '\n');
265 } else if (isa<CleanupPadInst>(FirstNonPHI)) {
Joseph Tremoulet676e5cf2015-10-09 00:46:08 +0000266 // A cleanup can have multiple exits; don't re-process after the first.
267 if (FuncInfo.EHPadStateMap.count(FirstNonPHI))
268 return;
David Majnemer0ad363e2015-08-18 19:07:12 +0000269 int CleanupState = addUnwindMapEntry(FuncInfo, ParentState, &BB);
270 FuncInfo.EHPadStateMap[FirstNonPHI] = CleanupState;
271 DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
272 << BB.getName() << '\n');
273 for (const BasicBlock *PredBlock : predecessors(&BB))
274 if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
Reid Kleckner94b704c2015-09-09 21:10:03 +0000275 calculateExplicitCXXStateNumbers(FuncInfo, *PredBlock, CleanupState);
Joseph Tremoulet676e5cf2015-10-09 00:46:08 +0000276 } else if (auto *CEPI = dyn_cast<CleanupEndPadInst>(FirstNonPHI)) {
277 // Propagate ParentState to the cleanuppad in case it doesn't have
278 // any cleanuprets.
279 BasicBlock *CleanupBlock = CEPI->getCleanupPad()->getParent();
280 calculateExplicitCXXStateNumbers(FuncInfo, *CleanupBlock, ParentState);
281 // Anything unwinding through CleanupEndPadInst is in ParentState.
Joseph Tremoulet53e9cbd2015-10-16 18:08:16 +0000282 FuncInfo.EHPadStateMap[FirstNonPHI] = ParentState;
Joseph Tremoulet676e5cf2015-10-09 00:46:08 +0000283 for (const BasicBlock *PredBlock : predecessors(&BB))
284 if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
285 calculateExplicitCXXStateNumbers(FuncInfo, *PredBlock, ParentState);
David Majnemer0ad363e2015-08-18 19:07:12 +0000286 } else if (isa<TerminatePadInst>(FirstNonPHI)) {
287 report_fatal_error("Not yet implemented!");
288 } else {
289 llvm_unreachable("unexpected EH Pad!");
290 }
291}
292
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000293static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState,
294 const Function *Filter, const BasicBlock *Handler) {
Reid Kleckner94b704c2015-09-09 21:10:03 +0000295 SEHUnwindMapEntry Entry;
296 Entry.ToState = ParentState;
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000297 Entry.IsFinally = false;
Reid Kleckner94b704c2015-09-09 21:10:03 +0000298 Entry.Filter = Filter;
299 Entry.Handler = Handler;
300 FuncInfo.SEHUnwindMap.push_back(Entry);
301 return FuncInfo.SEHUnwindMap.size() - 1;
302}
303
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000304static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState,
305 const BasicBlock *Handler) {
306 SEHUnwindMapEntry Entry;
307 Entry.ToState = ParentState;
308 Entry.IsFinally = true;
309 Entry.Filter = nullptr;
310 Entry.Handler = Handler;
311 FuncInfo.SEHUnwindMap.push_back(Entry);
312 return FuncInfo.SEHUnwindMap.size() - 1;
313}
314
Reid Kleckner94b704c2015-09-09 21:10:03 +0000315static void calculateExplicitSEHStateNumbers(WinEHFuncInfo &FuncInfo,
316 const BasicBlock &BB,
317 int ParentState) {
318 assert(BB.isEHPad());
319 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
320 // All catchpad instructions will be handled when we process their
321 // respective catchendpad instruction.
322 if (isa<CatchPadInst>(FirstNonPHI))
323 return;
324
325 if (isa<CatchEndPadInst>(FirstNonPHI)) {
326 // Extract the filter function and the __except basic block and create a
327 // state for them.
328 SmallVector<const CatchPadInst *, 1> Handlers;
329 findCatchPadsForCatchEndPad(&BB, Handlers);
330 assert(Handlers.size() == 1 &&
331 "SEH doesn't have multiple handlers per __try");
332 const CatchPadInst *CPI = Handlers.front();
333 const BasicBlock *CatchPadBB = CPI->getParent();
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000334 const Constant *FilterOrNull =
335 cast<Constant>(CPI->getArgOperand(0)->stripPointerCasts());
336 const Function *Filter = dyn_cast<Function>(FilterOrNull);
337 assert((Filter || FilterOrNull->isNullValue()) &&
338 "unexpected filter value");
David Majnemer7735a6d2015-10-06 23:31:59 +0000339 int TryState = addSEHExcept(FuncInfo, ParentState, Filter, CatchPadBB);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000340
341 // Everything in the __try block uses TryState as its parent state.
342 FuncInfo.EHPadStateMap[CPI] = TryState;
343 DEBUG(dbgs() << "Assigning state #" << TryState << " to BB "
344 << CatchPadBB->getName() << '\n');
345 for (const BasicBlock *PredBlock : predecessors(CatchPadBB))
346 if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
347 calculateExplicitSEHStateNumbers(FuncInfo, *PredBlock, TryState);
348
349 // Everything in the __except block unwinds to ParentState, just like code
350 // outside the __try.
351 FuncInfo.EHPadStateMap[FirstNonPHI] = ParentState;
352 DEBUG(dbgs() << "Assigning state #" << ParentState << " to BB "
353 << BB.getName() << '\n');
354 for (const BasicBlock *PredBlock : predecessors(&BB))
355 if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
356 calculateExplicitSEHStateNumbers(FuncInfo, *PredBlock, ParentState);
357 } else if (isa<CleanupPadInst>(FirstNonPHI)) {
Joseph Tremoulet676e5cf2015-10-09 00:46:08 +0000358 // A cleanup can have multiple exits; don't re-process after the first.
359 if (FuncInfo.EHPadStateMap.count(FirstNonPHI))
360 return;
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000361 int CleanupState = addSEHFinally(FuncInfo, ParentState, &BB);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000362 FuncInfo.EHPadStateMap[FirstNonPHI] = CleanupState;
363 DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
364 << BB.getName() << '\n');
365 for (const BasicBlock *PredBlock : predecessors(&BB))
366 if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
367 calculateExplicitSEHStateNumbers(FuncInfo, *PredBlock, CleanupState);
Joseph Tremoulet676e5cf2015-10-09 00:46:08 +0000368 } else if (auto *CEPI = dyn_cast<CleanupEndPadInst>(FirstNonPHI)) {
369 // Propagate ParentState to the cleanuppad in case it doesn't have
370 // any cleanuprets.
371 BasicBlock *CleanupBlock = CEPI->getCleanupPad()->getParent();
372 calculateExplicitSEHStateNumbers(FuncInfo, *CleanupBlock, ParentState);
Reid Kleckner7bb20bd2015-09-10 21:46:36 +0000373 // Anything unwinding through CleanupEndPadInst is in ParentState.
374 FuncInfo.EHPadStateMap[FirstNonPHI] = ParentState;
375 DEBUG(dbgs() << "Assigning state #" << ParentState << " to BB "
376 << BB.getName() << '\n');
377 for (const BasicBlock *PredBlock : predecessors(&BB))
378 if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
379 calculateExplicitSEHStateNumbers(FuncInfo, *PredBlock, ParentState);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000380 } else if (isa<TerminatePadInst>(FirstNonPHI)) {
381 report_fatal_error("Not yet implemented!");
382 } else {
383 llvm_unreachable("unexpected EH Pad!");
384 }
385}
386
387/// Check if the EH Pad unwinds to caller. Cleanups are a little bit of a
388/// special case because we have to look at the cleanupret instruction that uses
389/// the cleanuppad.
390static bool doesEHPadUnwindToCaller(const Instruction *EHPad) {
391 auto *CPI = dyn_cast<CleanupPadInst>(EHPad);
392 if (!CPI)
393 return EHPad->mayThrow();
394
395 // This cleanup does not return or unwind, so we say it unwinds to caller.
396 if (CPI->use_empty())
397 return true;
398
399 const Instruction *User = CPI->user_back();
400 if (auto *CRI = dyn_cast<CleanupReturnInst>(User))
401 return CRI->unwindsToCaller();
402 return cast<CleanupEndPadInst>(User)->unwindsToCaller();
403}
404
Reid Kleckner813f1b62015-09-16 22:14:46 +0000405void llvm::calculateSEHStateNumbers(const Function *Fn,
Reid Kleckner94b704c2015-09-09 21:10:03 +0000406 WinEHFuncInfo &FuncInfo) {
407 // Don't compute state numbers twice.
408 if (!FuncInfo.SEHUnwindMap.empty())
409 return;
410
Reid Kleckner813f1b62015-09-16 22:14:46 +0000411 for (const BasicBlock &BB : *Fn) {
Reid Kleckner94b704c2015-09-09 21:10:03 +0000412 if (!BB.isEHPad() || !doesEHPadUnwindToCaller(BB.getFirstNonPHI()))
413 continue;
414 calculateExplicitSEHStateNumbers(FuncInfo, BB, -1);
415 }
416}
417
Reid Kleckner813f1b62015-09-16 22:14:46 +0000418void llvm::calculateWinCXXEHStateNumbers(const Function *Fn,
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000419 WinEHFuncInfo &FuncInfo) {
420 // Return if it's already been done.
David Majnemer0ad363e2015-08-18 19:07:12 +0000421 if (!FuncInfo.EHPadStateMap.empty())
422 return;
423
Reid Kleckner813f1b62015-09-16 22:14:46 +0000424 for (const BasicBlock &BB : *Fn) {
David Majnemer0ad363e2015-08-18 19:07:12 +0000425 if (!BB.isEHPad())
426 continue;
Reid Kleckner813f1b62015-09-16 22:14:46 +0000427 if (BB.isLandingPad())
428 report_fatal_error("MSVC C++ EH cannot use landingpads");
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000429 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
Reid Kleckner94b704c2015-09-09 21:10:03 +0000430 if (!doesEHPadUnwindToCaller(FirstNonPHI))
David Majnemer0ad363e2015-08-18 19:07:12 +0000431 continue;
Reid Kleckner94b704c2015-09-09 21:10:03 +0000432 calculateExplicitCXXStateNumbers(FuncInfo, BB, -1);
David Majnemer0ad363e2015-08-18 19:07:12 +0000433 }
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000434}
David Majnemerfd9f4772015-08-11 01:15:26 +0000435
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000436static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int ParentState,
437 ClrHandlerType HandlerType, uint32_t TypeToken,
438 const BasicBlock *Handler) {
439 ClrEHUnwindMapEntry Entry;
440 Entry.Parent = ParentState;
441 Entry.Handler = Handler;
442 Entry.HandlerType = HandlerType;
443 Entry.TypeToken = TypeToken;
444 FuncInfo.ClrEHUnwindMap.push_back(Entry);
445 return FuncInfo.ClrEHUnwindMap.size() - 1;
446}
447
448void llvm::calculateClrEHStateNumbers(const Function *Fn,
449 WinEHFuncInfo &FuncInfo) {
450 // Return if it's already been done.
451 if (!FuncInfo.EHPadStateMap.empty())
452 return;
453
454 SmallVector<std::pair<const Instruction *, int>, 8> Worklist;
455
456 // Each pad needs to be able to refer to its parent, so scan the function
457 // looking for top-level handlers and seed the worklist with them.
458 for (const BasicBlock &BB : *Fn) {
459 if (!BB.isEHPad())
460 continue;
461 if (BB.isLandingPad())
462 report_fatal_error("CoreCLR EH cannot use landingpads");
463 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
464 if (!doesEHPadUnwindToCaller(FirstNonPHI))
465 continue;
466 // queue this with sentinel parent state -1 to mean unwind to caller.
467 Worklist.emplace_back(FirstNonPHI, -1);
468 }
469
470 while (!Worklist.empty()) {
471 const Instruction *Pad;
472 int ParentState;
473 std::tie(Pad, ParentState) = Worklist.pop_back_val();
474
475 int PredState;
476 if (const CleanupEndPadInst *EndPad = dyn_cast<CleanupEndPadInst>(Pad)) {
477 FuncInfo.EHPadStateMap[EndPad] = ParentState;
478 // Queue the cleanuppad, in case it doesn't have a cleanupret.
479 Worklist.emplace_back(EndPad->getCleanupPad(), ParentState);
480 // Preds of the endpad should get the parent state.
481 PredState = ParentState;
482 } else if (const CleanupPadInst *Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
483 // A cleanup can have multiple exits; don't re-process after the first.
484 if (FuncInfo.EHPadStateMap.count(Pad))
485 continue;
486 // CoreCLR personality uses arity to distinguish faults from finallies.
487 const BasicBlock *PadBlock = Cleanup->getParent();
488 ClrHandlerType HandlerType =
489 (Cleanup->getNumOperands() ? ClrHandlerType::Fault
490 : ClrHandlerType::Finally);
491 int NewState =
492 addClrEHHandler(FuncInfo, ParentState, HandlerType, 0, PadBlock);
493 FuncInfo.EHPadStateMap[Cleanup] = NewState;
494 // Propagate the new state to all preds of the cleanup
495 PredState = NewState;
496 } else if (const CatchEndPadInst *EndPad = dyn_cast<CatchEndPadInst>(Pad)) {
497 FuncInfo.EHPadStateMap[EndPad] = ParentState;
498 // Preds of the endpad should get the parent state.
499 PredState = ParentState;
500 } else if (const CatchPadInst *Catch = dyn_cast<CatchPadInst>(Pad)) {
Joseph Tremouletbde46c52015-10-07 17:16:25 +0000501 const BasicBlock *PadBlock = Catch->getParent();
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000502 uint32_t TypeToken = static_cast<uint32_t>(
503 cast<ConstantInt>(Catch->getArgOperand(0))->getZExtValue());
504 int NewState = addClrEHHandler(FuncInfo, ParentState,
Joseph Tremouletbde46c52015-10-07 17:16:25 +0000505 ClrHandlerType::Catch, TypeToken, PadBlock);
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000506 FuncInfo.EHPadStateMap[Catch] = NewState;
507 // Preds of the catch get its state
508 PredState = NewState;
509 } else {
510 llvm_unreachable("Unexpected EH pad");
511 }
512
513 // Queue all predecessors with the given state
514 for (const BasicBlock *Pred : predecessors(Pad->getParent())) {
515 if ((Pred = getEHPadFromPredecessor(Pred)))
516 Worklist.emplace_back(Pred->getFirstNonPHI(), PredState);
517 }
518 }
519}
520
David Majnemer67bff0d2015-09-16 20:42:16 +0000521void WinEHPrepare::replaceTerminatePadWithCleanup(Function &F) {
522 if (Personality != EHPersonality::MSVC_CXX)
523 return;
524 for (BasicBlock &BB : F) {
525 Instruction *First = BB.getFirstNonPHI();
526 auto *TPI = dyn_cast<TerminatePadInst>(First);
527 if (!TPI)
528 continue;
529
530 if (TPI->getNumArgOperands() != 1)
531 report_fatal_error(
532 "Expected a unary terminatepad for MSVC C++ personalities!");
533
534 auto *TerminateFn = dyn_cast<Function>(TPI->getArgOperand(0));
535 if (!TerminateFn)
536 report_fatal_error("Function operand expected in terminatepad for MSVC "
537 "C++ personalities!");
538
539 // Insert the cleanuppad instruction.
540 auto *CPI = CleanupPadInst::Create(
541 BB.getContext(), {}, Twine("terminatepad.for.", BB.getName()), &BB);
542
543 // Insert the call to the terminate instruction.
544 auto *CallTerminate = CallInst::Create(TerminateFn, {}, &BB);
545 CallTerminate->setDoesNotThrow();
546 CallTerminate->setDoesNotReturn();
547 CallTerminate->setCallingConv(TerminateFn->getCallingConv());
548
549 // Insert a new terminator for the cleanuppad using the same successor as
550 // the terminatepad.
551 CleanupReturnInst::Create(CPI, TPI->getUnwindDest(), &BB);
552
553 // Let's remove the terminatepad now that we've inserted the new
554 // instructions.
555 TPI->eraseFromParent();
556 }
557}
558
David Majnemerf828a0c2015-10-01 18:44:59 +0000559static void
560colorFunclets(Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks,
561 std::map<BasicBlock *, std::set<BasicBlock *>> &BlockColors,
562 std::map<BasicBlock *, std::set<BasicBlock *>> &FuncletBlocks,
563 std::map<BasicBlock *, std::set<BasicBlock *>> &FuncletChildren) {
Joseph Tremouletec182852015-08-28 01:12:35 +0000564 SmallVector<std::pair<BasicBlock *, BasicBlock *>, 16> Worklist;
565 BasicBlock *EntryBlock = &F.getEntryBlock();
David Majnemerfd9f4772015-08-11 01:15:26 +0000566
Joseph Tremouletec182852015-08-28 01:12:35 +0000567 // Build up the color map, which maps each block to its set of 'colors'.
568 // For any block B, the "colors" of B are the set of funclets F (possibly
569 // including a root "funclet" representing the main function), such that
570 // F will need to directly contain B or a copy of B (where the term "directly
571 // contain" is used to distinguish from being "transitively contained" in
572 // a nested funclet).
573 // Use a CFG walk driven by a worklist of (block, color) pairs. The "color"
574 // sets attached during this processing to a block which is the entry of some
575 // funclet F is actually the set of F's parents -- i.e. the union of colors
576 // of all predecessors of F's entry. For all other blocks, the color sets
577 // are as defined above. A post-pass fixes up the block color map to reflect
578 // the same sense of "color" for funclet entries as for other blocks.
579
580 Worklist.push_back({EntryBlock, EntryBlock});
David Majnemerfd9f4772015-08-11 01:15:26 +0000581
582 while (!Worklist.empty()) {
Joseph Tremouletec182852015-08-28 01:12:35 +0000583 BasicBlock *Visiting;
584 BasicBlock *Color;
585 std::tie(Visiting, Color) = Worklist.pop_back_val();
586 Instruction *VisitingHead = Visiting->getFirstNonPHI();
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000587 if (VisitingHead->isEHPad() && !isa<CatchEndPadInst>(VisitingHead) &&
588 !isa<CleanupEndPadInst>(VisitingHead)) {
Joseph Tremouletec182852015-08-28 01:12:35 +0000589 // Mark this as a funclet head as a member of itself.
590 FuncletBlocks[Visiting].insert(Visiting);
Joseph Tremoulet53e9cbd2015-10-16 18:08:16 +0000591 // Queue exits (i.e. successors of rets/endpads) with the parent color.
592 // Skip any exits that are catchendpads, since the parent color must then
593 // represent one of the catches chained to that catchendpad, but the
594 // catchendpad should get the color of the common parent of all its
595 // chained catches (i.e. the grandparent color of the current pad).
596 // We don't need to worry abou catchendpads going unvisited, since the
597 // catches chained to them must have unwind edges to them by which we will
598 // visit them.
Reid Kleckner72ba7042015-10-07 00:27:33 +0000599 for (User *U : VisitingHead->users()) {
600 if (auto *Exit = dyn_cast<TerminatorInst>(U)) {
601 for (BasicBlock *Succ : successors(Exit->getParent()))
Joseph Tremoulet53e9cbd2015-10-16 18:08:16 +0000602 if (!isa<CatchEndPadInst>(*Succ->getFirstNonPHI()))
603 if (BlockColors[Succ].insert(Color).second)
604 Worklist.push_back({Succ, Color});
Joseph Tremouletec182852015-08-28 01:12:35 +0000605 }
606 }
607 // Handle CatchPad specially since its successors need different colors.
608 if (CatchPadInst *CatchPad = dyn_cast<CatchPadInst>(VisitingHead)) {
609 // Visit the normal successor with the color of the new EH pad, and
610 // visit the unwind successor with the color of the parent.
611 BasicBlock *NormalSucc = CatchPad->getNormalDest();
612 if (BlockColors[NormalSucc].insert(Visiting).second) {
613 Worklist.push_back({NormalSucc, Visiting});
614 }
615 BasicBlock *UnwindSucc = CatchPad->getUnwindDest();
616 if (BlockColors[UnwindSucc].insert(Color).second) {
617 Worklist.push_back({UnwindSucc, Color});
618 }
619 continue;
620 }
621 // Switch color to the current node, except for terminate pads which
622 // have no bodies and only unwind successors and so need their successors
623 // visited with the color of the parent.
624 if (!isa<TerminatePadInst>(VisitingHead))
625 Color = Visiting;
626 } else {
627 // Note that this is a member of the given color.
628 FuncletBlocks[Color].insert(Visiting);
Joseph Tremouletf3aff312015-09-10 16:51:25 +0000629 }
630
631 TerminatorInst *Terminator = Visiting->getTerminator();
632 if (isa<CleanupReturnInst>(Terminator) ||
633 isa<CatchReturnInst>(Terminator) ||
634 isa<CleanupEndPadInst>(Terminator)) {
635 // These blocks' successors have already been queued with the parent
636 // color.
637 continue;
David Majnemerfd9f4772015-08-11 01:15:26 +0000638 }
Joseph Tremouletec182852015-08-28 01:12:35 +0000639 for (BasicBlock *Succ : successors(Visiting)) {
640 if (isa<CatchEndPadInst>(Succ->getFirstNonPHI())) {
641 // The catchendpad needs to be visited with the parent's color, not
642 // the current color. This will happen in the code above that visits
643 // any catchpad unwind successor with the parent color, so we can
644 // safely skip this successor here.
645 continue;
646 }
647 if (BlockColors[Succ].insert(Color).second) {
648 Worklist.push_back({Succ, Color});
649 }
650 }
651 }
David Majnemerfd9f4772015-08-11 01:15:26 +0000652
Joseph Tremouletec182852015-08-28 01:12:35 +0000653 // The processing above actually accumulated the parent set for this
654 // funclet into the color set for its entry; use the parent set to
655 // populate the children map, and reset the color set to include just
656 // the funclet itself (no instruction can target a funclet entry except on
657 // that transitions to the child funclet).
658 for (BasicBlock *FuncletEntry : EntryBlocks) {
659 std::set<BasicBlock *> &ColorMapItem = BlockColors[FuncletEntry];
660 for (BasicBlock *Parent : ColorMapItem)
661 FuncletChildren[Parent].insert(FuncletEntry);
662 ColorMapItem.clear();
663 ColorMapItem.insert(FuncletEntry);
David Majnemerfd9f4772015-08-11 01:15:26 +0000664 }
665}
666
David Majnemerf828a0c2015-10-01 18:44:59 +0000667void WinEHPrepare::colorFunclets(Function &F,
668 SmallVectorImpl<BasicBlock *> &EntryBlocks) {
669 ::colorFunclets(F, EntryBlocks, BlockColors, FuncletBlocks, FuncletChildren);
670}
671
672void llvm::calculateCatchReturnSuccessorColors(const Function *Fn,
673 WinEHFuncInfo &FuncInfo) {
David Majnemerf828a0c2015-10-01 18:44:59 +0000674 SmallVector<BasicBlock *, 4> EntryBlocks;
675 // colorFunclets needs the set of EntryBlocks, get them using
Reid Kleckner14e77352015-10-09 23:34:53 +0000676 // findFuncletEntryPoints.
677 findFuncletEntryPoints(const_cast<Function &>(*Fn), EntryBlocks);
David Majnemerf828a0c2015-10-01 18:44:59 +0000678
679 std::map<BasicBlock *, std::set<BasicBlock *>> BlockColors;
680 std::map<BasicBlock *, std::set<BasicBlock *>> FuncletBlocks;
681 std::map<BasicBlock *, std::set<BasicBlock *>> FuncletChildren;
682 // Figure out which basic blocks belong to which funclets.
683 colorFunclets(const_cast<Function &>(*Fn), EntryBlocks, BlockColors,
684 FuncletBlocks, FuncletChildren);
685
686 // We need to find the catchret successors. To do this, we must first find
687 // all the catchpad funclets.
688 for (auto &Funclet : FuncletBlocks) {
689 // Figure out what kind of funclet we are looking at; We only care about
690 // catchpads.
691 BasicBlock *FuncletPadBB = Funclet.first;
692 Instruction *FirstNonPHI = FuncletPadBB->getFirstNonPHI();
693 auto *CatchPad = dyn_cast<CatchPadInst>(FirstNonPHI);
694 if (!CatchPad)
695 continue;
696
697 // The users of a catchpad are always catchrets.
698 for (User *Exit : CatchPad->users()) {
Reid Kleckner72ba7042015-10-07 00:27:33 +0000699 auto *CatchReturn = dyn_cast<CatchReturnInst>(Exit);
700 if (!CatchReturn)
701 continue;
David Majnemerf828a0c2015-10-01 18:44:59 +0000702 BasicBlock *CatchRetSuccessor = CatchReturn->getSuccessor();
703 std::set<BasicBlock *> &SuccessorColors = BlockColors[CatchRetSuccessor];
704 assert(SuccessorColors.size() == 1 && "Expected BB to be monochrome!");
705 BasicBlock *Color = *SuccessorColors.begin();
706 if (auto *CPI = dyn_cast<CatchPadInst>(Color->getFirstNonPHI()))
707 Color = CPI->getNormalDest();
708 // Record the catchret successor's funclet membership.
709 FuncInfo.CatchRetSuccessorColorMap[CatchReturn] = Color;
710 }
711 }
712}
713
David Majnemerb3d9b962015-09-16 18:40:24 +0000714void WinEHPrepare::demotePHIsOnFunclets(Function &F) {
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000715 // Strip PHI nodes off of EH pads.
716 SmallVector<PHINode *, 16> PHINodes;
David Majnemerfd9f4772015-08-11 01:15:26 +0000717 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000718 BasicBlock *BB = &*FI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000719 if (!BB->isEHPad())
720 continue;
David Majnemerfd9f4772015-08-11 01:15:26 +0000721 for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000722 Instruction *I = &*BI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000723 auto *PN = dyn_cast<PHINode>(I);
724 // Stop at the first non-PHI.
725 if (!PN)
726 break;
David Majnemerfd9f4772015-08-11 01:15:26 +0000727
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000728 AllocaInst *SpillSlot = insertPHILoads(PN, F);
729 if (SpillSlot)
730 insertPHIStores(PN, SpillSlot);
731
732 PHINodes.push_back(PN);
David Majnemerfd9f4772015-08-11 01:15:26 +0000733 }
734 }
735
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000736 for (auto *PN : PHINodes) {
737 // There may be lingering uses on other EH PHIs being removed
738 PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
739 PN->eraseFromParent();
David Majnemerfd9f4772015-08-11 01:15:26 +0000740 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000741}
David Majnemerfd9f4772015-08-11 01:15:26 +0000742
David Majnemerb3d9b962015-09-16 18:40:24 +0000743void WinEHPrepare::demoteUsesBetweenFunclets(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000744 // Turn all inter-funclet uses of a Value into loads and stores.
745 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000746 BasicBlock *BB = &*FI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000747 std::set<BasicBlock *> &ColorsForBB = BlockColors[BB];
748 for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000749 Instruction *I = &*BI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000750 // Funclets are permitted to use static allocas.
751 if (auto *AI = dyn_cast<AllocaInst>(I))
752 if (AI->isStaticAlloca())
753 continue;
754
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000755 demoteNonlocalUses(I, ColorsForBB, F);
David Majnemerfd9f4772015-08-11 01:15:26 +0000756 }
757 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000758}
759
760void WinEHPrepare::demoteArgumentUses(Function &F) {
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000761 // Also demote function parameters used in funclets.
762 std::set<BasicBlock *> &ColorsForEntry = BlockColors[&F.getEntryBlock()];
763 for (Argument &Arg : F.args())
764 demoteNonlocalUses(&Arg, ColorsForEntry, F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000765}
David Majnemerfd9f4772015-08-11 01:15:26 +0000766
David Majnemerb3d9b962015-09-16 18:40:24 +0000767void WinEHPrepare::cloneCommonBlocks(
768 Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000769 // We need to clone all blocks which belong to multiple funclets. Values are
770 // remapped throughout the funclet to propogate both the new instructions
771 // *and* the new basic blocks themselves.
Joseph Tremouletec182852015-08-28 01:12:35 +0000772 for (BasicBlock *FuncletPadBB : EntryBlocks) {
773 std::set<BasicBlock *> &BlocksInFunclet = FuncletBlocks[FuncletPadBB];
David Majnemerfd9f4772015-08-11 01:15:26 +0000774
775 std::map<BasicBlock *, BasicBlock *> Orig2Clone;
776 ValueToValueMapTy VMap;
777 for (BasicBlock *BB : BlocksInFunclet) {
778 std::set<BasicBlock *> &ColorsForBB = BlockColors[BB];
779 // We don't need to do anything if the block is monochromatic.
780 size_t NumColorsForBB = ColorsForBB.size();
781 if (NumColorsForBB == 1)
782 continue;
783
David Majnemerfd9f4772015-08-11 01:15:26 +0000784 // Create a new basic block and copy instructions into it!
Joseph Tremouletec182852015-08-28 01:12:35 +0000785 BasicBlock *CBB =
786 CloneBasicBlock(BB, VMap, Twine(".for.", FuncletPadBB->getName()));
787 // Insert the clone immediately after the original to ensure determinism
788 // and to keep the same relative ordering of any funclet's blocks.
789 CBB->insertInto(&F, BB->getNextNode());
David Majnemerfd9f4772015-08-11 01:15:26 +0000790
791 // Add basic block mapping.
792 VMap[BB] = CBB;
793
794 // Record delta operations that we need to perform to our color mappings.
795 Orig2Clone[BB] = CBB;
796 }
797
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000798 // If nothing was cloned, we're done cloning in this funclet.
799 if (Orig2Clone.empty())
800 continue;
801
David Majnemerfd9f4772015-08-11 01:15:26 +0000802 // Update our color mappings to reflect that one block has lost a color and
803 // another has gained a color.
804 for (auto &BBMapping : Orig2Clone) {
805 BasicBlock *OldBlock = BBMapping.first;
806 BasicBlock *NewBlock = BBMapping.second;
807
808 BlocksInFunclet.insert(NewBlock);
809 BlockColors[NewBlock].insert(FuncletPadBB);
810
811 BlocksInFunclet.erase(OldBlock);
812 BlockColors[OldBlock].erase(FuncletPadBB);
813 }
814
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000815 // Loop over all of the instructions in this funclet, fixing up operand
David Majnemerfd9f4772015-08-11 01:15:26 +0000816 // references as we go. This uses VMap to do all the hard work.
817 for (BasicBlock *BB : BlocksInFunclet)
818 // Loop over all instructions, fixing each one as we find it...
819 for (Instruction &I : *BB)
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000820 RemapInstruction(&I, VMap,
821 RF_IgnoreMissingEntries | RF_NoModuleLevelChanges);
David Majnemer459a64a2015-09-16 18:40:37 +0000822
823 // Check to see if SuccBB has PHI nodes. If so, we need to add entries to
824 // the PHI nodes for NewBB now.
825 for (auto &BBMapping : Orig2Clone) {
826 BasicBlock *OldBlock = BBMapping.first;
827 BasicBlock *NewBlock = BBMapping.second;
828 for (BasicBlock *SuccBB : successors(NewBlock)) {
829 for (Instruction &SuccI : *SuccBB) {
830 auto *SuccPN = dyn_cast<PHINode>(&SuccI);
831 if (!SuccPN)
832 break;
833
834 // Ok, we have a PHI node. Figure out what the incoming value was for
835 // the OldBlock.
836 int OldBlockIdx = SuccPN->getBasicBlockIndex(OldBlock);
837 if (OldBlockIdx == -1)
838 break;
839 Value *IV = SuccPN->getIncomingValue(OldBlockIdx);
840
841 // Remap the value if necessary.
842 if (auto *Inst = dyn_cast<Instruction>(IV)) {
843 ValueToValueMapTy::iterator I = VMap.find(Inst);
844 if (I != VMap.end())
845 IV = I->second;
846 }
847
848 SuccPN->addIncoming(IV, NewBlock);
849 }
850 }
851 }
852
853 for (ValueToValueMapTy::value_type VT : VMap) {
854 // If there were values defined in BB that are used outside the funclet,
855 // then we now have to update all uses of the value to use either the
856 // original value, the cloned value, or some PHI derived value. This can
857 // require arbitrary PHI insertion, of which we are prepared to do, clean
858 // these up now.
859 SmallVector<Use *, 16> UsesToRename;
860
861 auto *OldI = dyn_cast<Instruction>(const_cast<Value *>(VT.first));
862 if (!OldI)
863 continue;
864 auto *NewI = cast<Instruction>(VT.second);
865 // Scan all uses of this instruction to see if it is used outside of its
866 // funclet, and if so, record them in UsesToRename.
867 for (Use &U : OldI->uses()) {
868 Instruction *UserI = cast<Instruction>(U.getUser());
869 BasicBlock *UserBB = UserI->getParent();
870 std::set<BasicBlock *> &ColorsForUserBB = BlockColors[UserBB];
871 assert(!ColorsForUserBB.empty());
872 if (ColorsForUserBB.size() > 1 ||
873 *ColorsForUserBB.begin() != FuncletPadBB)
874 UsesToRename.push_back(&U);
875 }
876
877 // If there are no uses outside the block, we're done with this
878 // instruction.
879 if (UsesToRename.empty())
880 continue;
881
882 // We found a use of OldI outside of the funclet. Rename all uses of OldI
883 // that are outside its funclet to be uses of the appropriate PHI node
884 // etc.
885 SSAUpdater SSAUpdate;
886 SSAUpdate.Initialize(OldI->getType(), OldI->getName());
887 SSAUpdate.AddAvailableValue(OldI->getParent(), OldI);
888 SSAUpdate.AddAvailableValue(NewI->getParent(), NewI);
889
890 while (!UsesToRename.empty())
891 SSAUpdate.RewriteUseAfterInsertions(*UsesToRename.pop_back_val());
892 }
David Majnemerfd9f4772015-08-11 01:15:26 +0000893 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000894}
David Majnemerfd9f4772015-08-11 01:15:26 +0000895
David Majnemerb3d9b962015-09-16 18:40:24 +0000896void WinEHPrepare::removeImplausibleTerminators(Function &F) {
David Majnemer83f4bb22015-08-17 20:56:39 +0000897 // Remove implausible terminators and replace them with UnreachableInst.
898 for (auto &Funclet : FuncletBlocks) {
899 BasicBlock *FuncletPadBB = Funclet.first;
900 std::set<BasicBlock *> &BlocksInFunclet = Funclet.second;
901 Instruction *FirstNonPHI = FuncletPadBB->getFirstNonPHI();
902 auto *CatchPad = dyn_cast<CatchPadInst>(FirstNonPHI);
903 auto *CleanupPad = dyn_cast<CleanupPadInst>(FirstNonPHI);
904
905 for (BasicBlock *BB : BlocksInFunclet) {
906 TerminatorInst *TI = BB->getTerminator();
907 // CatchPadInst and CleanupPadInst can't transfer control to a ReturnInst.
908 bool IsUnreachableRet = isa<ReturnInst>(TI) && (CatchPad || CleanupPad);
909 // The token consumed by a CatchReturnInst must match the funclet token.
910 bool IsUnreachableCatchret = false;
911 if (auto *CRI = dyn_cast<CatchReturnInst>(TI))
Joseph Tremoulet8220bcc2015-08-23 00:26:33 +0000912 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000913 // The token consumed by a CleanupReturnInst must match the funclet token.
David Majnemer83f4bb22015-08-17 20:56:39 +0000914 bool IsUnreachableCleanupret = false;
915 if (auto *CRI = dyn_cast<CleanupReturnInst>(TI))
Joseph Tremoulet8220bcc2015-08-23 00:26:33 +0000916 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000917 // The token consumed by a CleanupEndPadInst must match the funclet token.
918 bool IsUnreachableCleanupendpad = false;
919 if (auto *CEPI = dyn_cast<CleanupEndPadInst>(TI))
920 IsUnreachableCleanupendpad = CEPI->getCleanupPad() != CleanupPad;
921 if (IsUnreachableRet || IsUnreachableCatchret ||
922 IsUnreachableCleanupret || IsUnreachableCleanupendpad) {
David Majnemer459a64a2015-09-16 18:40:37 +0000923 // Loop through all of our successors and make sure they know that one
924 // of their predecessors is going away.
925 for (BasicBlock *SuccBB : TI->successors())
926 SuccBB->removePredecessor(BB);
927
Joseph Tremoulet09af67a2015-09-27 01:47:46 +0000928 if (IsUnreachableCleanupendpad) {
929 // We can't simply replace a cleanupendpad with unreachable, because
930 // its predecessor edges are EH edges and unreachable is not an EH
931 // pad. Change all predecessors to the "unwind to caller" form.
932 for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
933 PI != PE;) {
934 BasicBlock *Pred = *PI++;
935 removeUnwindEdge(Pred);
936 }
937 }
938
David Majnemer83f4bb22015-08-17 20:56:39 +0000939 new UnreachableInst(BB->getContext(), TI);
940 TI->eraseFromParent();
941 }
Joseph Tremoulet09af67a2015-09-27 01:47:46 +0000942 // FIXME: Check for invokes/cleanuprets/cleanupendpads which unwind to
943 // implausible catchendpads (i.e. catchendpad not in immediate parent
944 // funclet).
David Majnemer83f4bb22015-08-17 20:56:39 +0000945 }
946 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000947}
David Majnemer83f4bb22015-08-17 20:56:39 +0000948
David Majnemerb3d9b962015-09-16 18:40:24 +0000949void WinEHPrepare::cleanupPreparedFunclets(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000950 // Clean-up some of the mess we made by removing useles PHI nodes, trivial
951 // branches, etc.
952 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000953 BasicBlock *BB = &*FI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000954 SimplifyInstructionsInBlock(BB);
955 ConstantFoldTerminator(BB, /*DeleteDeadConditions=*/true);
956 MergeBlockIntoPredecessor(BB);
957 }
958
David Majnemerfd9f4772015-08-11 01:15:26 +0000959 // We might have some unreachable blocks after cleaning up some impossible
960 // control flow.
961 removeUnreachableBlocks(F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000962}
David Majnemerfd9f4772015-08-11 01:15:26 +0000963
David Majnemerb3d9b962015-09-16 18:40:24 +0000964void WinEHPrepare::verifyPreparedFunclets(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000965 // Recolor the CFG to verify that all is well.
966 for (BasicBlock &BB : F) {
967 size_t NumColors = BlockColors[&BB].size();
968 assert(NumColors == 1 && "Expected monochromatic BB!");
969 if (NumColors == 0)
970 report_fatal_error("Uncolored BB!");
971 if (NumColors > 1)
972 report_fatal_error("Multicolor BB!");
David Majnemer459a64a2015-09-16 18:40:37 +0000973 if (!DisableDemotion) {
974 bool EHPadHasPHI = BB.isEHPad() && isa<PHINode>(BB.begin());
975 assert(!EHPadHasPHI && "EH Pad still has a PHI!");
976 if (EHPadHasPHI)
977 report_fatal_error("EH Pad still has a PHI!");
978 }
David Majnemerfd9f4772015-08-11 01:15:26 +0000979 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000980}
981
982bool WinEHPrepare::prepareExplicitEH(
983 Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks) {
David Majnemer67bff0d2015-09-16 20:42:16 +0000984 replaceTerminatePadWithCleanup(F);
985
David Majnemerb3d9b962015-09-16 18:40:24 +0000986 // Determine which blocks are reachable from which funclet entries.
987 colorFunclets(F, EntryBlocks);
988
David Majnemer459a64a2015-09-16 18:40:37 +0000989 if (!DisableDemotion) {
990 demotePHIsOnFunclets(F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000991
David Majnemer459a64a2015-09-16 18:40:37 +0000992 demoteUsesBetweenFunclets(F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000993
David Majnemer459a64a2015-09-16 18:40:37 +0000994 demoteArgumentUses(F);
995 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000996
997 cloneCommonBlocks(F, EntryBlocks);
998
David Majnemer459a64a2015-09-16 18:40:37 +0000999 if (!DisableCleanups) {
1000 removeImplausibleTerminators(F);
David Majnemerb3d9b962015-09-16 18:40:24 +00001001
David Majnemer459a64a2015-09-16 18:40:37 +00001002 cleanupPreparedFunclets(F);
1003 }
David Majnemerb3d9b962015-09-16 18:40:24 +00001004
1005 verifyPreparedFunclets(F);
David Majnemerfd9f4772015-08-11 01:15:26 +00001006
1007 BlockColors.clear();
1008 FuncletBlocks.clear();
Joseph Tremouletec182852015-08-28 01:12:35 +00001009 FuncletChildren.clear();
David Majnemer0ad363e2015-08-18 19:07:12 +00001010
David Majnemerfd9f4772015-08-11 01:15:26 +00001011 return true;
1012}
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001013
1014// TODO: Share loads when one use dominates another, or when a catchpad exit
1015// dominates uses (needs dominators).
1016AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) {
1017 BasicBlock *PHIBlock = PN->getParent();
1018 AllocaInst *SpillSlot = nullptr;
1019
1020 if (isa<CleanupPadInst>(PHIBlock->getFirstNonPHI())) {
1021 // Insert a load in place of the PHI and replace all uses.
1022 SpillSlot = new AllocaInst(PN->getType(), nullptr,
1023 Twine(PN->getName(), ".wineh.spillslot"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001024 &F.getEntryBlock().front());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001025 Value *V = new LoadInst(SpillSlot, Twine(PN->getName(), ".wineh.reload"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001026 &*PHIBlock->getFirstInsertionPt());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001027 PN->replaceAllUsesWith(V);
1028 return SpillSlot;
1029 }
1030
1031 DenseMap<BasicBlock *, Value *> Loads;
1032 for (Value::use_iterator UI = PN->use_begin(), UE = PN->use_end();
1033 UI != UE;) {
1034 Use &U = *UI++;
1035 auto *UsingInst = cast<Instruction>(U.getUser());
1036 BasicBlock *UsingBB = UsingInst->getParent();
1037 if (UsingBB->isEHPad()) {
1038 // Use is on an EH pad phi. Leave it alone; we'll insert loads and
1039 // stores for it separately.
1040 assert(isa<PHINode>(UsingInst));
1041 continue;
1042 }
1043 replaceUseWithLoad(PN, U, SpillSlot, Loads, F);
1044 }
1045 return SpillSlot;
1046}
1047
1048// TODO: improve store placement. Inserting at def is probably good, but need
1049// to be careful not to introduce interfering stores (needs liveness analysis).
1050// TODO: identify related phi nodes that can share spill slots, and share them
1051// (also needs liveness).
1052void WinEHPrepare::insertPHIStores(PHINode *OriginalPHI,
1053 AllocaInst *SpillSlot) {
1054 // Use a worklist of (Block, Value) pairs -- the given Value needs to be
1055 // stored to the spill slot by the end of the given Block.
1056 SmallVector<std::pair<BasicBlock *, Value *>, 4> Worklist;
1057
1058 Worklist.push_back({OriginalPHI->getParent(), OriginalPHI});
1059
1060 while (!Worklist.empty()) {
1061 BasicBlock *EHBlock;
1062 Value *InVal;
1063 std::tie(EHBlock, InVal) = Worklist.pop_back_val();
1064
1065 PHINode *PN = dyn_cast<PHINode>(InVal);
1066 if (PN && PN->getParent() == EHBlock) {
1067 // The value is defined by another PHI we need to remove, with no room to
1068 // insert a store after the PHI, so each predecessor needs to store its
1069 // incoming value.
1070 for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
1071 Value *PredVal = PN->getIncomingValue(i);
1072
1073 // Undef can safely be skipped.
1074 if (isa<UndefValue>(PredVal))
1075 continue;
1076
1077 insertPHIStore(PN->getIncomingBlock(i), PredVal, SpillSlot, Worklist);
1078 }
1079 } else {
1080 // We need to store InVal, which dominates EHBlock, but can't put a store
1081 // in EHBlock, so need to put stores in each predecessor.
1082 for (BasicBlock *PredBlock : predecessors(EHBlock)) {
1083 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1084 }
1085 }
1086 }
1087}
1088
1089void WinEHPrepare::insertPHIStore(
1090 BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
1091 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist) {
1092
1093 if (PredBlock->isEHPad() &&
1094 !isa<CleanupPadInst>(PredBlock->getFirstNonPHI())) {
1095 // Pred is unsplittable, so we need to queue it on the worklist.
1096 Worklist.push_back({PredBlock, PredVal});
1097 return;
1098 }
1099
1100 // Otherwise, insert the store at the end of the basic block.
1101 new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator());
1102}
1103
1104// TODO: Share loads for same-funclet uses (requires dominators if funclets
1105// aren't properly nested).
1106void WinEHPrepare::demoteNonlocalUses(Value *V,
1107 std::set<BasicBlock *> &ColorsForBB,
1108 Function &F) {
David Majnemer83f4bb22015-08-17 20:56:39 +00001109 // Tokens can only be used non-locally due to control flow involving
1110 // unreachable edges. Don't try to demote the token usage, we'll simply
1111 // delete the cloned user later.
1112 if (isa<CatchPadInst>(V) || isa<CleanupPadInst>(V))
1113 return;
1114
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001115 DenseMap<BasicBlock *, Value *> Loads;
1116 AllocaInst *SpillSlot = nullptr;
1117 for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE;) {
1118 Use &U = *UI++;
1119 auto *UsingInst = cast<Instruction>(U.getUser());
1120 BasicBlock *UsingBB = UsingInst->getParent();
1121
Joseph Tremouletec182852015-08-28 01:12:35 +00001122 // Is the Use inside a block which is colored the same as the Def?
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001123 // If so, we don't need to escape the Def because we will clone
1124 // ourselves our own private copy.
1125 std::set<BasicBlock *> &ColorsForUsingBB = BlockColors[UsingBB];
Joseph Tremouletec182852015-08-28 01:12:35 +00001126 if (ColorsForUsingBB == ColorsForBB)
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001127 continue;
1128
1129 replaceUseWithLoad(V, U, SpillSlot, Loads, F);
1130 }
1131 if (SpillSlot) {
1132 // Insert stores of the computed value into the stack slot.
1133 // We have to be careful if I is an invoke instruction,
1134 // because we can't insert the store AFTER the terminator instruction.
1135 BasicBlock::iterator InsertPt;
1136 if (isa<Argument>(V)) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001137 InsertPt = F.getEntryBlock().getTerminator()->getIterator();
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001138 } else if (isa<TerminatorInst>(V)) {
1139 auto *II = cast<InvokeInst>(V);
1140 // We cannot demote invoke instructions to the stack if their normal
1141 // edge is critical. Therefore, split the critical edge and create a
1142 // basic block into which the store can be inserted.
1143 if (!II->getNormalDest()->getSinglePredecessor()) {
1144 unsigned SuccNum =
1145 GetSuccessorNumber(II->getParent(), II->getNormalDest());
1146 assert(isCriticalEdge(II, SuccNum) && "Expected a critical edge!");
1147 BasicBlock *NewBlock = SplitCriticalEdge(II, SuccNum);
1148 assert(NewBlock && "Unable to split critical edge.");
1149 // Update the color mapping for the newly split edge.
1150 std::set<BasicBlock *> &ColorsForUsingBB = BlockColors[II->getParent()];
1151 BlockColors[NewBlock] = ColorsForUsingBB;
1152 for (BasicBlock *FuncletPad : ColorsForUsingBB)
1153 FuncletBlocks[FuncletPad].insert(NewBlock);
1154 }
1155 InsertPt = II->getNormalDest()->getFirstInsertionPt();
1156 } else {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001157 InsertPt = cast<Instruction>(V)->getIterator();
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001158 ++InsertPt;
1159 // Don't insert before PHI nodes or EH pad instrs.
1160 for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt)
1161 ;
1162 }
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001163 new StoreInst(V, SpillSlot, &*InsertPt);
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001164 }
1165}
1166
1167void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
1168 DenseMap<BasicBlock *, Value *> &Loads,
1169 Function &F) {
1170 // Lazilly create the spill slot.
1171 if (!SpillSlot)
1172 SpillSlot = new AllocaInst(V->getType(), nullptr,
1173 Twine(V->getName(), ".wineh.spillslot"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001174 &F.getEntryBlock().front());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001175
1176 auto *UsingInst = cast<Instruction>(U.getUser());
1177 if (auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1178 // If this is a PHI node, we can't insert a load of the value before
1179 // the use. Instead insert the load in the predecessor block
1180 // corresponding to the incoming value.
1181 //
1182 // Note that if there are multiple edges from a basic block to this
1183 // PHI node that we cannot have multiple loads. The problem is that
1184 // the resulting PHI node will have multiple values (from each load)
1185 // coming in from the same block, which is illegal SSA form.
1186 // For this reason, we keep track of and reuse loads we insert.
1187 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
Joseph Tremoulet7031c9f2015-08-17 13:51:37 +00001188 if (auto *CatchRet =
1189 dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) {
1190 // Putting a load above a catchret and use on the phi would still leave
1191 // a cross-funclet def/use. We need to split the edge, change the
1192 // catchret to target the new block, and put the load there.
1193 BasicBlock *PHIBlock = UsingInst->getParent();
1194 BasicBlock *NewBlock = SplitEdge(IncomingBlock, PHIBlock);
1195 // SplitEdge gives us:
1196 // IncomingBlock:
1197 // ...
1198 // br label %NewBlock
1199 // NewBlock:
1200 // catchret label %PHIBlock
1201 // But we need:
1202 // IncomingBlock:
1203 // ...
1204 // catchret label %NewBlock
1205 // NewBlock:
1206 // br label %PHIBlock
1207 // So move the terminators to each others' blocks and swap their
1208 // successors.
1209 BranchInst *Goto = cast<BranchInst>(IncomingBlock->getTerminator());
1210 Goto->removeFromParent();
1211 CatchRet->removeFromParent();
1212 IncomingBlock->getInstList().push_back(CatchRet);
1213 NewBlock->getInstList().push_back(Goto);
1214 Goto->setSuccessor(0, PHIBlock);
1215 CatchRet->setSuccessor(NewBlock);
1216 // Update the color mapping for the newly split edge.
1217 std::set<BasicBlock *> &ColorsForPHIBlock = BlockColors[PHIBlock];
1218 BlockColors[NewBlock] = ColorsForPHIBlock;
1219 for (BasicBlock *FuncletPad : ColorsForPHIBlock)
1220 FuncletBlocks[FuncletPad].insert(NewBlock);
1221 // Treat the new block as incoming for load insertion.
1222 IncomingBlock = NewBlock;
1223 }
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001224 Value *&Load = Loads[IncomingBlock];
1225 // Insert the load into the predecessor block
1226 if (!Load)
1227 Load = new LoadInst(SpillSlot, Twine(V->getName(), ".wineh.reload"),
1228 /*Volatile=*/false, IncomingBlock->getTerminator());
1229
1230 U.set(Load);
1231 } else {
1232 // Reload right before the old use.
1233 auto *Load = new LoadInst(SpillSlot, Twine(V->getName(), ".wineh.reload"),
1234 /*Volatile=*/false, UsingInst);
1235 U.set(Load);
1236 }
1237}
Reid Klecknerc71d6272015-09-28 23:56:30 +00001238
1239void WinEHFuncInfo::addIPToStateRange(const BasicBlock *PadBB,
1240 MCSymbol *InvokeBegin,
1241 MCSymbol *InvokeEnd) {
1242 assert(PadBB->isEHPad() && EHPadStateMap.count(PadBB->getFirstNonPHI()) &&
1243 "should get EH pad BB with precomputed state");
1244 InvokeToStateMap[InvokeBegin] =
1245 std::make_pair(EHPadStateMap[PadBB->getFirstNonPHI()], InvokeEnd);
1246}