blob: 83507894b49d7d87f548c0ce57d4484bdf72311e [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"
David Majnemerdbdc9c22016-01-02 09:26:36 +000025#include "llvm/IR/Verifier.h"
Chandler Carruthe0115342015-12-29 09:24:39 +000026#include "llvm/MC/MCSymbol.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000027#include "llvm/Pass.h"
Andrew Kaylor6b67d422015-03-11 23:22:06 +000028#include "llvm/Support/Debug.h"
Benjamin Kramera8d61b12015-03-23 18:57:17 +000029#include "llvm/Support/raw_ostream.h"
Andrew Kaylor6b67d422015-03-11 23:22:06 +000030#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000031#include "llvm/Transforms/Utils/Cloning.h"
32#include "llvm/Transforms/Utils/Local.h"
David Majnemer459a64a2015-09-16 18:40:37 +000033#include "llvm/Transforms/Utils/SSAUpdater.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000034
35using namespace llvm;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000036
37#define DEBUG_TYPE "winehprepare"
38
David Majnemer459a64a2015-09-16 18:40:37 +000039static cl::opt<bool> DisableDemotion(
40 "disable-demotion", cl::Hidden,
41 cl::desc(
42 "Clone multicolor basic blocks but do not demote cross funclet values"),
43 cl::init(false));
44
45static cl::opt<bool> DisableCleanups(
46 "disable-cleanups", cl::Hidden,
47 cl::desc("Do not remove implausible terminators or other similar cleanups"),
48 cl::init(false));
49
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000050namespace {
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +000051
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000052class WinEHPrepare : public FunctionPass {
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000053public:
54 static char ID; // Pass identification, replacement for typeid.
David Majnemere6965832015-10-16 19:59:52 +000055 WinEHPrepare(const TargetMachine *TM = nullptr) : FunctionPass(ID) {}
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000056
57 bool runOnFunction(Function &Fn) override;
58
59 bool doFinalization(Module &M) override;
60
61 void getAnalysisUsage(AnalysisUsage &AU) const override;
62
63 const char *getPassName() const override {
64 return "Windows exception handling preparation";
65 }
66
67private:
Joseph Tremouletc9ff9142015-08-13 14:30:10 +000068 void insertPHIStores(PHINode *OriginalPHI, AllocaInst *SpillSlot);
69 void
70 insertPHIStore(BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
71 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist);
72 AllocaInst *insertPHILoads(PHINode *PN, Function &F);
73 void replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
74 DenseMap<BasicBlock *, Value *> &Loads, Function &F);
David Majnemer8a1c45d2015-12-12 05:38:55 +000075 bool prepareExplicitEH(Function &F);
David Majnemer8a1c45d2015-12-12 05:38:55 +000076 void colorFunclets(Function &F);
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +000077
David Majnemerb3d9b962015-09-16 18:40:24 +000078 void demotePHIsOnFunclets(Function &F);
David Majnemer8a1c45d2015-12-12 05:38:55 +000079 void cloneCommonBlocks(Function &F);
David Majnemer3bb88c02015-12-15 21:27:27 +000080 void removeImplausibleInstructions(Function &F);
David Majnemerb3d9b962015-09-16 18:40:24 +000081 void cleanupPreparedFunclets(Function &F);
82 void verifyPreparedFunclets(Function &F);
David Majnemerfd9f4772015-08-11 01:15:26 +000083
Reid Kleckner0f9e27a2015-03-18 20:26:53 +000084 // All fields are reset by runOnFunction.
Reid Kleckner582786b2015-04-30 18:17:12 +000085 EHPersonality Personality = EHPersonality::Unknown;
David Majnemerfd9f4772015-08-11 01:15:26 +000086
David Majnemer8a1c45d2015-12-12 05:38:55 +000087 DenseMap<BasicBlock *, ColorVector> BlockColors;
88 MapVector<BasicBlock *, std::vector<BasicBlock *>> FuncletBlocks;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000089};
90
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000091} // end anonymous namespace
92
93char WinEHPrepare::ID = 0;
Reid Kleckner47c8e7a2015-03-12 00:36:20 +000094INITIALIZE_TM_PASS(WinEHPrepare, "winehprepare", "Prepare Windows exceptions",
95 false, false)
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000096
97FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
98 return new WinEHPrepare(TM);
99}
100
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000101bool WinEHPrepare::runOnFunction(Function &Fn) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000102 if (!Fn.hasPersonalityFn())
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000103 return false;
104
105 // Classify the personality to see what kind of preparation we need.
David Majnemer7fddecc2015-06-17 20:52:32 +0000106 Personality = classifyEHPersonality(Fn.getPersonalityFn());
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000107
Joseph Tremoulet2afea542015-10-06 20:28:16 +0000108 // Do nothing if this is not a funclet-based personality.
109 if (!isFuncletEHPersonality(Personality))
Reid Kleckner47c8e7a2015-03-12 00:36:20 +0000110 return false;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000111
David Majnemer8a1c45d2015-12-12 05:38:55 +0000112 return prepareExplicitEH(Fn);
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000113}
114
Andrew Kayloraa92ab02015-04-03 19:37:50 +0000115bool WinEHPrepare::doFinalization(Module &M) { return false; }
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000116
David Majnemere6965832015-10-16 19:59:52 +0000117void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {}
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000118
David Majnemer0ad363e2015-08-18 19:07:12 +0000119static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState,
David Majnemerbfa5b982015-10-10 00:04:29 +0000120 const BasicBlock *BB) {
Reid Kleckner14e77352015-10-09 23:34:53 +0000121 CxxUnwindMapEntry UME;
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000122 UME.ToState = ToState;
David Majnemerbfa5b982015-10-10 00:04:29 +0000123 UME.Cleanup = BB;
Reid Kleckner14e77352015-10-09 23:34:53 +0000124 FuncInfo.CxxUnwindMap.push_back(UME);
David Majnemer0ad363e2015-08-18 19:07:12 +0000125 return FuncInfo.getLastStateNumber();
126}
127
128static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
129 int TryHigh, int CatchHigh,
130 ArrayRef<const CatchPadInst *> Handlers) {
131 WinEHTryBlockMapEntry TBME;
132 TBME.TryLow = TryLow;
133 TBME.TryHigh = TryHigh;
134 TBME.CatchHigh = CatchHigh;
135 assert(TBME.TryLow <= TBME.TryHigh);
136 for (const CatchPadInst *CPI : Handlers) {
137 WinEHHandlerType HT;
138 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
Reid Klecknerb005d282015-09-16 20:16:27 +0000139 if (TypeInfo->isNullValue())
David Majnemer0ad363e2015-08-18 19:07:12 +0000140 HT.TypeDescriptor = nullptr;
Reid Klecknerb005d282015-09-16 20:16:27 +0000141 else
142 HT.TypeDescriptor = cast<GlobalVariable>(TypeInfo->stripPointerCasts());
143 HT.Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
David Majnemer7735a6d2015-10-06 23:31:59 +0000144 HT.Handler = CPI->getParent();
Reid Klecknerb005d282015-09-16 20:16:27 +0000145 if (isa<ConstantPointerNull>(CPI->getArgOperand(2)))
146 HT.CatchObj.Alloca = nullptr;
147 else
148 HT.CatchObj.Alloca = cast<AllocaInst>(CPI->getArgOperand(2));
David Majnemer0ad363e2015-08-18 19:07:12 +0000149 TBME.HandlerArray.push_back(HT);
150 }
151 FuncInfo.TryBlockMap.push_back(TBME);
152}
153
David Majnemer8a1c45d2015-12-12 05:38:55 +0000154static BasicBlock *getCleanupRetUnwindDest(const CleanupPadInst *CleanupPad) {
155 for (const User *U : CleanupPad->users())
156 if (const auto *CRI = dyn_cast<CleanupReturnInst>(U))
157 return CRI->getUnwindDest();
David Majnemer0ad363e2015-08-18 19:07:12 +0000158 return nullptr;
159}
160
David Majnemer8a1c45d2015-12-12 05:38:55 +0000161static void calculateStateNumbersForInvokes(const Function *Fn,
162 WinEHFuncInfo &FuncInfo) {
163 auto *F = const_cast<Function *>(Fn);
164 DenseMap<BasicBlock *, ColorVector> BlockColors = colorEHFunclets(*F);
165 for (BasicBlock &BB : *F) {
166 auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
167 if (!II)
168 continue;
169
170 auto &BBColors = BlockColors[&BB];
David Majnemerc640f862015-12-23 03:59:04 +0000171 assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
David Majnemer8a1c45d2015-12-12 05:38:55 +0000172 BasicBlock *FuncletEntryBB = BBColors.front();
173
174 BasicBlock *FuncletUnwindDest;
175 auto *FuncletPad =
176 dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI());
177 assert(FuncletPad || FuncletEntryBB == &Fn->getEntryBlock());
178 if (!FuncletPad)
179 FuncletUnwindDest = nullptr;
180 else if (auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
181 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
182 else if (auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad))
183 FuncletUnwindDest = getCleanupRetUnwindDest(CleanupPad);
184 else
185 llvm_unreachable("unexpected funclet pad!");
186
187 BasicBlock *InvokeUnwindDest = II->getUnwindDest();
188 int BaseState = -1;
189 if (FuncletUnwindDest == InvokeUnwindDest) {
190 auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad);
191 if (BaseStateI != FuncInfo.FuncletBaseStateMap.end())
192 BaseState = BaseStateI->second;
193 }
194
195 if (BaseState != -1) {
196 FuncInfo.InvokeStateMap[II] = BaseState;
197 } else {
198 Instruction *PadInst = InvokeUnwindDest->getFirstNonPHI();
199 assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!");
200 FuncInfo.InvokeStateMap[II] = FuncInfo.EHPadStateMap[PadInst];
201 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000202 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000203}
204
David Majnemer0ad363e2015-08-18 19:07:12 +0000205// Given BB which ends in an unwind edge, return the EHPad that this BB belongs
206// to. If the unwind edge came from an invoke, return null.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000207static const BasicBlock *getEHPadFromPredecessor(const BasicBlock *BB,
208 Value *ParentPad) {
David Majnemer0ad363e2015-08-18 19:07:12 +0000209 const TerminatorInst *TI = BB->getTerminator();
210 if (isa<InvokeInst>(TI))
211 return nullptr;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000212 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
213 if (CatchSwitch->getParentPad() != ParentPad)
214 return nullptr;
David Majnemer0ad363e2015-08-18 19:07:12 +0000215 return BB;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000216 }
217 assert(!TI->isEHPad() && "unexpected EHPad!");
218 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
219 if (CleanupPad->getParentPad() != ParentPad)
220 return nullptr;
221 return CleanupPad->getParent();
David Majnemer0ad363e2015-08-18 19:07:12 +0000222}
223
David Majnemer8a1c45d2015-12-12 05:38:55 +0000224static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo,
225 const Instruction *FirstNonPHI,
226 int ParentState) {
227 const BasicBlock *BB = FirstNonPHI->getParent();
228 assert(BB->isEHPad() && "not a funclet!");
David Majnemer0ad363e2015-08-18 19:07:12 +0000229
David Majnemer8a1c45d2015-12-12 05:38:55 +0000230 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
231 assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
232 "shouldn't revist catch funclets!");
233
David Majnemer0ad363e2015-08-18 19:07:12 +0000234 SmallVector<const CatchPadInst *, 2> Handlers;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000235 for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
236 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
237 Handlers.push_back(CatchPad);
238 }
David Majnemer0ad363e2015-08-18 19:07:12 +0000239 int TryLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000240 FuncInfo.EHPadStateMap[CatchSwitch] = TryLow;
241 for (const BasicBlock *PredBlock : predecessors(BB))
242 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
243 CatchSwitch->getParentPad())))
244 calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
245 TryLow);
David Majnemer0ad363e2015-08-18 19:07:12 +0000246 int CatchLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000247
248 // catchpads are separate funclets in C++ EH due to the way rethrow works.
David Majnemer0ad363e2015-08-18 19:07:12 +0000249 int TryHigh = CatchLow - 1;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000250 for (const auto *CatchPad : Handlers) {
251 FuncInfo.FuncletBaseStateMap[CatchPad] = CatchLow;
252 for (const User *U : CatchPad->users()) {
253 const auto *UserI = cast<Instruction>(U);
David Majnemerc640f862015-12-23 03:59:04 +0000254 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI))
255 if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest())
256 calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
257 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI))
258 if (getCleanupRetUnwindDest(InnerCleanupPad) ==
259 CatchSwitch->getUnwindDest())
260 calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000261 }
262 }
David Majnemer0ad363e2015-08-18 19:07:12 +0000263 int CatchHigh = FuncInfo.getLastStateNumber();
264 addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchHigh, Handlers);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000265 DEBUG(dbgs() << "TryLow[" << BB->getName() << "]: " << TryLow << '\n');
266 DEBUG(dbgs() << "TryHigh[" << BB->getName() << "]: " << TryHigh << '\n');
267 DEBUG(dbgs() << "CatchHigh[" << BB->getName() << "]: " << CatchHigh
David Majnemer0ad363e2015-08-18 19:07:12 +0000268 << '\n');
David Majnemer0ad363e2015-08-18 19:07:12 +0000269 } else {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000270 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
271
272 // It's possible for a cleanup to be visited twice: it might have multiple
273 // cleanupret instructions.
274 if (FuncInfo.EHPadStateMap.count(CleanupPad))
275 return;
276
277 int CleanupState = addUnwindMapEntry(FuncInfo, ParentState, BB);
278 FuncInfo.EHPadStateMap[CleanupPad] = CleanupState;
279 DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
280 << BB->getName() << '\n');
281 for (const BasicBlock *PredBlock : predecessors(BB)) {
282 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
283 CleanupPad->getParentPad()))) {
284 calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
285 CleanupState);
286 }
287 }
288 for (const User *U : CleanupPad->users()) {
289 const auto *UserI = cast<Instruction>(U);
290 if (UserI->isEHPad())
291 report_fatal_error("Cleanup funclets for the MSVC++ personality cannot "
292 "contain exceptional actions");
293 }
David Majnemer0ad363e2015-08-18 19:07:12 +0000294 }
295}
296
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000297static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState,
298 const Function *Filter, const BasicBlock *Handler) {
Reid Kleckner94b704c2015-09-09 21:10:03 +0000299 SEHUnwindMapEntry Entry;
300 Entry.ToState = ParentState;
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000301 Entry.IsFinally = false;
Reid Kleckner94b704c2015-09-09 21:10:03 +0000302 Entry.Filter = Filter;
303 Entry.Handler = Handler;
304 FuncInfo.SEHUnwindMap.push_back(Entry);
305 return FuncInfo.SEHUnwindMap.size() - 1;
306}
307
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000308static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState,
309 const BasicBlock *Handler) {
310 SEHUnwindMapEntry Entry;
311 Entry.ToState = ParentState;
312 Entry.IsFinally = true;
313 Entry.Filter = nullptr;
314 Entry.Handler = Handler;
315 FuncInfo.SEHUnwindMap.push_back(Entry);
316 return FuncInfo.SEHUnwindMap.size() - 1;
317}
318
David Majnemer8a1c45d2015-12-12 05:38:55 +0000319static void calculateSEHStateNumbers(WinEHFuncInfo &FuncInfo,
320 const Instruction *FirstNonPHI,
321 int ParentState) {
322 const BasicBlock *BB = FirstNonPHI->getParent();
323 assert(BB->isEHPad() && "no a funclet!");
Reid Kleckner94b704c2015-09-09 21:10:03 +0000324
David Majnemer8a1c45d2015-12-12 05:38:55 +0000325 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
326 assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
327 "shouldn't revist catch funclets!");
328
Reid Kleckner94b704c2015-09-09 21:10:03 +0000329 // Extract the filter function and the __except basic block and create a
330 // state for them.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000331 assert(CatchSwitch->getNumHandlers() == 1 &&
Reid Kleckner94b704c2015-09-09 21:10:03 +0000332 "SEH doesn't have multiple handlers per __try");
David Majnemer8a1c45d2015-12-12 05:38:55 +0000333 const auto *CatchPad =
334 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI());
335 const BasicBlock *CatchPadBB = CatchPad->getParent();
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000336 const Constant *FilterOrNull =
David Majnemer8a1c45d2015-12-12 05:38:55 +0000337 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000338 const Function *Filter = dyn_cast<Function>(FilterOrNull);
339 assert((Filter || FilterOrNull->isNullValue()) &&
340 "unexpected filter value");
David Majnemer7735a6d2015-10-06 23:31:59 +0000341 int TryState = addSEHExcept(FuncInfo, ParentState, Filter, CatchPadBB);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000342
343 // Everything in the __try block uses TryState as its parent state.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000344 FuncInfo.EHPadStateMap[CatchSwitch] = TryState;
Reid Kleckner94b704c2015-09-09 21:10:03 +0000345 DEBUG(dbgs() << "Assigning state #" << TryState << " to BB "
346 << CatchPadBB->getName() << '\n');
David Majnemer8a1c45d2015-12-12 05:38:55 +0000347 for (const BasicBlock *PredBlock : predecessors(BB))
348 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
349 CatchSwitch->getParentPad())))
350 calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
351 TryState);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000352
353 // Everything in the __except block unwinds to ParentState, just like code
354 // outside the __try.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000355 for (const User *U : CatchPad->users()) {
356 const auto *UserI = cast<Instruction>(U);
David Majnemerc640f862015-12-23 03:59:04 +0000357 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI))
358 if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest())
359 calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
360 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI))
361 if (getCleanupRetUnwindDest(InnerCleanupPad) ==
362 CatchSwitch->getUnwindDest())
363 calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000364 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000365 } else {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000366 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
367
368 // It's possible for a cleanup to be visited twice: it might have multiple
369 // cleanupret instructions.
370 if (FuncInfo.EHPadStateMap.count(CleanupPad))
371 return;
372
373 int CleanupState = addSEHFinally(FuncInfo, ParentState, BB);
374 FuncInfo.EHPadStateMap[CleanupPad] = CleanupState;
375 DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
376 << BB->getName() << '\n');
377 for (const BasicBlock *PredBlock : predecessors(BB))
378 if ((PredBlock =
379 getEHPadFromPredecessor(PredBlock, CleanupPad->getParentPad())))
380 calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
381 CleanupState);
382 for (const User *U : CleanupPad->users()) {
383 const auto *UserI = cast<Instruction>(U);
384 if (UserI->isEHPad())
385 report_fatal_error("Cleanup funclets for the SEH personality cannot "
386 "contain exceptional actions");
387 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000388 }
389}
390
David Majnemer8a1c45d2015-12-12 05:38:55 +0000391static bool isTopLevelPadForMSVC(const Instruction *EHPad) {
392 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
393 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
394 CatchSwitch->unwindsToCaller();
395 if (auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
396 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
397 getCleanupRetUnwindDest(CleanupPad) == nullptr;
398 if (isa<CatchPadInst>(EHPad))
399 return false;
400 llvm_unreachable("unexpected EHPad!");
Reid Kleckner94b704c2015-09-09 21:10:03 +0000401}
402
Reid Kleckner813f1b62015-09-16 22:14:46 +0000403void llvm::calculateSEHStateNumbers(const Function *Fn,
Reid Kleckner94b704c2015-09-09 21:10:03 +0000404 WinEHFuncInfo &FuncInfo) {
405 // Don't compute state numbers twice.
406 if (!FuncInfo.SEHUnwindMap.empty())
407 return;
408
Reid Kleckner813f1b62015-09-16 22:14:46 +0000409 for (const BasicBlock &BB : *Fn) {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000410 if (!BB.isEHPad())
Reid Kleckner94b704c2015-09-09 21:10:03 +0000411 continue;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000412 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
413 if (!isTopLevelPadForMSVC(FirstNonPHI))
414 continue;
415 ::calculateSEHStateNumbers(FuncInfo, FirstNonPHI, -1);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000416 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000417
418 calculateStateNumbersForInvokes(Fn, FuncInfo);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000419}
420
Reid Kleckner813f1b62015-09-16 22:14:46 +0000421void llvm::calculateWinCXXEHStateNumbers(const Function *Fn,
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000422 WinEHFuncInfo &FuncInfo) {
423 // Return if it's already been done.
David Majnemer0ad363e2015-08-18 19:07:12 +0000424 if (!FuncInfo.EHPadStateMap.empty())
425 return;
426
Reid Kleckner813f1b62015-09-16 22:14:46 +0000427 for (const BasicBlock &BB : *Fn) {
David Majnemer0ad363e2015-08-18 19:07:12 +0000428 if (!BB.isEHPad())
429 continue;
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000430 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
David Majnemer8a1c45d2015-12-12 05:38:55 +0000431 if (!isTopLevelPadForMSVC(FirstNonPHI))
David Majnemer0ad363e2015-08-18 19:07:12 +0000432 continue;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000433 calculateCXXStateNumbers(FuncInfo, FirstNonPHI, -1);
David Majnemer0ad363e2015-08-18 19:07:12 +0000434 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000435
436 calculateStateNumbersForInvokes(Fn, FuncInfo);
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000437}
David Majnemerfd9f4772015-08-11 01:15:26 +0000438
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000439static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int ParentState,
440 ClrHandlerType HandlerType, uint32_t TypeToken,
441 const BasicBlock *Handler) {
442 ClrEHUnwindMapEntry Entry;
443 Entry.Parent = ParentState;
444 Entry.Handler = Handler;
445 Entry.HandlerType = HandlerType;
446 Entry.TypeToken = TypeToken;
447 FuncInfo.ClrEHUnwindMap.push_back(Entry);
448 return FuncInfo.ClrEHUnwindMap.size() - 1;
449}
450
451void llvm::calculateClrEHStateNumbers(const Function *Fn,
452 WinEHFuncInfo &FuncInfo) {
453 // Return if it's already been done.
454 if (!FuncInfo.EHPadStateMap.empty())
455 return;
456
457 SmallVector<std::pair<const Instruction *, int>, 8> Worklist;
458
459 // Each pad needs to be able to refer to its parent, so scan the function
460 // looking for top-level handlers and seed the worklist with them.
461 for (const BasicBlock &BB : *Fn) {
462 if (!BB.isEHPad())
463 continue;
464 if (BB.isLandingPad())
465 report_fatal_error("CoreCLR EH cannot use landingpads");
466 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
David Majnemer8a1c45d2015-12-12 05:38:55 +0000467 if (!isTopLevelPadForMSVC(FirstNonPHI))
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000468 continue;
469 // queue this with sentinel parent state -1 to mean unwind to caller.
470 Worklist.emplace_back(FirstNonPHI, -1);
471 }
472
473 while (!Worklist.empty()) {
474 const Instruction *Pad;
475 int ParentState;
476 std::tie(Pad, ParentState) = Worklist.pop_back_val();
477
David Majnemer8a1c45d2015-12-12 05:38:55 +0000478 Value *ParentPad;
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000479 int PredState;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000480 if (const CleanupPadInst *Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000481 // A cleanup can have multiple exits; don't re-process after the first.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000482 if (FuncInfo.EHPadStateMap.count(Cleanup))
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000483 continue;
484 // CoreCLR personality uses arity to distinguish faults from finallies.
485 const BasicBlock *PadBlock = Cleanup->getParent();
486 ClrHandlerType HandlerType =
487 (Cleanup->getNumOperands() ? ClrHandlerType::Fault
488 : ClrHandlerType::Finally);
489 int NewState =
490 addClrEHHandler(FuncInfo, ParentState, HandlerType, 0, PadBlock);
491 FuncInfo.EHPadStateMap[Cleanup] = NewState;
492 // Propagate the new state to all preds of the cleanup
David Majnemer8a1c45d2015-12-12 05:38:55 +0000493 ParentPad = Cleanup->getParentPad();
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000494 PredState = NewState;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000495 } else if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(Pad)) {
496 SmallVector<const CatchPadInst *, 1> Handlers;
497 for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
498 const auto *Catch = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
499 Handlers.push_back(Catch);
500 }
501 FuncInfo.EHPadStateMap[CatchSwitch] = ParentState;
502 int NewState = ParentState;
503 for (auto HandlerI = Handlers.rbegin(), HandlerE = Handlers.rend();
504 HandlerI != HandlerE; ++HandlerI) {
505 const CatchPadInst *Catch = *HandlerI;
506 const BasicBlock *PadBlock = Catch->getParent();
507 uint32_t TypeToken = static_cast<uint32_t>(
508 cast<ConstantInt>(Catch->getArgOperand(0))->getZExtValue());
509 NewState = addClrEHHandler(FuncInfo, NewState, ClrHandlerType::Catch,
510 TypeToken, PadBlock);
511 FuncInfo.EHPadStateMap[Catch] = NewState;
512 }
513 for (const auto *CatchPad : Handlers) {
514 for (const User *U : CatchPad->users()) {
515 const auto *UserI = cast<Instruction>(U);
516 if (UserI->isEHPad())
517 Worklist.emplace_back(UserI, ParentState);
518 }
519 }
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000520 PredState = NewState;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000521 ParentPad = CatchSwitch->getParentPad();
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000522 } else {
523 llvm_unreachable("Unexpected EH pad");
524 }
525
526 // Queue all predecessors with the given state
527 for (const BasicBlock *Pred : predecessors(Pad->getParent())) {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000528 if ((Pred = getEHPadFromPredecessor(Pred, ParentPad)))
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000529 Worklist.emplace_back(Pred->getFirstNonPHI(), PredState);
530 }
531 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000532
533 calculateStateNumbersForInvokes(Fn, FuncInfo);
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000534}
535
David Majnemer8a1c45d2015-12-12 05:38:55 +0000536void WinEHPrepare::colorFunclets(Function &F) {
537 BlockColors = colorEHFunclets(F);
David Majnemerfd9f4772015-08-11 01:15:26 +0000538
David Majnemer8a1c45d2015-12-12 05:38:55 +0000539 // Invert the map from BB to colors to color to BBs.
540 for (BasicBlock &BB : F) {
541 ColorVector &Colors = BlockColors[&BB];
542 for (BasicBlock *Color : Colors)
543 FuncletBlocks[Color].push_back(&BB);
David Majnemerfd9f4772015-08-11 01:15:26 +0000544 }
545}
546
David Majnemerf828a0c2015-10-01 18:44:59 +0000547void llvm::calculateCatchReturnSuccessorColors(const Function *Fn,
548 WinEHFuncInfo &FuncInfo) {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000549 for (const BasicBlock &BB : *Fn) {
550 const auto *CatchRet = dyn_cast<CatchReturnInst>(BB.getTerminator());
551 if (!CatchRet)
David Majnemerf828a0c2015-10-01 18:44:59 +0000552 continue;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000553 // A 'catchret' returns to the outer scope's color.
554 Value *ParentPad = CatchRet->getParentPad();
555 const BasicBlock *Color;
556 if (isa<ConstantTokenNone>(ParentPad))
557 Color = &Fn->getEntryBlock();
558 else
559 Color = cast<Instruction>(ParentPad)->getParent();
560 // Record the catchret successor's funclet membership.
561 FuncInfo.CatchRetSuccessorColorMap[CatchRet] = Color;
David Majnemerf828a0c2015-10-01 18:44:59 +0000562 }
563}
564
David Majnemerb3d9b962015-09-16 18:40:24 +0000565void WinEHPrepare::demotePHIsOnFunclets(Function &F) {
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000566 // Strip PHI nodes off of EH pads.
567 SmallVector<PHINode *, 16> PHINodes;
David Majnemerfd9f4772015-08-11 01:15:26 +0000568 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000569 BasicBlock *BB = &*FI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000570 if (!BB->isEHPad())
571 continue;
David Majnemerfd9f4772015-08-11 01:15:26 +0000572 for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000573 Instruction *I = &*BI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000574 auto *PN = dyn_cast<PHINode>(I);
575 // Stop at the first non-PHI.
576 if (!PN)
577 break;
David Majnemerfd9f4772015-08-11 01:15:26 +0000578
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000579 AllocaInst *SpillSlot = insertPHILoads(PN, F);
580 if (SpillSlot)
581 insertPHIStores(PN, SpillSlot);
582
583 PHINodes.push_back(PN);
David Majnemerfd9f4772015-08-11 01:15:26 +0000584 }
585 }
586
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000587 for (auto *PN : PHINodes) {
588 // There may be lingering uses on other EH PHIs being removed
589 PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
590 PN->eraseFromParent();
David Majnemerfd9f4772015-08-11 01:15:26 +0000591 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000592}
David Majnemerfd9f4772015-08-11 01:15:26 +0000593
David Majnemer8a1c45d2015-12-12 05:38:55 +0000594void WinEHPrepare::cloneCommonBlocks(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000595 // We need to clone all blocks which belong to multiple funclets. Values are
596 // remapped throughout the funclet to propogate both the new instructions
597 // *and* the new basic blocks themselves.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000598 for (auto &Funclets : FuncletBlocks) {
599 BasicBlock *FuncletPadBB = Funclets.first;
600 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
David Majnemerfd9f4772015-08-11 01:15:26 +0000601
David Majnemer8a1c45d2015-12-12 05:38:55 +0000602 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
David Majnemerfd9f4772015-08-11 01:15:26 +0000603 ValueToValueMapTy VMap;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000604 for (BasicBlock *BB : BlocksInFunclet) {
605 ColorVector &ColorsForBB = BlockColors[BB];
David Majnemerfd9f4772015-08-11 01:15:26 +0000606 // We don't need to do anything if the block is monochromatic.
607 size_t NumColorsForBB = ColorsForBB.size();
608 if (NumColorsForBB == 1)
609 continue;
610
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +0000611 DEBUG_WITH_TYPE("winehprepare-coloring",
612 dbgs() << " Cloning block \'" << BB->getName()
613 << "\' for funclet \'" << FuncletPadBB->getName()
614 << "\'.\n");
615
David Majnemerfd9f4772015-08-11 01:15:26 +0000616 // Create a new basic block and copy instructions into it!
Joseph Tremouletec182852015-08-28 01:12:35 +0000617 BasicBlock *CBB =
618 CloneBasicBlock(BB, VMap, Twine(".for.", FuncletPadBB->getName()));
619 // Insert the clone immediately after the original to ensure determinism
620 // and to keep the same relative ordering of any funclet's blocks.
621 CBB->insertInto(&F, BB->getNextNode());
David Majnemerfd9f4772015-08-11 01:15:26 +0000622
623 // Add basic block mapping.
624 VMap[BB] = CBB;
625
626 // Record delta operations that we need to perform to our color mappings.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000627 Orig2Clone.emplace_back(BB, CBB);
David Majnemerfd9f4772015-08-11 01:15:26 +0000628 }
629
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000630 // If nothing was cloned, we're done cloning in this funclet.
631 if (Orig2Clone.empty())
632 continue;
633
David Majnemerfd9f4772015-08-11 01:15:26 +0000634 // Update our color mappings to reflect that one block has lost a color and
635 // another has gained a color.
636 for (auto &BBMapping : Orig2Clone) {
637 BasicBlock *OldBlock = BBMapping.first;
638 BasicBlock *NewBlock = BBMapping.second;
639
David Majnemer8a1c45d2015-12-12 05:38:55 +0000640 BlocksInFunclet.push_back(NewBlock);
641 ColorVector &NewColors = BlockColors[NewBlock];
642 assert(NewColors.empty() && "A new block should only have one color!");
643 NewColors.push_back(FuncletPadBB);
David Majnemerfd9f4772015-08-11 01:15:26 +0000644
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +0000645 DEBUG_WITH_TYPE("winehprepare-coloring",
646 dbgs() << " Assigned color \'" << FuncletPadBB->getName()
647 << "\' to block \'" << NewBlock->getName()
648 << "\'.\n");
649
David Majnemer8a1c45d2015-12-12 05:38:55 +0000650 BlocksInFunclet.erase(
651 std::remove(BlocksInFunclet.begin(), BlocksInFunclet.end(), OldBlock),
652 BlocksInFunclet.end());
653 ColorVector &OldColors = BlockColors[OldBlock];
654 OldColors.erase(
655 std::remove(OldColors.begin(), OldColors.end(), FuncletPadBB),
656 OldColors.end());
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +0000657
658 DEBUG_WITH_TYPE("winehprepare-coloring",
659 dbgs() << " Removed color \'" << FuncletPadBB->getName()
660 << "\' from block \'" << OldBlock->getName()
661 << "\'.\n");
David Majnemerfd9f4772015-08-11 01:15:26 +0000662 }
663
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000664 // Loop over all of the instructions in this funclet, fixing up operand
David Majnemerfd9f4772015-08-11 01:15:26 +0000665 // references as we go. This uses VMap to do all the hard work.
666 for (BasicBlock *BB : BlocksInFunclet)
667 // Loop over all instructions, fixing each one as we find it...
668 for (Instruction &I : *BB)
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000669 RemapInstruction(&I, VMap,
670 RF_IgnoreMissingEntries | RF_NoModuleLevelChanges);
David Majnemer459a64a2015-09-16 18:40:37 +0000671
David Majnemer8a1c45d2015-12-12 05:38:55 +0000672 auto UpdatePHIOnClonedBlock = [&](PHINode *PN, bool IsForOldBlock) {
673 unsigned NumPreds = PN->getNumIncomingValues();
674 for (unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
675 ++PredIdx) {
676 BasicBlock *IncomingBlock = PN->getIncomingBlock(PredIdx);
677 ColorVector &IncomingColors = BlockColors[IncomingBlock];
678 bool BlockInFunclet = IncomingColors.size() == 1 &&
679 IncomingColors.front() == FuncletPadBB;
680 if (IsForOldBlock != BlockInFunclet)
681 continue;
682 PN->removeIncomingValue(IncomingBlock, /*DeletePHIIfEmpty=*/false);
683 // Revisit the next entry.
684 --PredIdx;
685 --PredEnd;
686 }
687 };
688
689 for (auto &BBMapping : Orig2Clone) {
690 BasicBlock *OldBlock = BBMapping.first;
691 BasicBlock *NewBlock = BBMapping.second;
692 for (Instruction &OldI : *OldBlock) {
693 auto *OldPN = dyn_cast<PHINode>(&OldI);
694 if (!OldPN)
695 break;
696 UpdatePHIOnClonedBlock(OldPN, /*IsForOldBlock=*/true);
697 }
698 for (Instruction &NewI : *NewBlock) {
699 auto *NewPN = dyn_cast<PHINode>(&NewI);
700 if (!NewPN)
701 break;
702 UpdatePHIOnClonedBlock(NewPN, /*IsForOldBlock=*/false);
703 }
704 }
705
David Majnemer459a64a2015-09-16 18:40:37 +0000706 // Check to see if SuccBB has PHI nodes. If so, we need to add entries to
707 // the PHI nodes for NewBB now.
708 for (auto &BBMapping : Orig2Clone) {
709 BasicBlock *OldBlock = BBMapping.first;
710 BasicBlock *NewBlock = BBMapping.second;
711 for (BasicBlock *SuccBB : successors(NewBlock)) {
712 for (Instruction &SuccI : *SuccBB) {
713 auto *SuccPN = dyn_cast<PHINode>(&SuccI);
714 if (!SuccPN)
715 break;
716
717 // Ok, we have a PHI node. Figure out what the incoming value was for
718 // the OldBlock.
719 int OldBlockIdx = SuccPN->getBasicBlockIndex(OldBlock);
720 if (OldBlockIdx == -1)
721 break;
722 Value *IV = SuccPN->getIncomingValue(OldBlockIdx);
723
724 // Remap the value if necessary.
725 if (auto *Inst = dyn_cast<Instruction>(IV)) {
726 ValueToValueMapTy::iterator I = VMap.find(Inst);
727 if (I != VMap.end())
728 IV = I->second;
729 }
730
731 SuccPN->addIncoming(IV, NewBlock);
732 }
733 }
734 }
735
736 for (ValueToValueMapTy::value_type VT : VMap) {
737 // If there were values defined in BB that are used outside the funclet,
738 // then we now have to update all uses of the value to use either the
739 // original value, the cloned value, or some PHI derived value. This can
740 // require arbitrary PHI insertion, of which we are prepared to do, clean
741 // these up now.
742 SmallVector<Use *, 16> UsesToRename;
743
744 auto *OldI = dyn_cast<Instruction>(const_cast<Value *>(VT.first));
745 if (!OldI)
746 continue;
747 auto *NewI = cast<Instruction>(VT.second);
748 // Scan all uses of this instruction to see if it is used outside of its
749 // funclet, and if so, record them in UsesToRename.
750 for (Use &U : OldI->uses()) {
751 Instruction *UserI = cast<Instruction>(U.getUser());
752 BasicBlock *UserBB = UserI->getParent();
David Majnemer8a1c45d2015-12-12 05:38:55 +0000753 ColorVector &ColorsForUserBB = BlockColors[UserBB];
David Majnemer459a64a2015-09-16 18:40:37 +0000754 assert(!ColorsForUserBB.empty());
755 if (ColorsForUserBB.size() > 1 ||
756 *ColorsForUserBB.begin() != FuncletPadBB)
757 UsesToRename.push_back(&U);
758 }
759
760 // If there are no uses outside the block, we're done with this
761 // instruction.
762 if (UsesToRename.empty())
763 continue;
764
765 // We found a use of OldI outside of the funclet. Rename all uses of OldI
766 // that are outside its funclet to be uses of the appropriate PHI node
767 // etc.
768 SSAUpdater SSAUpdate;
769 SSAUpdate.Initialize(OldI->getType(), OldI->getName());
770 SSAUpdate.AddAvailableValue(OldI->getParent(), OldI);
771 SSAUpdate.AddAvailableValue(NewI->getParent(), NewI);
772
773 while (!UsesToRename.empty())
774 SSAUpdate.RewriteUseAfterInsertions(*UsesToRename.pop_back_val());
775 }
David Majnemerfd9f4772015-08-11 01:15:26 +0000776 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000777}
David Majnemerfd9f4772015-08-11 01:15:26 +0000778
David Majnemer3bb88c02015-12-15 21:27:27 +0000779void WinEHPrepare::removeImplausibleInstructions(Function &F) {
David Majnemer83f4bb22015-08-17 20:56:39 +0000780 // Remove implausible terminators and replace them with UnreachableInst.
781 for (auto &Funclet : FuncletBlocks) {
782 BasicBlock *FuncletPadBB = Funclet.first;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000783 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
David Majnemer3bb88c02015-12-15 21:27:27 +0000784 Instruction *FirstNonPHI = FuncletPadBB->getFirstNonPHI();
785 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
786 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
787 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
David Majnemer83f4bb22015-08-17 20:56:39 +0000788
789 for (BasicBlock *BB : BlocksInFunclet) {
David Majnemer3bb88c02015-12-15 21:27:27 +0000790 for (Instruction &I : *BB) {
791 CallSite CS(&I);
792 if (!CS)
793 continue;
794
795 Value *FuncletBundleOperand = nullptr;
796 if (auto BU = CS.getOperandBundle(LLVMContext::OB_funclet))
797 FuncletBundleOperand = BU->Inputs.front();
798
799 if (FuncletBundleOperand == FuncletPad)
800 continue;
801
802 // Skip call sites which are nounwind intrinsics.
803 auto *CalledFn =
804 dyn_cast<Function>(CS.getCalledValue()->stripPointerCasts());
805 if (CalledFn && CalledFn->isIntrinsic() && CS.doesNotThrow())
806 continue;
807
808 // This call site was not part of this funclet, remove it.
809 if (CS.isInvoke()) {
810 // Remove the unwind edge if it was an invoke.
811 removeUnwindEdge(BB);
812 // Get a pointer to the new call.
813 BasicBlock::iterator CallI =
814 std::prev(BB->getTerminator()->getIterator());
815 auto *CI = cast<CallInst>(&*CallI);
816 changeToUnreachable(CI, /*UseLLVMTrap=*/false);
817 } else {
818 changeToUnreachable(&I, /*UseLLVMTrap=*/false);
819 }
820
821 // There are no more instructions in the block (except for unreachable),
822 // we are done.
823 break;
824 }
825
David Majnemer83f4bb22015-08-17 20:56:39 +0000826 TerminatorInst *TI = BB->getTerminator();
827 // CatchPadInst and CleanupPadInst can't transfer control to a ReturnInst.
David Majnemer3bb88c02015-12-15 21:27:27 +0000828 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
David Majnemer83f4bb22015-08-17 20:56:39 +0000829 // The token consumed by a CatchReturnInst must match the funclet token.
830 bool IsUnreachableCatchret = false;
831 if (auto *CRI = dyn_cast<CatchReturnInst>(TI))
Joseph Tremoulet8220bcc2015-08-23 00:26:33 +0000832 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000833 // The token consumed by a CleanupReturnInst must match the funclet token.
David Majnemer83f4bb22015-08-17 20:56:39 +0000834 bool IsUnreachableCleanupret = false;
835 if (auto *CRI = dyn_cast<CleanupReturnInst>(TI))
Joseph Tremoulet8220bcc2015-08-23 00:26:33 +0000836 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000837 if (IsUnreachableRet || IsUnreachableCatchret ||
David Majnemer8a1c45d2015-12-12 05:38:55 +0000838 IsUnreachableCleanupret) {
David Majnemer3bb88c02015-12-15 21:27:27 +0000839 changeToUnreachable(TI, /*UseLLVMTrap=*/false);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000840 } else if (isa<InvokeInst>(TI)) {
David Majnemer3bb88c02015-12-15 21:27:27 +0000841 if (Personality == EHPersonality::MSVC_CXX && CleanupPad) {
842 // Invokes within a cleanuppad for the MSVC++ personality never
843 // transfer control to their unwind edge: the personality will
844 // terminate the program.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000845 removeUnwindEdge(BB);
David Majnemer3bb88c02015-12-15 21:27:27 +0000846 }
David Majnemer83f4bb22015-08-17 20:56:39 +0000847 }
848 }
849 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000850}
David Majnemer83f4bb22015-08-17 20:56:39 +0000851
David Majnemerb3d9b962015-09-16 18:40:24 +0000852void WinEHPrepare::cleanupPreparedFunclets(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000853 // Clean-up some of the mess we made by removing useles PHI nodes, trivial
854 // branches, etc.
855 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000856 BasicBlock *BB = &*FI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000857 SimplifyInstructionsInBlock(BB);
858 ConstantFoldTerminator(BB, /*DeleteDeadConditions=*/true);
859 MergeBlockIntoPredecessor(BB);
860 }
861
David Majnemerfd9f4772015-08-11 01:15:26 +0000862 // We might have some unreachable blocks after cleaning up some impossible
863 // control flow.
864 removeUnreachableBlocks(F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000865}
David Majnemerfd9f4772015-08-11 01:15:26 +0000866
David Majnemerb3d9b962015-09-16 18:40:24 +0000867void WinEHPrepare::verifyPreparedFunclets(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000868 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!");
David Majnemer8a1c45d2015-12-12 05:38:55 +0000878 }
David Majnemerfd9f4772015-08-11 01:15:26 +0000879 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000880}
881
David Majnemer8a1c45d2015-12-12 05:38:55 +0000882bool WinEHPrepare::prepareExplicitEH(Function &F) {
883 // Remove unreachable blocks. It is not valuable to assign them a color and
884 // their existence can trick us into thinking values are alive when they are
885 // not.
886 removeUnreachableBlocks(F);
887
David Majnemerb3d9b962015-09-16 18:40:24 +0000888 // Determine which blocks are reachable from which funclet entries.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000889 colorFunclets(F);
890
891 cloneCommonBlocks(F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000892
Reid Klecknercc2f6c32015-11-19 23:23:33 +0000893 if (!DisableDemotion)
David Majnemer459a64a2015-09-16 18:40:37 +0000894 demotePHIsOnFunclets(F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000895
David Majnemer459a64a2015-09-16 18:40:37 +0000896 if (!DisableCleanups) {
David Majnemerdbdc9c22016-01-02 09:26:36 +0000897 DEBUG(verifyFunction(F));
David Majnemer3bb88c02015-12-15 21:27:27 +0000898 removeImplausibleInstructions(F);
David Majnemerb3d9b962015-09-16 18:40:24 +0000899
David Majnemerdbdc9c22016-01-02 09:26:36 +0000900 DEBUG(verifyFunction(F));
David Majnemer459a64a2015-09-16 18:40:37 +0000901 cleanupPreparedFunclets(F);
902 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000903
David Majnemerdbdc9c22016-01-02 09:26:36 +0000904 DEBUG(verifyPreparedFunclets(F));
905 // Recolor the CFG to verify that all is well.
906 DEBUG(colorFunclets(F));
907 DEBUG(verifyPreparedFunclets(F));
David Majnemerfd9f4772015-08-11 01:15:26 +0000908
909 BlockColors.clear();
910 FuncletBlocks.clear();
David Majnemer0ad363e2015-08-18 19:07:12 +0000911
David Majnemerfd9f4772015-08-11 01:15:26 +0000912 return true;
913}
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000914
915// TODO: Share loads when one use dominates another, or when a catchpad exit
916// dominates uses (needs dominators).
917AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) {
918 BasicBlock *PHIBlock = PN->getParent();
919 AllocaInst *SpillSlot = nullptr;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000920 Instruction *EHPad = PHIBlock->getFirstNonPHI();
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000921
David Majnemer8a1c45d2015-12-12 05:38:55 +0000922 if (!isa<TerminatorInst>(EHPad)) {
923 // If the EHPad isn't a terminator, then we can insert a load in this block
924 // that will dominate all uses.
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000925 SpillSlot = new AllocaInst(PN->getType(), nullptr,
926 Twine(PN->getName(), ".wineh.spillslot"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000927 &F.getEntryBlock().front());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000928 Value *V = new LoadInst(SpillSlot, Twine(PN->getName(), ".wineh.reload"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000929 &*PHIBlock->getFirstInsertionPt());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000930 PN->replaceAllUsesWith(V);
931 return SpillSlot;
932 }
933
David Majnemer8a1c45d2015-12-12 05:38:55 +0000934 // Otherwise, we have a PHI on a terminator EHPad, and we give up and insert
935 // loads of the slot before every use.
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000936 DenseMap<BasicBlock *, Value *> Loads;
937 for (Value::use_iterator UI = PN->use_begin(), UE = PN->use_end();
938 UI != UE;) {
939 Use &U = *UI++;
940 auto *UsingInst = cast<Instruction>(U.getUser());
David Majnemer8a1c45d2015-12-12 05:38:55 +0000941 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000942 // Use is on an EH pad phi. Leave it alone; we'll insert loads and
943 // stores for it separately.
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000944 continue;
945 }
946 replaceUseWithLoad(PN, U, SpillSlot, Loads, F);
947 }
948 return SpillSlot;
949}
950
951// TODO: improve store placement. Inserting at def is probably good, but need
952// to be careful not to introduce interfering stores (needs liveness analysis).
953// TODO: identify related phi nodes that can share spill slots, and share them
954// (also needs liveness).
955void WinEHPrepare::insertPHIStores(PHINode *OriginalPHI,
956 AllocaInst *SpillSlot) {
957 // Use a worklist of (Block, Value) pairs -- the given Value needs to be
958 // stored to the spill slot by the end of the given Block.
959 SmallVector<std::pair<BasicBlock *, Value *>, 4> Worklist;
960
961 Worklist.push_back({OriginalPHI->getParent(), OriginalPHI});
962
963 while (!Worklist.empty()) {
964 BasicBlock *EHBlock;
965 Value *InVal;
966 std::tie(EHBlock, InVal) = Worklist.pop_back_val();
967
968 PHINode *PN = dyn_cast<PHINode>(InVal);
969 if (PN && PN->getParent() == EHBlock) {
970 // The value is defined by another PHI we need to remove, with no room to
971 // insert a store after the PHI, so each predecessor needs to store its
972 // incoming value.
973 for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
974 Value *PredVal = PN->getIncomingValue(i);
975
976 // Undef can safely be skipped.
977 if (isa<UndefValue>(PredVal))
978 continue;
979
980 insertPHIStore(PN->getIncomingBlock(i), PredVal, SpillSlot, Worklist);
981 }
982 } else {
983 // We need to store InVal, which dominates EHBlock, but can't put a store
984 // in EHBlock, so need to put stores in each predecessor.
985 for (BasicBlock *PredBlock : predecessors(EHBlock)) {
986 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
987 }
988 }
989 }
990}
991
992void WinEHPrepare::insertPHIStore(
993 BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
994 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist) {
995
996 if (PredBlock->isEHPad() &&
David Majnemer8a1c45d2015-12-12 05:38:55 +0000997 isa<TerminatorInst>(PredBlock->getFirstNonPHI())) {
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000998 // Pred is unsplittable, so we need to queue it on the worklist.
999 Worklist.push_back({PredBlock, PredVal});
1000 return;
1001 }
1002
1003 // Otherwise, insert the store at the end of the basic block.
1004 new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator());
1005}
1006
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001007void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
1008 DenseMap<BasicBlock *, Value *> &Loads,
1009 Function &F) {
1010 // Lazilly create the spill slot.
1011 if (!SpillSlot)
1012 SpillSlot = new AllocaInst(V->getType(), nullptr,
1013 Twine(V->getName(), ".wineh.spillslot"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001014 &F.getEntryBlock().front());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001015
1016 auto *UsingInst = cast<Instruction>(U.getUser());
1017 if (auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1018 // If this is a PHI node, we can't insert a load of the value before
1019 // the use. Instead insert the load in the predecessor block
1020 // corresponding to the incoming value.
1021 //
1022 // Note that if there are multiple edges from a basic block to this
1023 // PHI node that we cannot have multiple loads. The problem is that
1024 // the resulting PHI node will have multiple values (from each load)
1025 // coming in from the same block, which is illegal SSA form.
1026 // For this reason, we keep track of and reuse loads we insert.
1027 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
Joseph Tremoulet7031c9f2015-08-17 13:51:37 +00001028 if (auto *CatchRet =
1029 dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) {
1030 // Putting a load above a catchret and use on the phi would still leave
1031 // a cross-funclet def/use. We need to split the edge, change the
1032 // catchret to target the new block, and put the load there.
1033 BasicBlock *PHIBlock = UsingInst->getParent();
1034 BasicBlock *NewBlock = SplitEdge(IncomingBlock, PHIBlock);
1035 // SplitEdge gives us:
1036 // IncomingBlock:
1037 // ...
1038 // br label %NewBlock
1039 // NewBlock:
1040 // catchret label %PHIBlock
1041 // But we need:
1042 // IncomingBlock:
1043 // ...
1044 // catchret label %NewBlock
1045 // NewBlock:
1046 // br label %PHIBlock
1047 // So move the terminators to each others' blocks and swap their
1048 // successors.
1049 BranchInst *Goto = cast<BranchInst>(IncomingBlock->getTerminator());
1050 Goto->removeFromParent();
1051 CatchRet->removeFromParent();
1052 IncomingBlock->getInstList().push_back(CatchRet);
1053 NewBlock->getInstList().push_back(Goto);
1054 Goto->setSuccessor(0, PHIBlock);
1055 CatchRet->setSuccessor(NewBlock);
1056 // Update the color mapping for the newly split edge.
David Majnemer8a1c45d2015-12-12 05:38:55 +00001057 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
Joseph Tremoulet7031c9f2015-08-17 13:51:37 +00001058 BlockColors[NewBlock] = ColorsForPHIBlock;
1059 for (BasicBlock *FuncletPad : ColorsForPHIBlock)
David Majnemer8a1c45d2015-12-12 05:38:55 +00001060 FuncletBlocks[FuncletPad].push_back(NewBlock);
Joseph Tremoulet7031c9f2015-08-17 13:51:37 +00001061 // Treat the new block as incoming for load insertion.
1062 IncomingBlock = NewBlock;
1063 }
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001064 Value *&Load = Loads[IncomingBlock];
1065 // Insert the load into the predecessor block
1066 if (!Load)
1067 Load = new LoadInst(SpillSlot, Twine(V->getName(), ".wineh.reload"),
1068 /*Volatile=*/false, IncomingBlock->getTerminator());
1069
1070 U.set(Load);
1071 } else {
1072 // Reload right before the old use.
1073 auto *Load = new LoadInst(SpillSlot, Twine(V->getName(), ".wineh.reload"),
1074 /*Volatile=*/false, UsingInst);
1075 U.set(Load);
1076 }
1077}
Reid Klecknerc71d6272015-09-28 23:56:30 +00001078
David Majnemer8a1c45d2015-12-12 05:38:55 +00001079void WinEHFuncInfo::addIPToStateRange(const InvokeInst *II,
Reid Klecknerc71d6272015-09-28 23:56:30 +00001080 MCSymbol *InvokeBegin,
1081 MCSymbol *InvokeEnd) {
David Majnemer8a1c45d2015-12-12 05:38:55 +00001082 assert(InvokeStateMap.count(II) &&
1083 "should get invoke with precomputed state");
1084 LabelToStateMap[InvokeBegin] = std::make_pair(InvokeStateMap[II], InvokeEnd);
Reid Klecknerc71d6272015-09-28 23:56:30 +00001085}
Chandler Carruthe0115342015-12-29 09:24:39 +00001086
1087WinEHFuncInfo::WinEHFuncInfo() {}