blob: 52fb922c935a9c726e255e6405d6aef375d58d20 [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 Majnemer8a1c45d2015-12-12 05:38:55 +000020#include "llvm/ADT/MapVector.h"
David Majnemerfd9f4772015-08-11 01:15:26 +000021#include "llvm/Analysis/CFG.h"
David Majnemer70497c62015-12-02 23:06:39 +000022#include "llvm/Analysis/EHPersonalities.h"
Chandler Carruthe0115342015-12-29 09:24:39 +000023#include "llvm/CodeGen/MachineBasicBlock.h"
David Majnemercde33032015-03-30 22:58:10 +000024#include "llvm/CodeGen/WinEHFuncInfo.h"
Chandler Carruthe0115342015-12-29 09:24:39 +000025#include "llvm/MC/MCSymbol.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000026#include "llvm/Pass.h"
Andrew Kaylor6b67d422015-03-11 23:22:06 +000027#include "llvm/Support/Debug.h"
Benjamin Kramera8d61b12015-03-23 18:57:17 +000028#include "llvm/Support/raw_ostream.h"
Andrew Kaylor6b67d422015-03-11 23:22:06 +000029#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000030#include "llvm/Transforms/Utils/Cloning.h"
31#include "llvm/Transforms/Utils/Local.h"
David Majnemer459a64a2015-09-16 18:40:37 +000032#include "llvm/Transforms/Utils/SSAUpdater.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000033
34using namespace llvm;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000035
36#define DEBUG_TYPE "winehprepare"
37
David Majnemer459a64a2015-09-16 18:40:37 +000038static cl::opt<bool> DisableDemotion(
39 "disable-demotion", cl::Hidden,
40 cl::desc(
41 "Clone multicolor basic blocks but do not demote cross funclet values"),
42 cl::init(false));
43
44static cl::opt<bool> DisableCleanups(
45 "disable-cleanups", cl::Hidden,
46 cl::desc("Do not remove implausible terminators or other similar cleanups"),
47 cl::init(false));
48
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000049namespace {
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +000050
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000051class WinEHPrepare : public FunctionPass {
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000052public:
53 static char ID; // Pass identification, replacement for typeid.
David Majnemere6965832015-10-16 19:59:52 +000054 WinEHPrepare(const TargetMachine *TM = nullptr) : FunctionPass(ID) {}
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000055
56 bool runOnFunction(Function &Fn) override;
57
58 bool doFinalization(Module &M) override;
59
60 void getAnalysisUsage(AnalysisUsage &AU) const override;
61
62 const char *getPassName() const override {
63 return "Windows exception handling preparation";
64 }
65
66private:
Joseph Tremouletc9ff9142015-08-13 14:30:10 +000067 void insertPHIStores(PHINode *OriginalPHI, AllocaInst *SpillSlot);
68 void
69 insertPHIStore(BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
70 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist);
71 AllocaInst *insertPHILoads(PHINode *PN, Function &F);
72 void replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
73 DenseMap<BasicBlock *, Value *> &Loads, Function &F);
David Majnemer8a1c45d2015-12-12 05:38:55 +000074 bool prepareExplicitEH(Function &F);
David Majnemer8a1c45d2015-12-12 05:38:55 +000075 void colorFunclets(Function &F);
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +000076
David Majnemerb3d9b962015-09-16 18:40:24 +000077 void demotePHIsOnFunclets(Function &F);
David Majnemer8a1c45d2015-12-12 05:38:55 +000078 void cloneCommonBlocks(Function &F);
David Majnemer3bb88c02015-12-15 21:27:27 +000079 void removeImplausibleInstructions(Function &F);
David Majnemerb3d9b962015-09-16 18:40:24 +000080 void cleanupPreparedFunclets(Function &F);
81 void verifyPreparedFunclets(Function &F);
David Majnemerfd9f4772015-08-11 01:15:26 +000082
Reid Kleckner0f9e27a2015-03-18 20:26:53 +000083 // All fields are reset by runOnFunction.
Reid Kleckner582786b2015-04-30 18:17:12 +000084 EHPersonality Personality = EHPersonality::Unknown;
David Majnemerfd9f4772015-08-11 01:15:26 +000085
David Majnemer8a1c45d2015-12-12 05:38:55 +000086 DenseMap<BasicBlock *, ColorVector> BlockColors;
87 MapVector<BasicBlock *, std::vector<BasicBlock *>> FuncletBlocks;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000088};
89
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000090} // end anonymous namespace
91
92char WinEHPrepare::ID = 0;
Reid Kleckner47c8e7a2015-03-12 00:36:20 +000093INITIALIZE_TM_PASS(WinEHPrepare, "winehprepare", "Prepare Windows exceptions",
94 false, false)
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000095
96FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
97 return new WinEHPrepare(TM);
98}
99
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000100bool WinEHPrepare::runOnFunction(Function &Fn) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000101 if (!Fn.hasPersonalityFn())
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000102 return false;
103
104 // Classify the personality to see what kind of preparation we need.
David Majnemer7fddecc2015-06-17 20:52:32 +0000105 Personality = classifyEHPersonality(Fn.getPersonalityFn());
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000106
Joseph Tremoulet2afea542015-10-06 20:28:16 +0000107 // Do nothing if this is not a funclet-based personality.
108 if (!isFuncletEHPersonality(Personality))
Reid Kleckner47c8e7a2015-03-12 00:36:20 +0000109 return false;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000110
David Majnemer8a1c45d2015-12-12 05:38:55 +0000111 return prepareExplicitEH(Fn);
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000112}
113
Andrew Kayloraa92ab02015-04-03 19:37:50 +0000114bool WinEHPrepare::doFinalization(Module &M) { return false; }
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000115
David Majnemere6965832015-10-16 19:59:52 +0000116void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {}
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000117
David Majnemer0ad363e2015-08-18 19:07:12 +0000118static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState,
David Majnemerbfa5b982015-10-10 00:04:29 +0000119 const BasicBlock *BB) {
Reid Kleckner14e77352015-10-09 23:34:53 +0000120 CxxUnwindMapEntry UME;
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000121 UME.ToState = ToState;
David Majnemerbfa5b982015-10-10 00:04:29 +0000122 UME.Cleanup = BB;
Reid Kleckner14e77352015-10-09 23:34:53 +0000123 FuncInfo.CxxUnwindMap.push_back(UME);
David Majnemer0ad363e2015-08-18 19:07:12 +0000124 return FuncInfo.getLastStateNumber();
125}
126
127static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
128 int TryHigh, int CatchHigh,
129 ArrayRef<const CatchPadInst *> Handlers) {
130 WinEHTryBlockMapEntry TBME;
131 TBME.TryLow = TryLow;
132 TBME.TryHigh = TryHigh;
133 TBME.CatchHigh = CatchHigh;
134 assert(TBME.TryLow <= TBME.TryHigh);
135 for (const CatchPadInst *CPI : Handlers) {
136 WinEHHandlerType HT;
137 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
Reid Klecknerb005d282015-09-16 20:16:27 +0000138 if (TypeInfo->isNullValue())
David Majnemer0ad363e2015-08-18 19:07:12 +0000139 HT.TypeDescriptor = nullptr;
Reid Klecknerb005d282015-09-16 20:16:27 +0000140 else
141 HT.TypeDescriptor = cast<GlobalVariable>(TypeInfo->stripPointerCasts());
142 HT.Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
David Majnemer7735a6d2015-10-06 23:31:59 +0000143 HT.Handler = CPI->getParent();
Reid Klecknerb005d282015-09-16 20:16:27 +0000144 if (isa<ConstantPointerNull>(CPI->getArgOperand(2)))
145 HT.CatchObj.Alloca = nullptr;
146 else
147 HT.CatchObj.Alloca = cast<AllocaInst>(CPI->getArgOperand(2));
David Majnemer0ad363e2015-08-18 19:07:12 +0000148 TBME.HandlerArray.push_back(HT);
149 }
150 FuncInfo.TryBlockMap.push_back(TBME);
151}
152
David Majnemer8a1c45d2015-12-12 05:38:55 +0000153static BasicBlock *getCleanupRetUnwindDest(const CleanupPadInst *CleanupPad) {
154 for (const User *U : CleanupPad->users())
155 if (const auto *CRI = dyn_cast<CleanupReturnInst>(U))
156 return CRI->getUnwindDest();
David Majnemer0ad363e2015-08-18 19:07:12 +0000157 return nullptr;
158}
159
David Majnemer8a1c45d2015-12-12 05:38:55 +0000160static void calculateStateNumbersForInvokes(const Function *Fn,
161 WinEHFuncInfo &FuncInfo) {
162 auto *F = const_cast<Function *>(Fn);
163 DenseMap<BasicBlock *, ColorVector> BlockColors = colorEHFunclets(*F);
164 for (BasicBlock &BB : *F) {
165 auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
166 if (!II)
167 continue;
168
169 auto &BBColors = BlockColors[&BB];
David Majnemerc640f862015-12-23 03:59:04 +0000170 assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
David Majnemer8a1c45d2015-12-12 05:38:55 +0000171 BasicBlock *FuncletEntryBB = BBColors.front();
172
173 BasicBlock *FuncletUnwindDest;
174 auto *FuncletPad =
175 dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI());
176 assert(FuncletPad || FuncletEntryBB == &Fn->getEntryBlock());
177 if (!FuncletPad)
178 FuncletUnwindDest = nullptr;
179 else if (auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
180 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
181 else if (auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad))
182 FuncletUnwindDest = getCleanupRetUnwindDest(CleanupPad);
183 else
184 llvm_unreachable("unexpected funclet pad!");
185
186 BasicBlock *InvokeUnwindDest = II->getUnwindDest();
187 int BaseState = -1;
188 if (FuncletUnwindDest == InvokeUnwindDest) {
189 auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad);
190 if (BaseStateI != FuncInfo.FuncletBaseStateMap.end())
191 BaseState = BaseStateI->second;
192 }
193
194 if (BaseState != -1) {
195 FuncInfo.InvokeStateMap[II] = BaseState;
196 } else {
197 Instruction *PadInst = InvokeUnwindDest->getFirstNonPHI();
198 assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!");
199 FuncInfo.InvokeStateMap[II] = FuncInfo.EHPadStateMap[PadInst];
200 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000201 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000202}
203
David Majnemer0ad363e2015-08-18 19:07:12 +0000204// Given BB which ends in an unwind edge, return the EHPad that this BB belongs
205// to. If the unwind edge came from an invoke, return null.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000206static const BasicBlock *getEHPadFromPredecessor(const BasicBlock *BB,
207 Value *ParentPad) {
David Majnemer0ad363e2015-08-18 19:07:12 +0000208 const TerminatorInst *TI = BB->getTerminator();
209 if (isa<InvokeInst>(TI))
210 return nullptr;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000211 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
212 if (CatchSwitch->getParentPad() != ParentPad)
213 return nullptr;
David Majnemer0ad363e2015-08-18 19:07:12 +0000214 return BB;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000215 }
216 assert(!TI->isEHPad() && "unexpected EHPad!");
217 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
218 if (CleanupPad->getParentPad() != ParentPad)
219 return nullptr;
220 return CleanupPad->getParent();
David Majnemer0ad363e2015-08-18 19:07:12 +0000221}
222
David Majnemer8a1c45d2015-12-12 05:38:55 +0000223static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo,
224 const Instruction *FirstNonPHI,
225 int ParentState) {
226 const BasicBlock *BB = FirstNonPHI->getParent();
227 assert(BB->isEHPad() && "not a funclet!");
David Majnemer0ad363e2015-08-18 19:07:12 +0000228
David Majnemer8a1c45d2015-12-12 05:38:55 +0000229 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
230 assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
231 "shouldn't revist catch funclets!");
232
David Majnemer0ad363e2015-08-18 19:07:12 +0000233 SmallVector<const CatchPadInst *, 2> Handlers;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000234 for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
235 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
236 Handlers.push_back(CatchPad);
237 }
David Majnemer0ad363e2015-08-18 19:07:12 +0000238 int TryLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000239 FuncInfo.EHPadStateMap[CatchSwitch] = TryLow;
240 for (const BasicBlock *PredBlock : predecessors(BB))
241 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
242 CatchSwitch->getParentPad())))
243 calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
244 TryLow);
David Majnemer0ad363e2015-08-18 19:07:12 +0000245 int CatchLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000246
247 // catchpads are separate funclets in C++ EH due to the way rethrow works.
David Majnemer0ad363e2015-08-18 19:07:12 +0000248 int TryHigh = CatchLow - 1;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000249 for (const auto *CatchPad : Handlers) {
250 FuncInfo.FuncletBaseStateMap[CatchPad] = CatchLow;
251 for (const User *U : CatchPad->users()) {
252 const auto *UserI = cast<Instruction>(U);
David Majnemerc640f862015-12-23 03:59:04 +0000253 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI))
254 if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest())
255 calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
256 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI))
257 if (getCleanupRetUnwindDest(InnerCleanupPad) ==
258 CatchSwitch->getUnwindDest())
259 calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000260 }
261 }
David Majnemer0ad363e2015-08-18 19:07:12 +0000262 int CatchHigh = FuncInfo.getLastStateNumber();
263 addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchHigh, Handlers);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000264 DEBUG(dbgs() << "TryLow[" << BB->getName() << "]: " << TryLow << '\n');
265 DEBUG(dbgs() << "TryHigh[" << BB->getName() << "]: " << TryHigh << '\n');
266 DEBUG(dbgs() << "CatchHigh[" << BB->getName() << "]: " << CatchHigh
David Majnemer0ad363e2015-08-18 19:07:12 +0000267 << '\n');
David Majnemer0ad363e2015-08-18 19:07:12 +0000268 } else {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000269 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
270
271 // It's possible for a cleanup to be visited twice: it might have multiple
272 // cleanupret instructions.
273 if (FuncInfo.EHPadStateMap.count(CleanupPad))
274 return;
275
276 int CleanupState = addUnwindMapEntry(FuncInfo, ParentState, BB);
277 FuncInfo.EHPadStateMap[CleanupPad] = CleanupState;
278 DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
279 << BB->getName() << '\n');
280 for (const BasicBlock *PredBlock : predecessors(BB)) {
281 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
282 CleanupPad->getParentPad()))) {
283 calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
284 CleanupState);
285 }
286 }
287 for (const User *U : CleanupPad->users()) {
288 const auto *UserI = cast<Instruction>(U);
289 if (UserI->isEHPad())
290 report_fatal_error("Cleanup funclets for the MSVC++ personality cannot "
291 "contain exceptional actions");
292 }
David Majnemer0ad363e2015-08-18 19:07:12 +0000293 }
294}
295
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000296static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState,
297 const Function *Filter, const BasicBlock *Handler) {
Reid Kleckner94b704c2015-09-09 21:10:03 +0000298 SEHUnwindMapEntry Entry;
299 Entry.ToState = ParentState;
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000300 Entry.IsFinally = false;
Reid Kleckner94b704c2015-09-09 21:10:03 +0000301 Entry.Filter = Filter;
302 Entry.Handler = Handler;
303 FuncInfo.SEHUnwindMap.push_back(Entry);
304 return FuncInfo.SEHUnwindMap.size() - 1;
305}
306
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000307static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState,
308 const BasicBlock *Handler) {
309 SEHUnwindMapEntry Entry;
310 Entry.ToState = ParentState;
311 Entry.IsFinally = true;
312 Entry.Filter = nullptr;
313 Entry.Handler = Handler;
314 FuncInfo.SEHUnwindMap.push_back(Entry);
315 return FuncInfo.SEHUnwindMap.size() - 1;
316}
317
David Majnemer8a1c45d2015-12-12 05:38:55 +0000318static void calculateSEHStateNumbers(WinEHFuncInfo &FuncInfo,
319 const Instruction *FirstNonPHI,
320 int ParentState) {
321 const BasicBlock *BB = FirstNonPHI->getParent();
322 assert(BB->isEHPad() && "no a funclet!");
Reid Kleckner94b704c2015-09-09 21:10:03 +0000323
David Majnemer8a1c45d2015-12-12 05:38:55 +0000324 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
325 assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
326 "shouldn't revist catch funclets!");
327
Reid Kleckner94b704c2015-09-09 21:10:03 +0000328 // Extract the filter function and the __except basic block and create a
329 // state for them.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000330 assert(CatchSwitch->getNumHandlers() == 1 &&
Reid Kleckner94b704c2015-09-09 21:10:03 +0000331 "SEH doesn't have multiple handlers per __try");
David Majnemer8a1c45d2015-12-12 05:38:55 +0000332 const auto *CatchPad =
333 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI());
334 const BasicBlock *CatchPadBB = CatchPad->getParent();
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000335 const Constant *FilterOrNull =
David Majnemer8a1c45d2015-12-12 05:38:55 +0000336 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000337 const Function *Filter = dyn_cast<Function>(FilterOrNull);
338 assert((Filter || FilterOrNull->isNullValue()) &&
339 "unexpected filter value");
David Majnemer7735a6d2015-10-06 23:31:59 +0000340 int TryState = addSEHExcept(FuncInfo, ParentState, Filter, CatchPadBB);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000341
342 // Everything in the __try block uses TryState as its parent state.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000343 FuncInfo.EHPadStateMap[CatchSwitch] = TryState;
Reid Kleckner94b704c2015-09-09 21:10:03 +0000344 DEBUG(dbgs() << "Assigning state #" << TryState << " to BB "
345 << CatchPadBB->getName() << '\n');
David Majnemer8a1c45d2015-12-12 05:38:55 +0000346 for (const BasicBlock *PredBlock : predecessors(BB))
347 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
348 CatchSwitch->getParentPad())))
349 calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
350 TryState);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000351
352 // Everything in the __except block unwinds to ParentState, just like code
353 // outside the __try.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000354 for (const User *U : CatchPad->users()) {
355 const auto *UserI = cast<Instruction>(U);
David Majnemerc640f862015-12-23 03:59:04 +0000356 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI))
357 if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest())
358 calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
359 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI))
360 if (getCleanupRetUnwindDest(InnerCleanupPad) ==
361 CatchSwitch->getUnwindDest())
362 calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000363 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000364 } else {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000365 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
366
367 // It's possible for a cleanup to be visited twice: it might have multiple
368 // cleanupret instructions.
369 if (FuncInfo.EHPadStateMap.count(CleanupPad))
370 return;
371
372 int CleanupState = addSEHFinally(FuncInfo, ParentState, BB);
373 FuncInfo.EHPadStateMap[CleanupPad] = CleanupState;
374 DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
375 << BB->getName() << '\n');
376 for (const BasicBlock *PredBlock : predecessors(BB))
377 if ((PredBlock =
378 getEHPadFromPredecessor(PredBlock, CleanupPad->getParentPad())))
379 calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
380 CleanupState);
381 for (const User *U : CleanupPad->users()) {
382 const auto *UserI = cast<Instruction>(U);
383 if (UserI->isEHPad())
384 report_fatal_error("Cleanup funclets for the SEH personality cannot "
385 "contain exceptional actions");
386 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000387 }
388}
389
David Majnemer8a1c45d2015-12-12 05:38:55 +0000390static bool isTopLevelPadForMSVC(const Instruction *EHPad) {
391 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
392 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
393 CatchSwitch->unwindsToCaller();
394 if (auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
395 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
396 getCleanupRetUnwindDest(CleanupPad) == nullptr;
397 if (isa<CatchPadInst>(EHPad))
398 return false;
399 llvm_unreachable("unexpected EHPad!");
Reid Kleckner94b704c2015-09-09 21:10:03 +0000400}
401
Reid Kleckner813f1b62015-09-16 22:14:46 +0000402void llvm::calculateSEHStateNumbers(const Function *Fn,
Reid Kleckner94b704c2015-09-09 21:10:03 +0000403 WinEHFuncInfo &FuncInfo) {
404 // Don't compute state numbers twice.
405 if (!FuncInfo.SEHUnwindMap.empty())
406 return;
407
Reid Kleckner813f1b62015-09-16 22:14:46 +0000408 for (const BasicBlock &BB : *Fn) {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000409 if (!BB.isEHPad())
Reid Kleckner94b704c2015-09-09 21:10:03 +0000410 continue;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000411 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
412 if (!isTopLevelPadForMSVC(FirstNonPHI))
413 continue;
414 ::calculateSEHStateNumbers(FuncInfo, FirstNonPHI, -1);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000415 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000416
417 calculateStateNumbersForInvokes(Fn, FuncInfo);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000418}
419
Reid Kleckner813f1b62015-09-16 22:14:46 +0000420void llvm::calculateWinCXXEHStateNumbers(const Function *Fn,
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000421 WinEHFuncInfo &FuncInfo) {
422 // Return if it's already been done.
David Majnemer0ad363e2015-08-18 19:07:12 +0000423 if (!FuncInfo.EHPadStateMap.empty())
424 return;
425
Reid Kleckner813f1b62015-09-16 22:14:46 +0000426 for (const BasicBlock &BB : *Fn) {
David Majnemer0ad363e2015-08-18 19:07:12 +0000427 if (!BB.isEHPad())
428 continue;
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000429 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
David Majnemer8a1c45d2015-12-12 05:38:55 +0000430 if (!isTopLevelPadForMSVC(FirstNonPHI))
David Majnemer0ad363e2015-08-18 19:07:12 +0000431 continue;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000432 calculateCXXStateNumbers(FuncInfo, FirstNonPHI, -1);
David Majnemer0ad363e2015-08-18 19:07:12 +0000433 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000434
435 calculateStateNumbersForInvokes(Fn, FuncInfo);
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000436}
David Majnemerfd9f4772015-08-11 01:15:26 +0000437
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000438static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int ParentState,
439 ClrHandlerType HandlerType, uint32_t TypeToken,
440 const BasicBlock *Handler) {
441 ClrEHUnwindMapEntry Entry;
442 Entry.Parent = ParentState;
443 Entry.Handler = Handler;
444 Entry.HandlerType = HandlerType;
445 Entry.TypeToken = TypeToken;
446 FuncInfo.ClrEHUnwindMap.push_back(Entry);
447 return FuncInfo.ClrEHUnwindMap.size() - 1;
448}
449
450void llvm::calculateClrEHStateNumbers(const Function *Fn,
451 WinEHFuncInfo &FuncInfo) {
452 // Return if it's already been done.
453 if (!FuncInfo.EHPadStateMap.empty())
454 return;
455
456 SmallVector<std::pair<const Instruction *, int>, 8> Worklist;
457
458 // Each pad needs to be able to refer to its parent, so scan the function
459 // looking for top-level handlers and seed the worklist with them.
460 for (const BasicBlock &BB : *Fn) {
461 if (!BB.isEHPad())
462 continue;
463 if (BB.isLandingPad())
464 report_fatal_error("CoreCLR EH cannot use landingpads");
465 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
David Majnemer8a1c45d2015-12-12 05:38:55 +0000466 if (!isTopLevelPadForMSVC(FirstNonPHI))
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000467 continue;
468 // queue this with sentinel parent state -1 to mean unwind to caller.
469 Worklist.emplace_back(FirstNonPHI, -1);
470 }
471
472 while (!Worklist.empty()) {
473 const Instruction *Pad;
474 int ParentState;
475 std::tie(Pad, ParentState) = Worklist.pop_back_val();
476
David Majnemer8a1c45d2015-12-12 05:38:55 +0000477 Value *ParentPad;
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000478 int PredState;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000479 if (const CleanupPadInst *Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000480 // A cleanup can have multiple exits; don't re-process after the first.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000481 if (FuncInfo.EHPadStateMap.count(Cleanup))
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000482 continue;
483 // CoreCLR personality uses arity to distinguish faults from finallies.
484 const BasicBlock *PadBlock = Cleanup->getParent();
485 ClrHandlerType HandlerType =
486 (Cleanup->getNumOperands() ? ClrHandlerType::Fault
487 : ClrHandlerType::Finally);
488 int NewState =
489 addClrEHHandler(FuncInfo, ParentState, HandlerType, 0, PadBlock);
490 FuncInfo.EHPadStateMap[Cleanup] = NewState;
491 // Propagate the new state to all preds of the cleanup
David Majnemer8a1c45d2015-12-12 05:38:55 +0000492 ParentPad = Cleanup->getParentPad();
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000493 PredState = NewState;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000494 } else if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(Pad)) {
495 SmallVector<const CatchPadInst *, 1> Handlers;
496 for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
497 const auto *Catch = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
498 Handlers.push_back(Catch);
499 }
500 FuncInfo.EHPadStateMap[CatchSwitch] = ParentState;
501 int NewState = ParentState;
502 for (auto HandlerI = Handlers.rbegin(), HandlerE = Handlers.rend();
503 HandlerI != HandlerE; ++HandlerI) {
504 const CatchPadInst *Catch = *HandlerI;
505 const BasicBlock *PadBlock = Catch->getParent();
506 uint32_t TypeToken = static_cast<uint32_t>(
507 cast<ConstantInt>(Catch->getArgOperand(0))->getZExtValue());
508 NewState = addClrEHHandler(FuncInfo, NewState, ClrHandlerType::Catch,
509 TypeToken, PadBlock);
510 FuncInfo.EHPadStateMap[Catch] = NewState;
511 }
512 for (const auto *CatchPad : Handlers) {
513 for (const User *U : CatchPad->users()) {
514 const auto *UserI = cast<Instruction>(U);
515 if (UserI->isEHPad())
516 Worklist.emplace_back(UserI, ParentState);
517 }
518 }
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000519 PredState = NewState;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000520 ParentPad = CatchSwitch->getParentPad();
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000521 } else {
522 llvm_unreachable("Unexpected EH pad");
523 }
524
525 // Queue all predecessors with the given state
526 for (const BasicBlock *Pred : predecessors(Pad->getParent())) {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000527 if ((Pred = getEHPadFromPredecessor(Pred, ParentPad)))
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000528 Worklist.emplace_back(Pred->getFirstNonPHI(), PredState);
529 }
530 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000531
532 calculateStateNumbersForInvokes(Fn, FuncInfo);
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000533}
534
David Majnemer8a1c45d2015-12-12 05:38:55 +0000535void WinEHPrepare::colorFunclets(Function &F) {
536 BlockColors = colorEHFunclets(F);
David Majnemerfd9f4772015-08-11 01:15:26 +0000537
David Majnemer8a1c45d2015-12-12 05:38:55 +0000538 // Invert the map from BB to colors to color to BBs.
539 for (BasicBlock &BB : F) {
540 ColorVector &Colors = BlockColors[&BB];
541 for (BasicBlock *Color : Colors)
542 FuncletBlocks[Color].push_back(&BB);
David Majnemerfd9f4772015-08-11 01:15:26 +0000543 }
544}
545
David Majnemerf828a0c2015-10-01 18:44:59 +0000546void llvm::calculateCatchReturnSuccessorColors(const Function *Fn,
547 WinEHFuncInfo &FuncInfo) {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000548 for (const BasicBlock &BB : *Fn) {
549 const auto *CatchRet = dyn_cast<CatchReturnInst>(BB.getTerminator());
550 if (!CatchRet)
David Majnemerf828a0c2015-10-01 18:44:59 +0000551 continue;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000552 // A 'catchret' returns to the outer scope's color.
553 Value *ParentPad = CatchRet->getParentPad();
554 const BasicBlock *Color;
555 if (isa<ConstantTokenNone>(ParentPad))
556 Color = &Fn->getEntryBlock();
557 else
558 Color = cast<Instruction>(ParentPad)->getParent();
559 // Record the catchret successor's funclet membership.
560 FuncInfo.CatchRetSuccessorColorMap[CatchRet] = Color;
David Majnemerf828a0c2015-10-01 18:44:59 +0000561 }
562}
563
David Majnemerb3d9b962015-09-16 18:40:24 +0000564void WinEHPrepare::demotePHIsOnFunclets(Function &F) {
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000565 // Strip PHI nodes off of EH pads.
566 SmallVector<PHINode *, 16> PHINodes;
David Majnemerfd9f4772015-08-11 01:15:26 +0000567 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000568 BasicBlock *BB = &*FI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000569 if (!BB->isEHPad())
570 continue;
David Majnemerfd9f4772015-08-11 01:15:26 +0000571 for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000572 Instruction *I = &*BI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000573 auto *PN = dyn_cast<PHINode>(I);
574 // Stop at the first non-PHI.
575 if (!PN)
576 break;
David Majnemerfd9f4772015-08-11 01:15:26 +0000577
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000578 AllocaInst *SpillSlot = insertPHILoads(PN, F);
579 if (SpillSlot)
580 insertPHIStores(PN, SpillSlot);
581
582 PHINodes.push_back(PN);
David Majnemerfd9f4772015-08-11 01:15:26 +0000583 }
584 }
585
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000586 for (auto *PN : PHINodes) {
587 // There may be lingering uses on other EH PHIs being removed
588 PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
589 PN->eraseFromParent();
David Majnemerfd9f4772015-08-11 01:15:26 +0000590 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000591}
David Majnemerfd9f4772015-08-11 01:15:26 +0000592
David Majnemer8a1c45d2015-12-12 05:38:55 +0000593void WinEHPrepare::cloneCommonBlocks(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000594 // We need to clone all blocks which belong to multiple funclets. Values are
595 // remapped throughout the funclet to propogate both the new instructions
596 // *and* the new basic blocks themselves.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000597 for (auto &Funclets : FuncletBlocks) {
598 BasicBlock *FuncletPadBB = Funclets.first;
599 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
David Majnemerfd9f4772015-08-11 01:15:26 +0000600
David Majnemer8a1c45d2015-12-12 05:38:55 +0000601 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
David Majnemerfd9f4772015-08-11 01:15:26 +0000602 ValueToValueMapTy VMap;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000603 for (BasicBlock *BB : BlocksInFunclet) {
604 ColorVector &ColorsForBB = BlockColors[BB];
David Majnemerfd9f4772015-08-11 01:15:26 +0000605 // We don't need to do anything if the block is monochromatic.
606 size_t NumColorsForBB = ColorsForBB.size();
607 if (NumColorsForBB == 1)
608 continue;
609
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +0000610 DEBUG_WITH_TYPE("winehprepare-coloring",
611 dbgs() << " Cloning block \'" << BB->getName()
612 << "\' for funclet \'" << FuncletPadBB->getName()
613 << "\'.\n");
614
David Majnemerfd9f4772015-08-11 01:15:26 +0000615 // Create a new basic block and copy instructions into it!
Joseph Tremouletec182852015-08-28 01:12:35 +0000616 BasicBlock *CBB =
617 CloneBasicBlock(BB, VMap, Twine(".for.", FuncletPadBB->getName()));
618 // Insert the clone immediately after the original to ensure determinism
619 // and to keep the same relative ordering of any funclet's blocks.
620 CBB->insertInto(&F, BB->getNextNode());
David Majnemerfd9f4772015-08-11 01:15:26 +0000621
622 // Add basic block mapping.
623 VMap[BB] = CBB;
624
625 // Record delta operations that we need to perform to our color mappings.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000626 Orig2Clone.emplace_back(BB, CBB);
David Majnemerfd9f4772015-08-11 01:15:26 +0000627 }
628
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000629 // If nothing was cloned, we're done cloning in this funclet.
630 if (Orig2Clone.empty())
631 continue;
632
David Majnemerfd9f4772015-08-11 01:15:26 +0000633 // Update our color mappings to reflect that one block has lost a color and
634 // another has gained a color.
635 for (auto &BBMapping : Orig2Clone) {
636 BasicBlock *OldBlock = BBMapping.first;
637 BasicBlock *NewBlock = BBMapping.second;
638
David Majnemer8a1c45d2015-12-12 05:38:55 +0000639 BlocksInFunclet.push_back(NewBlock);
640 ColorVector &NewColors = BlockColors[NewBlock];
641 assert(NewColors.empty() && "A new block should only have one color!");
642 NewColors.push_back(FuncletPadBB);
David Majnemerfd9f4772015-08-11 01:15:26 +0000643
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +0000644 DEBUG_WITH_TYPE("winehprepare-coloring",
645 dbgs() << " Assigned color \'" << FuncletPadBB->getName()
646 << "\' to block \'" << NewBlock->getName()
647 << "\'.\n");
648
David Majnemer8a1c45d2015-12-12 05:38:55 +0000649 BlocksInFunclet.erase(
650 std::remove(BlocksInFunclet.begin(), BlocksInFunclet.end(), OldBlock),
651 BlocksInFunclet.end());
652 ColorVector &OldColors = BlockColors[OldBlock];
653 OldColors.erase(
654 std::remove(OldColors.begin(), OldColors.end(), FuncletPadBB),
655 OldColors.end());
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +0000656
657 DEBUG_WITH_TYPE("winehprepare-coloring",
658 dbgs() << " Removed color \'" << FuncletPadBB->getName()
659 << "\' from block \'" << OldBlock->getName()
660 << "\'.\n");
David Majnemerfd9f4772015-08-11 01:15:26 +0000661 }
662
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000663 // Loop over all of the instructions in this funclet, fixing up operand
David Majnemerfd9f4772015-08-11 01:15:26 +0000664 // references as we go. This uses VMap to do all the hard work.
665 for (BasicBlock *BB : BlocksInFunclet)
666 // Loop over all instructions, fixing each one as we find it...
667 for (Instruction &I : *BB)
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000668 RemapInstruction(&I, VMap,
669 RF_IgnoreMissingEntries | RF_NoModuleLevelChanges);
David Majnemer459a64a2015-09-16 18:40:37 +0000670
David Majnemer8a1c45d2015-12-12 05:38:55 +0000671 auto UpdatePHIOnClonedBlock = [&](PHINode *PN, bool IsForOldBlock) {
672 unsigned NumPreds = PN->getNumIncomingValues();
673 for (unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
674 ++PredIdx) {
675 BasicBlock *IncomingBlock = PN->getIncomingBlock(PredIdx);
676 ColorVector &IncomingColors = BlockColors[IncomingBlock];
677 bool BlockInFunclet = IncomingColors.size() == 1 &&
678 IncomingColors.front() == FuncletPadBB;
679 if (IsForOldBlock != BlockInFunclet)
680 continue;
681 PN->removeIncomingValue(IncomingBlock, /*DeletePHIIfEmpty=*/false);
682 // Revisit the next entry.
683 --PredIdx;
684 --PredEnd;
685 }
686 };
687
688 for (auto &BBMapping : Orig2Clone) {
689 BasicBlock *OldBlock = BBMapping.first;
690 BasicBlock *NewBlock = BBMapping.second;
691 for (Instruction &OldI : *OldBlock) {
692 auto *OldPN = dyn_cast<PHINode>(&OldI);
693 if (!OldPN)
694 break;
695 UpdatePHIOnClonedBlock(OldPN, /*IsForOldBlock=*/true);
696 }
697 for (Instruction &NewI : *NewBlock) {
698 auto *NewPN = dyn_cast<PHINode>(&NewI);
699 if (!NewPN)
700 break;
701 UpdatePHIOnClonedBlock(NewPN, /*IsForOldBlock=*/false);
702 }
703 }
704
David Majnemer459a64a2015-09-16 18:40:37 +0000705 // Check to see if SuccBB has PHI nodes. If so, we need to add entries to
706 // the PHI nodes for NewBB now.
707 for (auto &BBMapping : Orig2Clone) {
708 BasicBlock *OldBlock = BBMapping.first;
709 BasicBlock *NewBlock = BBMapping.second;
710 for (BasicBlock *SuccBB : successors(NewBlock)) {
711 for (Instruction &SuccI : *SuccBB) {
712 auto *SuccPN = dyn_cast<PHINode>(&SuccI);
713 if (!SuccPN)
714 break;
715
716 // Ok, we have a PHI node. Figure out what the incoming value was for
717 // the OldBlock.
718 int OldBlockIdx = SuccPN->getBasicBlockIndex(OldBlock);
719 if (OldBlockIdx == -1)
720 break;
721 Value *IV = SuccPN->getIncomingValue(OldBlockIdx);
722
723 // Remap the value if necessary.
724 if (auto *Inst = dyn_cast<Instruction>(IV)) {
725 ValueToValueMapTy::iterator I = VMap.find(Inst);
726 if (I != VMap.end())
727 IV = I->second;
728 }
729
730 SuccPN->addIncoming(IV, NewBlock);
731 }
732 }
733 }
734
735 for (ValueToValueMapTy::value_type VT : VMap) {
736 // If there were values defined in BB that are used outside the funclet,
737 // then we now have to update all uses of the value to use either the
738 // original value, the cloned value, or some PHI derived value. This can
739 // require arbitrary PHI insertion, of which we are prepared to do, clean
740 // these up now.
741 SmallVector<Use *, 16> UsesToRename;
742
743 auto *OldI = dyn_cast<Instruction>(const_cast<Value *>(VT.first));
744 if (!OldI)
745 continue;
746 auto *NewI = cast<Instruction>(VT.second);
747 // Scan all uses of this instruction to see if it is used outside of its
748 // funclet, and if so, record them in UsesToRename.
749 for (Use &U : OldI->uses()) {
750 Instruction *UserI = cast<Instruction>(U.getUser());
751 BasicBlock *UserBB = UserI->getParent();
David Majnemer8a1c45d2015-12-12 05:38:55 +0000752 ColorVector &ColorsForUserBB = BlockColors[UserBB];
David Majnemer459a64a2015-09-16 18:40:37 +0000753 assert(!ColorsForUserBB.empty());
754 if (ColorsForUserBB.size() > 1 ||
755 *ColorsForUserBB.begin() != FuncletPadBB)
756 UsesToRename.push_back(&U);
757 }
758
759 // If there are no uses outside the block, we're done with this
760 // instruction.
761 if (UsesToRename.empty())
762 continue;
763
764 // We found a use of OldI outside of the funclet. Rename all uses of OldI
765 // that are outside its funclet to be uses of the appropriate PHI node
766 // etc.
767 SSAUpdater SSAUpdate;
768 SSAUpdate.Initialize(OldI->getType(), OldI->getName());
769 SSAUpdate.AddAvailableValue(OldI->getParent(), OldI);
770 SSAUpdate.AddAvailableValue(NewI->getParent(), NewI);
771
772 while (!UsesToRename.empty())
773 SSAUpdate.RewriteUseAfterInsertions(*UsesToRename.pop_back_val());
774 }
David Majnemerfd9f4772015-08-11 01:15:26 +0000775 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000776}
David Majnemerfd9f4772015-08-11 01:15:26 +0000777
David Majnemer3bb88c02015-12-15 21:27:27 +0000778void WinEHPrepare::removeImplausibleInstructions(Function &F) {
David Majnemer83f4bb22015-08-17 20:56:39 +0000779 // Remove implausible terminators and replace them with UnreachableInst.
780 for (auto &Funclet : FuncletBlocks) {
781 BasicBlock *FuncletPadBB = Funclet.first;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000782 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
David Majnemer3bb88c02015-12-15 21:27:27 +0000783 Instruction *FirstNonPHI = FuncletPadBB->getFirstNonPHI();
784 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
785 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
786 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
David Majnemer83f4bb22015-08-17 20:56:39 +0000787
788 for (BasicBlock *BB : BlocksInFunclet) {
David Majnemer3bb88c02015-12-15 21:27:27 +0000789 for (Instruction &I : *BB) {
790 CallSite CS(&I);
791 if (!CS)
792 continue;
793
794 Value *FuncletBundleOperand = nullptr;
795 if (auto BU = CS.getOperandBundle(LLVMContext::OB_funclet))
796 FuncletBundleOperand = BU->Inputs.front();
797
798 if (FuncletBundleOperand == FuncletPad)
799 continue;
800
801 // Skip call sites which are nounwind intrinsics.
802 auto *CalledFn =
803 dyn_cast<Function>(CS.getCalledValue()->stripPointerCasts());
804 if (CalledFn && CalledFn->isIntrinsic() && CS.doesNotThrow())
805 continue;
806
807 // This call site was not part of this funclet, remove it.
808 if (CS.isInvoke()) {
809 // Remove the unwind edge if it was an invoke.
810 removeUnwindEdge(BB);
811 // Get a pointer to the new call.
812 BasicBlock::iterator CallI =
813 std::prev(BB->getTerminator()->getIterator());
814 auto *CI = cast<CallInst>(&*CallI);
815 changeToUnreachable(CI, /*UseLLVMTrap=*/false);
816 } else {
817 changeToUnreachable(&I, /*UseLLVMTrap=*/false);
818 }
819
820 // There are no more instructions in the block (except for unreachable),
821 // we are done.
822 break;
823 }
824
David Majnemer83f4bb22015-08-17 20:56:39 +0000825 TerminatorInst *TI = BB->getTerminator();
826 // CatchPadInst and CleanupPadInst can't transfer control to a ReturnInst.
David Majnemer3bb88c02015-12-15 21:27:27 +0000827 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
David Majnemer83f4bb22015-08-17 20:56:39 +0000828 // The token consumed by a CatchReturnInst must match the funclet token.
829 bool IsUnreachableCatchret = false;
830 if (auto *CRI = dyn_cast<CatchReturnInst>(TI))
Joseph Tremoulet8220bcc2015-08-23 00:26:33 +0000831 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000832 // The token consumed by a CleanupReturnInst must match the funclet token.
David Majnemer83f4bb22015-08-17 20:56:39 +0000833 bool IsUnreachableCleanupret = false;
834 if (auto *CRI = dyn_cast<CleanupReturnInst>(TI))
Joseph Tremoulet8220bcc2015-08-23 00:26:33 +0000835 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000836 if (IsUnreachableRet || IsUnreachableCatchret ||
David Majnemer8a1c45d2015-12-12 05:38:55 +0000837 IsUnreachableCleanupret) {
David Majnemer3bb88c02015-12-15 21:27:27 +0000838 changeToUnreachable(TI, /*UseLLVMTrap=*/false);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000839 } else if (isa<InvokeInst>(TI)) {
David Majnemer3bb88c02015-12-15 21:27:27 +0000840 if (Personality == EHPersonality::MSVC_CXX && CleanupPad) {
841 // Invokes within a cleanuppad for the MSVC++ personality never
842 // transfer control to their unwind edge: the personality will
843 // terminate the program.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000844 removeUnwindEdge(BB);
David Majnemer3bb88c02015-12-15 21:27:27 +0000845 }
David Majnemer83f4bb22015-08-17 20:56:39 +0000846 }
847 }
848 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000849}
David Majnemer83f4bb22015-08-17 20:56:39 +0000850
David Majnemerb3d9b962015-09-16 18:40:24 +0000851void WinEHPrepare::cleanupPreparedFunclets(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000852 // Clean-up some of the mess we made by removing useles PHI nodes, trivial
853 // branches, etc.
854 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000855 BasicBlock *BB = &*FI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000856 SimplifyInstructionsInBlock(BB);
857 ConstantFoldTerminator(BB, /*DeleteDeadConditions=*/true);
858 MergeBlockIntoPredecessor(BB);
859 }
860
David Majnemerfd9f4772015-08-11 01:15:26 +0000861 // We might have some unreachable blocks after cleaning up some impossible
862 // control flow.
863 removeUnreachableBlocks(F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000864}
David Majnemerfd9f4772015-08-11 01:15:26 +0000865
David Majnemerb3d9b962015-09-16 18:40:24 +0000866void WinEHPrepare::verifyPreparedFunclets(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000867 // Recolor the CFG to verify that all is well.
868 for (BasicBlock &BB : F) {
869 size_t NumColors = BlockColors[&BB].size();
870 assert(NumColors == 1 && "Expected monochromatic BB!");
871 if (NumColors == 0)
872 report_fatal_error("Uncolored BB!");
873 if (NumColors > 1)
874 report_fatal_error("Multicolor BB!");
David Majnemer8a1c45d2015-12-12 05:38:55 +0000875 if (!DisableDemotion) {
876 bool EHPadHasPHI = BB.isEHPad() && isa<PHINode>(BB.begin());
877 assert(!EHPadHasPHI && "EH Pad still has a PHI!");
878 if (EHPadHasPHI)
879 report_fatal_error("EH Pad still has a PHI!");
880 }
David Majnemerfd9f4772015-08-11 01:15:26 +0000881 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000882}
883
David Majnemer8a1c45d2015-12-12 05:38:55 +0000884bool WinEHPrepare::prepareExplicitEH(Function &F) {
885 // Remove unreachable blocks. It is not valuable to assign them a color and
886 // their existence can trick us into thinking values are alive when they are
887 // not.
888 removeUnreachableBlocks(F);
889
David Majnemerb3d9b962015-09-16 18:40:24 +0000890 // Determine which blocks are reachable from which funclet entries.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000891 colorFunclets(F);
892
893 cloneCommonBlocks(F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000894
Reid Klecknercc2f6c32015-11-19 23:23:33 +0000895 if (!DisableDemotion)
David Majnemer459a64a2015-09-16 18:40:37 +0000896 demotePHIsOnFunclets(F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000897
David Majnemer459a64a2015-09-16 18:40:37 +0000898 if (!DisableCleanups) {
David Majnemer3bb88c02015-12-15 21:27:27 +0000899 removeImplausibleInstructions(F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000900
David Majnemer459a64a2015-09-16 18:40:37 +0000901 cleanupPreparedFunclets(F);
902 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000903
904 verifyPreparedFunclets(F);
David Majnemerfd9f4772015-08-11 01:15:26 +0000905
906 BlockColors.clear();
907 FuncletBlocks.clear();
David Majnemer0ad363e2015-08-18 19:07:12 +0000908
David Majnemerfd9f4772015-08-11 01:15:26 +0000909 return true;
910}
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000911
912// TODO: Share loads when one use dominates another, or when a catchpad exit
913// dominates uses (needs dominators).
914AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) {
915 BasicBlock *PHIBlock = PN->getParent();
916 AllocaInst *SpillSlot = nullptr;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000917 Instruction *EHPad = PHIBlock->getFirstNonPHI();
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000918
David Majnemer8a1c45d2015-12-12 05:38:55 +0000919 if (!isa<TerminatorInst>(EHPad)) {
920 // If the EHPad isn't a terminator, then we can insert a load in this block
921 // that will dominate all uses.
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000922 SpillSlot = new AllocaInst(PN->getType(), nullptr,
923 Twine(PN->getName(), ".wineh.spillslot"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000924 &F.getEntryBlock().front());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000925 Value *V = new LoadInst(SpillSlot, Twine(PN->getName(), ".wineh.reload"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000926 &*PHIBlock->getFirstInsertionPt());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000927 PN->replaceAllUsesWith(V);
928 return SpillSlot;
929 }
930
David Majnemer8a1c45d2015-12-12 05:38:55 +0000931 // Otherwise, we have a PHI on a terminator EHPad, and we give up and insert
932 // loads of the slot before every use.
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000933 DenseMap<BasicBlock *, Value *> Loads;
934 for (Value::use_iterator UI = PN->use_begin(), UE = PN->use_end();
935 UI != UE;) {
936 Use &U = *UI++;
937 auto *UsingInst = cast<Instruction>(U.getUser());
David Majnemer8a1c45d2015-12-12 05:38:55 +0000938 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000939 // Use is on an EH pad phi. Leave it alone; we'll insert loads and
940 // stores for it separately.
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000941 continue;
942 }
943 replaceUseWithLoad(PN, U, SpillSlot, Loads, F);
944 }
945 return SpillSlot;
946}
947
948// TODO: improve store placement. Inserting at def is probably good, but need
949// to be careful not to introduce interfering stores (needs liveness analysis).
950// TODO: identify related phi nodes that can share spill slots, and share them
951// (also needs liveness).
952void WinEHPrepare::insertPHIStores(PHINode *OriginalPHI,
953 AllocaInst *SpillSlot) {
954 // Use a worklist of (Block, Value) pairs -- the given Value needs to be
955 // stored to the spill slot by the end of the given Block.
956 SmallVector<std::pair<BasicBlock *, Value *>, 4> Worklist;
957
958 Worklist.push_back({OriginalPHI->getParent(), OriginalPHI});
959
960 while (!Worklist.empty()) {
961 BasicBlock *EHBlock;
962 Value *InVal;
963 std::tie(EHBlock, InVal) = Worklist.pop_back_val();
964
965 PHINode *PN = dyn_cast<PHINode>(InVal);
966 if (PN && PN->getParent() == EHBlock) {
967 // The value is defined by another PHI we need to remove, with no room to
968 // insert a store after the PHI, so each predecessor needs to store its
969 // incoming value.
970 for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
971 Value *PredVal = PN->getIncomingValue(i);
972
973 // Undef can safely be skipped.
974 if (isa<UndefValue>(PredVal))
975 continue;
976
977 insertPHIStore(PN->getIncomingBlock(i), PredVal, SpillSlot, Worklist);
978 }
979 } else {
980 // We need to store InVal, which dominates EHBlock, but can't put a store
981 // in EHBlock, so need to put stores in each predecessor.
982 for (BasicBlock *PredBlock : predecessors(EHBlock)) {
983 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
984 }
985 }
986 }
987}
988
989void WinEHPrepare::insertPHIStore(
990 BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
991 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist) {
992
993 if (PredBlock->isEHPad() &&
David Majnemer8a1c45d2015-12-12 05:38:55 +0000994 isa<TerminatorInst>(PredBlock->getFirstNonPHI())) {
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000995 // Pred is unsplittable, so we need to queue it on the worklist.
996 Worklist.push_back({PredBlock, PredVal});
997 return;
998 }
999
1000 // Otherwise, insert the store at the end of the basic block.
1001 new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator());
1002}
1003
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001004void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
1005 DenseMap<BasicBlock *, Value *> &Loads,
1006 Function &F) {
1007 // Lazilly create the spill slot.
1008 if (!SpillSlot)
1009 SpillSlot = new AllocaInst(V->getType(), nullptr,
1010 Twine(V->getName(), ".wineh.spillslot"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001011 &F.getEntryBlock().front());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001012
1013 auto *UsingInst = cast<Instruction>(U.getUser());
1014 if (auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1015 // If this is a PHI node, we can't insert a load of the value before
1016 // the use. Instead insert the load in the predecessor block
1017 // corresponding to the incoming value.
1018 //
1019 // Note that if there are multiple edges from a basic block to this
1020 // PHI node that we cannot have multiple loads. The problem is that
1021 // the resulting PHI node will have multiple values (from each load)
1022 // coming in from the same block, which is illegal SSA form.
1023 // For this reason, we keep track of and reuse loads we insert.
1024 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
Joseph Tremoulet7031c9f2015-08-17 13:51:37 +00001025 if (auto *CatchRet =
1026 dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) {
1027 // Putting a load above a catchret and use on the phi would still leave
1028 // a cross-funclet def/use. We need to split the edge, change the
1029 // catchret to target the new block, and put the load there.
1030 BasicBlock *PHIBlock = UsingInst->getParent();
1031 BasicBlock *NewBlock = SplitEdge(IncomingBlock, PHIBlock);
1032 // SplitEdge gives us:
1033 // IncomingBlock:
1034 // ...
1035 // br label %NewBlock
1036 // NewBlock:
1037 // catchret label %PHIBlock
1038 // But we need:
1039 // IncomingBlock:
1040 // ...
1041 // catchret label %NewBlock
1042 // NewBlock:
1043 // br label %PHIBlock
1044 // So move the terminators to each others' blocks and swap their
1045 // successors.
1046 BranchInst *Goto = cast<BranchInst>(IncomingBlock->getTerminator());
1047 Goto->removeFromParent();
1048 CatchRet->removeFromParent();
1049 IncomingBlock->getInstList().push_back(CatchRet);
1050 NewBlock->getInstList().push_back(Goto);
1051 Goto->setSuccessor(0, PHIBlock);
1052 CatchRet->setSuccessor(NewBlock);
1053 // Update the color mapping for the newly split edge.
David Majnemer8a1c45d2015-12-12 05:38:55 +00001054 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
Joseph Tremoulet7031c9f2015-08-17 13:51:37 +00001055 BlockColors[NewBlock] = ColorsForPHIBlock;
1056 for (BasicBlock *FuncletPad : ColorsForPHIBlock)
David Majnemer8a1c45d2015-12-12 05:38:55 +00001057 FuncletBlocks[FuncletPad].push_back(NewBlock);
Joseph Tremoulet7031c9f2015-08-17 13:51:37 +00001058 // Treat the new block as incoming for load insertion.
1059 IncomingBlock = NewBlock;
1060 }
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001061 Value *&Load = Loads[IncomingBlock];
1062 // Insert the load into the predecessor block
1063 if (!Load)
1064 Load = new LoadInst(SpillSlot, Twine(V->getName(), ".wineh.reload"),
1065 /*Volatile=*/false, IncomingBlock->getTerminator());
1066
1067 U.set(Load);
1068 } else {
1069 // Reload right before the old use.
1070 auto *Load = new LoadInst(SpillSlot, Twine(V->getName(), ".wineh.reload"),
1071 /*Volatile=*/false, UsingInst);
1072 U.set(Load);
1073 }
1074}
Reid Klecknerc71d6272015-09-28 23:56:30 +00001075
David Majnemer8a1c45d2015-12-12 05:38:55 +00001076void WinEHFuncInfo::addIPToStateRange(const InvokeInst *II,
Reid Klecknerc71d6272015-09-28 23:56:30 +00001077 MCSymbol *InvokeBegin,
1078 MCSymbol *InvokeEnd) {
David Majnemer8a1c45d2015-12-12 05:38:55 +00001079 assert(InvokeStateMap.count(II) &&
1080 "should get invoke with precomputed state");
1081 LabelToStateMap[InvokeBegin] = std::make_pair(InvokeStateMap[II], InvokeEnd);
Reid Klecknerc71d6272015-09-28 23:56:30 +00001082}
Chandler Carruthe0115342015-12-29 09:24:39 +00001083
1084WinEHFuncInfo::WinEHFuncInfo() {}