blob: ae07e8b2fa03229a76eb51b327665d25c23a0e4e [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"
Joseph Tremoulet52f729a2016-01-04 16:16:01 +000020#include "llvm/ADT/DenseMap.h"
David Majnemer8a1c45d2015-12-12 05:38:55 +000021#include "llvm/ADT/MapVector.h"
Joseph Tremoulet52f729a2016-01-04 16:16:01 +000022#include "llvm/ADT/STLExtras.h"
David Majnemerfd9f4772015-08-11 01:15:26 +000023#include "llvm/Analysis/CFG.h"
David Majnemer70497c62015-12-02 23:06:39 +000024#include "llvm/Analysis/EHPersonalities.h"
Chandler Carruthe0115342015-12-29 09:24:39 +000025#include "llvm/CodeGen/MachineBasicBlock.h"
David Majnemercde33032015-03-30 22:58:10 +000026#include "llvm/CodeGen/WinEHFuncInfo.h"
David Majnemerdbdc9c22016-01-02 09:26:36 +000027#include "llvm/IR/Verifier.h"
Chandler Carruthe0115342015-12-29 09:24:39 +000028#include "llvm/MC/MCSymbol.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000029#include "llvm/Pass.h"
Andrew Kaylor6b67d422015-03-11 23:22:06 +000030#include "llvm/Support/Debug.h"
Benjamin Kramera8d61b12015-03-23 18:57:17 +000031#include "llvm/Support/raw_ostream.h"
Andrew Kaylor6b67d422015-03-11 23:22:06 +000032#include "llvm/Transforms/Utils/BasicBlockUtils.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000033#include "llvm/Transforms/Utils/Cloning.h"
34#include "llvm/Transforms/Utils/Local.h"
David Majnemer459a64a2015-09-16 18:40:37 +000035#include "llvm/Transforms/Utils/SSAUpdater.h"
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000036
37using namespace llvm;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000038
39#define DEBUG_TYPE "winehprepare"
40
David Majnemer459a64a2015-09-16 18:40:37 +000041static cl::opt<bool> DisableDemotion(
42 "disable-demotion", cl::Hidden,
43 cl::desc(
44 "Clone multicolor basic blocks but do not demote cross funclet values"),
45 cl::init(false));
46
47static cl::opt<bool> DisableCleanups(
48 "disable-cleanups", cl::Hidden,
49 cl::desc("Do not remove implausible terminators or other similar cleanups"),
50 cl::init(false));
51
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000052namespace {
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +000053
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000054class WinEHPrepare : public FunctionPass {
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000055public:
56 static char ID; // Pass identification, replacement for typeid.
David Majnemere6965832015-10-16 19:59:52 +000057 WinEHPrepare(const TargetMachine *TM = nullptr) : FunctionPass(ID) {}
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000058
59 bool runOnFunction(Function &Fn) override;
60
61 bool doFinalization(Module &M) override;
62
63 void getAnalysisUsage(AnalysisUsage &AU) const override;
64
Mehdi Amini117296c2016-10-01 02:56:57 +000065 StringRef getPassName() const override {
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000066 return "Windows exception handling preparation";
67 }
68
69private:
Joseph Tremouletc9ff9142015-08-13 14:30:10 +000070 void insertPHIStores(PHINode *OriginalPHI, AllocaInst *SpillSlot);
71 void
72 insertPHIStore(BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
73 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist);
74 AllocaInst *insertPHILoads(PHINode *PN, Function &F);
75 void replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
76 DenseMap<BasicBlock *, Value *> &Loads, Function &F);
David Majnemer8a1c45d2015-12-12 05:38:55 +000077 bool prepareExplicitEH(Function &F);
David Majnemer8a1c45d2015-12-12 05:38:55 +000078 void colorFunclets(Function &F);
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +000079
David Majnemerb3d9b962015-09-16 18:40:24 +000080 void demotePHIsOnFunclets(Function &F);
David Majnemer8a1c45d2015-12-12 05:38:55 +000081 void cloneCommonBlocks(Function &F);
David Majnemer3bb88c02015-12-15 21:27:27 +000082 void removeImplausibleInstructions(Function &F);
David Majnemerb3d9b962015-09-16 18:40:24 +000083 void cleanupPreparedFunclets(Function &F);
84 void verifyPreparedFunclets(Function &F);
David Majnemerfd9f4772015-08-11 01:15:26 +000085
Reid Kleckner0f9e27a2015-03-18 20:26:53 +000086 // All fields are reset by runOnFunction.
Reid Kleckner582786b2015-04-30 18:17:12 +000087 EHPersonality Personality = EHPersonality::Unknown;
David Majnemerfd9f4772015-08-11 01:15:26 +000088
Matt Arsenault3c1fc762017-04-10 22:27:50 +000089 const DataLayout *DL = nullptr;
David Majnemer8a1c45d2015-12-12 05:38:55 +000090 DenseMap<BasicBlock *, ColorVector> BlockColors;
91 MapVector<BasicBlock *, std::vector<BasicBlock *>> FuncletBlocks;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000092};
93
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000094} // end anonymous namespace
95
96char WinEHPrepare::ID = 0;
Reid Kleckner47c8e7a2015-03-12 00:36:20 +000097INITIALIZE_TM_PASS(WinEHPrepare, "winehprepare", "Prepare Windows exceptions",
98 false, false)
Andrew Kaylor1476e6d2015-02-24 20:49:35 +000099
100FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
101 return new WinEHPrepare(TM);
102}
103
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000104bool WinEHPrepare::runOnFunction(Function &Fn) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000105 if (!Fn.hasPersonalityFn())
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000106 return false;
107
108 // Classify the personality to see what kind of preparation we need.
David Majnemer7fddecc2015-06-17 20:52:32 +0000109 Personality = classifyEHPersonality(Fn.getPersonalityFn());
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000110
Joseph Tremoulet2afea542015-10-06 20:28:16 +0000111 // Do nothing if this is not a funclet-based personality.
112 if (!isFuncletEHPersonality(Personality))
Reid Kleckner47c8e7a2015-03-12 00:36:20 +0000113 return false;
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000114
Matt Arsenault3c1fc762017-04-10 22:27:50 +0000115 DL = &Fn.getParent()->getDataLayout();
David Majnemer8a1c45d2015-12-12 05:38:55 +0000116 return prepareExplicitEH(Fn);
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000117}
118
Andrew Kayloraa92ab02015-04-03 19:37:50 +0000119bool WinEHPrepare::doFinalization(Module &M) { return false; }
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000120
David Majnemere6965832015-10-16 19:59:52 +0000121void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {}
Andrew Kaylor1476e6d2015-02-24 20:49:35 +0000122
David Majnemer0ad363e2015-08-18 19:07:12 +0000123static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState,
David Majnemerbfa5b982015-10-10 00:04:29 +0000124 const BasicBlock *BB) {
Reid Kleckner14e77352015-10-09 23:34:53 +0000125 CxxUnwindMapEntry UME;
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000126 UME.ToState = ToState;
David Majnemerbfa5b982015-10-10 00:04:29 +0000127 UME.Cleanup = BB;
Reid Kleckner14e77352015-10-09 23:34:53 +0000128 FuncInfo.CxxUnwindMap.push_back(UME);
David Majnemer0ad363e2015-08-18 19:07:12 +0000129 return FuncInfo.getLastStateNumber();
130}
131
132static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
133 int TryHigh, int CatchHigh,
134 ArrayRef<const CatchPadInst *> Handlers) {
135 WinEHTryBlockMapEntry TBME;
136 TBME.TryLow = TryLow;
137 TBME.TryHigh = TryHigh;
138 TBME.CatchHigh = CatchHigh;
139 assert(TBME.TryLow <= TBME.TryHigh);
140 for (const CatchPadInst *CPI : Handlers) {
141 WinEHHandlerType HT;
142 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
Reid Klecknerb005d282015-09-16 20:16:27 +0000143 if (TypeInfo->isNullValue())
David Majnemer0ad363e2015-08-18 19:07:12 +0000144 HT.TypeDescriptor = nullptr;
Reid Klecknerb005d282015-09-16 20:16:27 +0000145 else
146 HT.TypeDescriptor = cast<GlobalVariable>(TypeInfo->stripPointerCasts());
147 HT.Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue();
David Majnemer7735a6d2015-10-06 23:31:59 +0000148 HT.Handler = CPI->getParent();
David Majnemer086fec22016-01-08 08:03:55 +0000149 if (auto *AI =
150 dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts()))
151 HT.CatchObj.Alloca = AI;
Reid Klecknerb005d282015-09-16 20:16:27 +0000152 else
David Majnemer086fec22016-01-08 08:03:55 +0000153 HT.CatchObj.Alloca = nullptr;
David Majnemer0ad363e2015-08-18 19:07:12 +0000154 TBME.HandlerArray.push_back(HT);
155 }
156 FuncInfo.TryBlockMap.push_back(TBME);
157}
158
David Majnemer8a1c45d2015-12-12 05:38:55 +0000159static BasicBlock *getCleanupRetUnwindDest(const CleanupPadInst *CleanupPad) {
160 for (const User *U : CleanupPad->users())
161 if (const auto *CRI = dyn_cast<CleanupReturnInst>(U))
162 return CRI->getUnwindDest();
David Majnemer0ad363e2015-08-18 19:07:12 +0000163 return nullptr;
164}
165
David Majnemer8a1c45d2015-12-12 05:38:55 +0000166static void calculateStateNumbersForInvokes(const Function *Fn,
167 WinEHFuncInfo &FuncInfo) {
168 auto *F = const_cast<Function *>(Fn);
169 DenseMap<BasicBlock *, ColorVector> BlockColors = colorEHFunclets(*F);
170 for (BasicBlock &BB : *F) {
171 auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
172 if (!II)
173 continue;
174
175 auto &BBColors = BlockColors[&BB];
David Majnemerc640f862015-12-23 03:59:04 +0000176 assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
David Majnemer8a1c45d2015-12-12 05:38:55 +0000177 BasicBlock *FuncletEntryBB = BBColors.front();
178
179 BasicBlock *FuncletUnwindDest;
180 auto *FuncletPad =
181 dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI());
182 assert(FuncletPad || FuncletEntryBB == &Fn->getEntryBlock());
183 if (!FuncletPad)
184 FuncletUnwindDest = nullptr;
185 else if (auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
186 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
187 else if (auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad))
188 FuncletUnwindDest = getCleanupRetUnwindDest(CleanupPad);
189 else
190 llvm_unreachable("unexpected funclet pad!");
191
192 BasicBlock *InvokeUnwindDest = II->getUnwindDest();
193 int BaseState = -1;
194 if (FuncletUnwindDest == InvokeUnwindDest) {
195 auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad);
196 if (BaseStateI != FuncInfo.FuncletBaseStateMap.end())
197 BaseState = BaseStateI->second;
198 }
199
200 if (BaseState != -1) {
201 FuncInfo.InvokeStateMap[II] = BaseState;
202 } else {
203 Instruction *PadInst = InvokeUnwindDest->getFirstNonPHI();
204 assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!");
205 FuncInfo.InvokeStateMap[II] = FuncInfo.EHPadStateMap[PadInst];
206 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000207 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000208}
209
David Majnemer0ad363e2015-08-18 19:07:12 +0000210// Given BB which ends in an unwind edge, return the EHPad that this BB belongs
211// to. If the unwind edge came from an invoke, return null.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000212static const BasicBlock *getEHPadFromPredecessor(const BasicBlock *BB,
213 Value *ParentPad) {
David Majnemer0ad363e2015-08-18 19:07:12 +0000214 const TerminatorInst *TI = BB->getTerminator();
215 if (isa<InvokeInst>(TI))
216 return nullptr;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000217 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
218 if (CatchSwitch->getParentPad() != ParentPad)
219 return nullptr;
David Majnemer0ad363e2015-08-18 19:07:12 +0000220 return BB;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000221 }
222 assert(!TI->isEHPad() && "unexpected EHPad!");
223 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
224 if (CleanupPad->getParentPad() != ParentPad)
225 return nullptr;
226 return CleanupPad->getParent();
David Majnemer0ad363e2015-08-18 19:07:12 +0000227}
228
David Majnemer8a1c45d2015-12-12 05:38:55 +0000229static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo,
230 const Instruction *FirstNonPHI,
231 int ParentState) {
232 const BasicBlock *BB = FirstNonPHI->getParent();
233 assert(BB->isEHPad() && "not a funclet!");
David Majnemer0ad363e2015-08-18 19:07:12 +0000234
David Majnemer8a1c45d2015-12-12 05:38:55 +0000235 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
236 assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
237 "shouldn't revist catch funclets!");
238
David Majnemer0ad363e2015-08-18 19:07:12 +0000239 SmallVector<const CatchPadInst *, 2> Handlers;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000240 for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
241 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
242 Handlers.push_back(CatchPad);
243 }
David Majnemer0ad363e2015-08-18 19:07:12 +0000244 int TryLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000245 FuncInfo.EHPadStateMap[CatchSwitch] = TryLow;
246 for (const BasicBlock *PredBlock : predecessors(BB))
247 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
248 CatchSwitch->getParentPad())))
249 calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
250 TryLow);
David Majnemer0ad363e2015-08-18 19:07:12 +0000251 int CatchLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000252
253 // catchpads are separate funclets in C++ EH due to the way rethrow works.
David Majnemer0ad363e2015-08-18 19:07:12 +0000254 int TryHigh = CatchLow - 1;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000255 for (const auto *CatchPad : Handlers) {
256 FuncInfo.FuncletBaseStateMap[CatchPad] = CatchLow;
257 for (const User *U : CatchPad->users()) {
258 const auto *UserI = cast<Instruction>(U);
David Majnemer17525ab2016-02-23 07:18:15 +0000259 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
260 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
261 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
David Majnemerc640f862015-12-23 03:59:04 +0000262 calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
David Majnemer17525ab2016-02-23 07:18:15 +0000263 }
Andrew Kaylord1188dd2016-02-12 21:10:16 +0000264 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
265 BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad);
266 // If a nested cleanup pad reports a null unwind destination and the
267 // enclosing catch pad doesn't it must be post-dominated by an
268 // unreachable instruction.
269 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
David Majnemerc640f862015-12-23 03:59:04 +0000270 calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
Andrew Kaylord1188dd2016-02-12 21:10:16 +0000271 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000272 }
273 }
David Majnemer0ad363e2015-08-18 19:07:12 +0000274 int CatchHigh = FuncInfo.getLastStateNumber();
275 addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchHigh, Handlers);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000276 DEBUG(dbgs() << "TryLow[" << BB->getName() << "]: " << TryLow << '\n');
277 DEBUG(dbgs() << "TryHigh[" << BB->getName() << "]: " << TryHigh << '\n');
278 DEBUG(dbgs() << "CatchHigh[" << BB->getName() << "]: " << CatchHigh
David Majnemer0ad363e2015-08-18 19:07:12 +0000279 << '\n');
David Majnemer0ad363e2015-08-18 19:07:12 +0000280 } else {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000281 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
282
283 // It's possible for a cleanup to be visited twice: it might have multiple
284 // cleanupret instructions.
285 if (FuncInfo.EHPadStateMap.count(CleanupPad))
286 return;
287
288 int CleanupState = addUnwindMapEntry(FuncInfo, ParentState, BB);
289 FuncInfo.EHPadStateMap[CleanupPad] = CleanupState;
290 DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
291 << BB->getName() << '\n');
292 for (const BasicBlock *PredBlock : predecessors(BB)) {
293 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
294 CleanupPad->getParentPad()))) {
295 calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
296 CleanupState);
297 }
298 }
299 for (const User *U : CleanupPad->users()) {
300 const auto *UserI = cast<Instruction>(U);
301 if (UserI->isEHPad())
302 report_fatal_error("Cleanup funclets for the MSVC++ personality cannot "
303 "contain exceptional actions");
304 }
David Majnemer0ad363e2015-08-18 19:07:12 +0000305 }
306}
307
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000308static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState,
309 const Function *Filter, const BasicBlock *Handler) {
Reid Kleckner94b704c2015-09-09 21:10:03 +0000310 SEHUnwindMapEntry Entry;
311 Entry.ToState = ParentState;
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000312 Entry.IsFinally = false;
Reid Kleckner94b704c2015-09-09 21:10:03 +0000313 Entry.Filter = Filter;
314 Entry.Handler = Handler;
315 FuncInfo.SEHUnwindMap.push_back(Entry);
316 return FuncInfo.SEHUnwindMap.size() - 1;
317}
318
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000319static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState,
320 const BasicBlock *Handler) {
321 SEHUnwindMapEntry Entry;
322 Entry.ToState = ParentState;
323 Entry.IsFinally = true;
324 Entry.Filter = nullptr;
325 Entry.Handler = Handler;
326 FuncInfo.SEHUnwindMap.push_back(Entry);
327 return FuncInfo.SEHUnwindMap.size() - 1;
328}
329
David Majnemer8a1c45d2015-12-12 05:38:55 +0000330static void calculateSEHStateNumbers(WinEHFuncInfo &FuncInfo,
331 const Instruction *FirstNonPHI,
332 int ParentState) {
333 const BasicBlock *BB = FirstNonPHI->getParent();
334 assert(BB->isEHPad() && "no a funclet!");
Reid Kleckner94b704c2015-09-09 21:10:03 +0000335
David Majnemer8a1c45d2015-12-12 05:38:55 +0000336 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
337 assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
338 "shouldn't revist catch funclets!");
339
Reid Kleckner94b704c2015-09-09 21:10:03 +0000340 // Extract the filter function and the __except basic block and create a
341 // state for them.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000342 assert(CatchSwitch->getNumHandlers() == 1 &&
Reid Kleckner94b704c2015-09-09 21:10:03 +0000343 "SEH doesn't have multiple handlers per __try");
David Majnemer8a1c45d2015-12-12 05:38:55 +0000344 const auto *CatchPad =
345 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI());
346 const BasicBlock *CatchPadBB = CatchPad->getParent();
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000347 const Constant *FilterOrNull =
David Majnemer8a1c45d2015-12-12 05:38:55 +0000348 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
Reid Klecknerfc64fae2015-10-01 21:38:24 +0000349 const Function *Filter = dyn_cast<Function>(FilterOrNull);
350 assert((Filter || FilterOrNull->isNullValue()) &&
351 "unexpected filter value");
David Majnemer7735a6d2015-10-06 23:31:59 +0000352 int TryState = addSEHExcept(FuncInfo, ParentState, Filter, CatchPadBB);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000353
354 // Everything in the __try block uses TryState as its parent state.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000355 FuncInfo.EHPadStateMap[CatchSwitch] = TryState;
Reid Kleckner94b704c2015-09-09 21:10:03 +0000356 DEBUG(dbgs() << "Assigning state #" << TryState << " to BB "
357 << CatchPadBB->getName() << '\n');
David Majnemer8a1c45d2015-12-12 05:38:55 +0000358 for (const BasicBlock *PredBlock : predecessors(BB))
359 if ((PredBlock = getEHPadFromPredecessor(PredBlock,
360 CatchSwitch->getParentPad())))
361 calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
362 TryState);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000363
364 // Everything in the __except block unwinds to ParentState, just like code
365 // outside the __try.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000366 for (const User *U : CatchPad->users()) {
367 const auto *UserI = cast<Instruction>(U);
David Majnemer17525ab2016-02-23 07:18:15 +0000368 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) {
369 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest();
370 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
David Majnemerc640f862015-12-23 03:59:04 +0000371 calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
David Majnemer17525ab2016-02-23 07:18:15 +0000372 }
Andrew Kaylord1188dd2016-02-12 21:10:16 +0000373 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) {
374 BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad);
375 // If a nested cleanup pad reports a null unwind destination and the
376 // enclosing catch pad doesn't it must be post-dominated by an
377 // unreachable instruction.
378 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest())
David Majnemerc640f862015-12-23 03:59:04 +0000379 calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
Andrew Kaylord1188dd2016-02-12 21:10:16 +0000380 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000381 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000382 } else {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000383 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
384
385 // It's possible for a cleanup to be visited twice: it might have multiple
386 // cleanupret instructions.
387 if (FuncInfo.EHPadStateMap.count(CleanupPad))
388 return;
389
390 int CleanupState = addSEHFinally(FuncInfo, ParentState, BB);
391 FuncInfo.EHPadStateMap[CleanupPad] = CleanupState;
392 DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
393 << BB->getName() << '\n');
394 for (const BasicBlock *PredBlock : predecessors(BB))
395 if ((PredBlock =
396 getEHPadFromPredecessor(PredBlock, CleanupPad->getParentPad())))
397 calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
398 CleanupState);
399 for (const User *U : CleanupPad->users()) {
400 const auto *UserI = cast<Instruction>(U);
401 if (UserI->isEHPad())
402 report_fatal_error("Cleanup funclets for the SEH personality cannot "
403 "contain exceptional actions");
404 }
Reid Kleckner94b704c2015-09-09 21:10:03 +0000405 }
406}
407
David Majnemer8a1c45d2015-12-12 05:38:55 +0000408static bool isTopLevelPadForMSVC(const Instruction *EHPad) {
409 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
410 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
411 CatchSwitch->unwindsToCaller();
412 if (auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
413 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
414 getCleanupRetUnwindDest(CleanupPad) == nullptr;
415 if (isa<CatchPadInst>(EHPad))
416 return false;
417 llvm_unreachable("unexpected EHPad!");
Reid Kleckner94b704c2015-09-09 21:10:03 +0000418}
419
Reid Kleckner813f1b62015-09-16 22:14:46 +0000420void llvm::calculateSEHStateNumbers(const Function *Fn,
Reid Kleckner94b704c2015-09-09 21:10:03 +0000421 WinEHFuncInfo &FuncInfo) {
422 // Don't compute state numbers twice.
423 if (!FuncInfo.SEHUnwindMap.empty())
424 return;
425
Reid Kleckner813f1b62015-09-16 22:14:46 +0000426 for (const BasicBlock &BB : *Fn) {
David Majnemer8a1c45d2015-12-12 05:38:55 +0000427 if (!BB.isEHPad())
Reid Kleckner94b704c2015-09-09 21:10:03 +0000428 continue;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000429 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
430 if (!isTopLevelPadForMSVC(FirstNonPHI))
431 continue;
432 ::calculateSEHStateNumbers(FuncInfo, FirstNonPHI, -1);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000433 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000434
435 calculateStateNumbersForInvokes(Fn, FuncInfo);
Reid Kleckner94b704c2015-09-09 21:10:03 +0000436}
437
Reid Kleckner813f1b62015-09-16 22:14:46 +0000438void llvm::calculateWinCXXEHStateNumbers(const Function *Fn,
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000439 WinEHFuncInfo &FuncInfo) {
440 // Return if it's already been done.
David Majnemer0ad363e2015-08-18 19:07:12 +0000441 if (!FuncInfo.EHPadStateMap.empty())
442 return;
443
Reid Kleckner813f1b62015-09-16 22:14:46 +0000444 for (const BasicBlock &BB : *Fn) {
David Majnemer0ad363e2015-08-18 19:07:12 +0000445 if (!BB.isEHPad())
446 continue;
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000447 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
David Majnemer8a1c45d2015-12-12 05:38:55 +0000448 if (!isTopLevelPadForMSVC(FirstNonPHI))
David Majnemer0ad363e2015-08-18 19:07:12 +0000449 continue;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000450 calculateCXXStateNumbers(FuncInfo, FirstNonPHI, -1);
David Majnemer0ad363e2015-08-18 19:07:12 +0000451 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000452
453 calculateStateNumbersForInvokes(Fn, FuncInfo);
Reid Klecknerfe4d4912015-05-28 22:00:24 +0000454}
David Majnemerfd9f4772015-08-11 01:15:26 +0000455
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000456static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int HandlerParentState,
457 int TryParentState, ClrHandlerType HandlerType,
458 uint32_t TypeToken, const BasicBlock *Handler) {
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000459 ClrEHUnwindMapEntry Entry;
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000460 Entry.HandlerParentState = HandlerParentState;
461 Entry.TryParentState = TryParentState;
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000462 Entry.Handler = Handler;
463 Entry.HandlerType = HandlerType;
464 Entry.TypeToken = TypeToken;
465 FuncInfo.ClrEHUnwindMap.push_back(Entry);
466 return FuncInfo.ClrEHUnwindMap.size() - 1;
467}
468
469void llvm::calculateClrEHStateNumbers(const Function *Fn,
470 WinEHFuncInfo &FuncInfo) {
471 // Return if it's already been done.
472 if (!FuncInfo.EHPadStateMap.empty())
473 return;
474
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000475 // This numbering assigns one state number to each catchpad and cleanuppad.
476 // It also computes two tree-like relations over states:
477 // 1) Each state has a "HandlerParentState", which is the state of the next
478 // outer handler enclosing this state's handler (same as nearest ancestor
479 // per the ParentPad linkage on EH pads, but skipping over catchswitches).
480 // 2) Each state has a "TryParentState", which:
481 // a) for a catchpad that's not the last handler on its catchswitch, is
482 // the state of the next catchpad on that catchswitch
483 // b) for all other pads, is the state of the pad whose try region is the
484 // next outer try region enclosing this state's try region. The "try
485 // regions are not present as such in the IR, but will be inferred
486 // based on the placement of invokes and pads which reach each other
487 // by exceptional exits
488 // Catchswitches do not get their own states, but each gets mapped to the
489 // state of its first catchpad.
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000490
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000491 // Step one: walk down from outermost to innermost funclets, assigning each
492 // catchpad and cleanuppad a state number. Add an entry to the
493 // ClrEHUnwindMap for each state, recording its HandlerParentState and
494 // handler attributes. Record the TryParentState as well for each catchpad
495 // that's not the last on its catchswitch, but initialize all other entries'
496 // TryParentStates to a sentinel -1 value that the next pass will update.
497
498 // Seed a worklist with pads that have no parent.
499 SmallVector<std::pair<const Instruction *, int>, 8> Worklist;
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000500 for (const BasicBlock &BB : *Fn) {
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000501 const Instruction *FirstNonPHI = BB.getFirstNonPHI();
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000502 const Value *ParentPad;
503 if (const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI))
504 ParentPad = CPI->getParentPad();
505 else if (const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI))
506 ParentPad = CSI->getParentPad();
507 else
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000508 continue;
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000509 if (isa<ConstantTokenNone>(ParentPad))
510 Worklist.emplace_back(FirstNonPHI, -1);
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000511 }
512
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000513 // Use the worklist to visit all pads, from outer to inner. Record
514 // HandlerParentState for all pads. Record TryParentState only for catchpads
515 // that aren't the last on their catchswitch (setting all other entries'
516 // TryParentStates to an initial value of -1). This loop is also responsible
517 // for setting the EHPadStateMap entry for all catchpads, cleanuppads, and
518 // catchswitches.
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000519 while (!Worklist.empty()) {
520 const Instruction *Pad;
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000521 int HandlerParentState;
522 std::tie(Pad, HandlerParentState) = Worklist.pop_back_val();
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000523
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000524 if (const auto *Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
525 // Create the entry for this cleanup with the appropriate handler
Simon Pilgrimf2fbf432016-11-20 13:47:59 +0000526 // properties. Finally and fault handlers are distinguished by arity.
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000527 ClrHandlerType HandlerType =
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000528 (Cleanup->getNumArgOperands() ? ClrHandlerType::Fault
529 : ClrHandlerType::Finally);
530 int CleanupState = addClrEHHandler(FuncInfo, HandlerParentState, -1,
531 HandlerType, 0, Pad->getParent());
532 // Queue any child EH pads on the worklist.
533 for (const User *U : Cleanup->users())
534 if (const auto *I = dyn_cast<Instruction>(U))
535 if (I->isEHPad())
536 Worklist.emplace_back(I, CleanupState);
537 // Remember this pad's state.
538 FuncInfo.EHPadStateMap[Cleanup] = CleanupState;
539 } else {
540 // Walk the handlers of this catchswitch in reverse order since all but
541 // the last need to set the following one as its TryParentState.
542 const auto *CatchSwitch = cast<CatchSwitchInst>(Pad);
543 int CatchState = -1, FollowerState = -1;
544 SmallVector<const BasicBlock *, 4> CatchBlocks(CatchSwitch->handlers());
545 for (auto CBI = CatchBlocks.rbegin(), CBE = CatchBlocks.rend();
546 CBI != CBE; ++CBI, FollowerState = CatchState) {
547 const BasicBlock *CatchBlock = *CBI;
548 // Create the entry for this catch with the appropriate handler
549 // properties.
550 const auto *Catch = cast<CatchPadInst>(CatchBlock->getFirstNonPHI());
David Majnemer8a1c45d2015-12-12 05:38:55 +0000551 uint32_t TypeToken = static_cast<uint32_t>(
552 cast<ConstantInt>(Catch->getArgOperand(0))->getZExtValue());
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000553 CatchState =
554 addClrEHHandler(FuncInfo, HandlerParentState, FollowerState,
555 ClrHandlerType::Catch, TypeToken, CatchBlock);
556 // Queue any child EH pads on the worklist.
557 for (const User *U : Catch->users())
558 if (const auto *I = dyn_cast<Instruction>(U))
559 if (I->isEHPad())
560 Worklist.emplace_back(I, CatchState);
561 // Remember this catch's state.
562 FuncInfo.EHPadStateMap[Catch] = CatchState;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000563 }
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000564 // Associate the catchswitch with the state of its first catch.
565 assert(CatchSwitch->getNumHandlers());
566 FuncInfo.EHPadStateMap[CatchSwitch] = CatchState;
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000567 }
568 }
David Majnemer8a1c45d2015-12-12 05:38:55 +0000569
Joseph Tremoulet52f729a2016-01-04 16:16:01 +0000570 // Step two: record the TryParentState of each state. For cleanuppads that
571 // don't have cleanuprets, we may need to infer this from their child pads,
572 // so visit pads in descendant-most to ancestor-most order.
573 for (auto Entry = FuncInfo.ClrEHUnwindMap.rbegin(),
574 End = FuncInfo.ClrEHUnwindMap.rend();
575 Entry != End; ++Entry) {
576 const Instruction *Pad =
577 Entry->Handler.get<const BasicBlock *>()->getFirstNonPHI();
578 // For most pads, the TryParentState is the state associated with the
579 // unwind dest of exceptional exits from it.
580 const BasicBlock *UnwindDest;
581 if (const auto *Catch = dyn_cast<CatchPadInst>(Pad)) {
582 // If a catch is not the last in its catchswitch, its TryParentState is
583 // the state associated with the next catch in the switch, even though
584 // that's not the unwind dest of exceptions escaping the catch. Those
585 // cases were already assigned a TryParentState in the first pass, so
586 // skip them.
587 if (Entry->TryParentState != -1)
588 continue;
589 // Otherwise, get the unwind dest from the catchswitch.
590 UnwindDest = Catch->getCatchSwitch()->getUnwindDest();
591 } else {
592 const auto *Cleanup = cast<CleanupPadInst>(Pad);
593 UnwindDest = nullptr;
594 for (const User *U : Cleanup->users()) {
595 if (auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) {
596 // Common and unambiguous case -- cleanupret indicates cleanup's
597 // unwind dest.
598 UnwindDest = CleanupRet->getUnwindDest();
599 break;
600 }
601
602 // Get an unwind dest for the user
603 const BasicBlock *UserUnwindDest = nullptr;
604 if (auto *Invoke = dyn_cast<InvokeInst>(U)) {
605 UserUnwindDest = Invoke->getUnwindDest();
606 } else if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) {
607 UserUnwindDest = CatchSwitch->getUnwindDest();
608 } else if (auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) {
609 int UserState = FuncInfo.EHPadStateMap[ChildCleanup];
610 int UserUnwindState =
611 FuncInfo.ClrEHUnwindMap[UserState].TryParentState;
612 if (UserUnwindState != -1)
613 UserUnwindDest = FuncInfo.ClrEHUnwindMap[UserUnwindState]
614 .Handler.get<const BasicBlock *>();
615 }
616
617 // Not having an unwind dest for this user might indicate that it
618 // doesn't unwind, so can't be taken as proof that the cleanup itself
619 // may unwind to caller (see e.g. SimplifyUnreachable and
620 // RemoveUnwindEdge).
621 if (!UserUnwindDest)
622 continue;
623
624 // Now we have an unwind dest for the user, but we need to see if it
625 // unwinds all the way out of the cleanup or if it stays within it.
626 const Instruction *UserUnwindPad = UserUnwindDest->getFirstNonPHI();
627 const Value *UserUnwindParent;
628 if (auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad))
629 UserUnwindParent = CSI->getParentPad();
630 else
631 UserUnwindParent =
632 cast<CleanupPadInst>(UserUnwindPad)->getParentPad();
633
634 // The unwind stays within the cleanup iff it targets a child of the
635 // cleanup.
636 if (UserUnwindParent == Cleanup)
637 continue;
638
639 // This unwind exits the cleanup, so its dest is the cleanup's dest.
640 UnwindDest = UserUnwindDest;
641 break;
642 }
643 }
644
645 // Record the state of the unwind dest as the TryParentState.
646 int UnwindDestState;
647
648 // If UnwindDest is null at this point, either the pad in question can
649 // be exited by unwind to caller, or it cannot be exited by unwind. In
650 // either case, reporting such cases as unwinding to caller is correct.
651 // This can lead to EH tables that "look strange" -- if this pad's is in
652 // a parent funclet which has other children that do unwind to an enclosing
653 // pad, the try region for this pad will be missing the "duplicate" EH
654 // clause entries that you'd expect to see covering the whole parent. That
655 // should be benign, since the unwind never actually happens. If it were
656 // an issue, we could add a subsequent pass that pushes unwind dests down
657 // from parents that have them to children that appear to unwind to caller.
658 if (!UnwindDest) {
659 UnwindDestState = -1;
660 } else {
661 UnwindDestState = FuncInfo.EHPadStateMap[UnwindDest->getFirstNonPHI()];
662 }
663
664 Entry->TryParentState = UnwindDestState;
665 }
666
667 // Step three: transfer information from pads to invokes.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000668 calculateStateNumbersForInvokes(Fn, FuncInfo);
Joseph Tremoulet7f8c1162015-10-06 20:30:33 +0000669}
670
David Majnemer8a1c45d2015-12-12 05:38:55 +0000671void WinEHPrepare::colorFunclets(Function &F) {
672 BlockColors = colorEHFunclets(F);
David Majnemerfd9f4772015-08-11 01:15:26 +0000673
David Majnemer8a1c45d2015-12-12 05:38:55 +0000674 // Invert the map from BB to colors to color to BBs.
675 for (BasicBlock &BB : F) {
676 ColorVector &Colors = BlockColors[&BB];
677 for (BasicBlock *Color : Colors)
678 FuncletBlocks[Color].push_back(&BB);
David Majnemerfd9f4772015-08-11 01:15:26 +0000679 }
680}
681
David Majnemerb3d9b962015-09-16 18:40:24 +0000682void WinEHPrepare::demotePHIsOnFunclets(Function &F) {
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000683 // Strip PHI nodes off of EH pads.
684 SmallVector<PHINode *, 16> PHINodes;
David Majnemerfd9f4772015-08-11 01:15:26 +0000685 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000686 BasicBlock *BB = &*FI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000687 if (!BB->isEHPad())
688 continue;
David Majnemerfd9f4772015-08-11 01:15:26 +0000689 for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +0000690 Instruction *I = &*BI++;
David Majnemerfd9f4772015-08-11 01:15:26 +0000691 auto *PN = dyn_cast<PHINode>(I);
692 // Stop at the first non-PHI.
693 if (!PN)
694 break;
David Majnemerfd9f4772015-08-11 01:15:26 +0000695
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000696 AllocaInst *SpillSlot = insertPHILoads(PN, F);
697 if (SpillSlot)
698 insertPHIStores(PN, SpillSlot);
699
700 PHINodes.push_back(PN);
David Majnemerfd9f4772015-08-11 01:15:26 +0000701 }
702 }
703
Joseph Tremouletc9ff9142015-08-13 14:30:10 +0000704 for (auto *PN : PHINodes) {
705 // There may be lingering uses on other EH PHIs being removed
706 PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
707 PN->eraseFromParent();
David Majnemerfd9f4772015-08-11 01:15:26 +0000708 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000709}
David Majnemerfd9f4772015-08-11 01:15:26 +0000710
David Majnemer8a1c45d2015-12-12 05:38:55 +0000711void WinEHPrepare::cloneCommonBlocks(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +0000712 // We need to clone all blocks which belong to multiple funclets. Values are
Simon Pilgrimf2fbf432016-11-20 13:47:59 +0000713 // remapped throughout the funclet to propagate both the new instructions
David Majnemerfd9f4772015-08-11 01:15:26 +0000714 // *and* the new basic blocks themselves.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000715 for (auto &Funclets : FuncletBlocks) {
716 BasicBlock *FuncletPadBB = Funclets.first;
717 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
Joseph Tremoulet71e56762016-01-02 15:22:36 +0000718 Value *FuncletToken;
719 if (FuncletPadBB == &F.getEntryBlock())
720 FuncletToken = ConstantTokenNone::get(F.getContext());
721 else
722 FuncletToken = FuncletPadBB->getFirstNonPHI();
David Majnemerfd9f4772015-08-11 01:15:26 +0000723
David Majnemer8a1c45d2015-12-12 05:38:55 +0000724 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
David Majnemerfd9f4772015-08-11 01:15:26 +0000725 ValueToValueMapTy VMap;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000726 for (BasicBlock *BB : BlocksInFunclet) {
727 ColorVector &ColorsForBB = BlockColors[BB];
David Majnemerfd9f4772015-08-11 01:15:26 +0000728 // We don't need to do anything if the block is monochromatic.
729 size_t NumColorsForBB = ColorsForBB.size();
730 if (NumColorsForBB == 1)
731 continue;
732
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +0000733 DEBUG_WITH_TYPE("winehprepare-coloring",
734 dbgs() << " Cloning block \'" << BB->getName()
735 << "\' for funclet \'" << FuncletPadBB->getName()
736 << "\'.\n");
737
David Majnemerfd9f4772015-08-11 01:15:26 +0000738 // Create a new basic block and copy instructions into it!
Joseph Tremouletec182852015-08-28 01:12:35 +0000739 BasicBlock *CBB =
740 CloneBasicBlock(BB, VMap, Twine(".for.", FuncletPadBB->getName()));
741 // Insert the clone immediately after the original to ensure determinism
742 // and to keep the same relative ordering of any funclet's blocks.
743 CBB->insertInto(&F, BB->getNextNode());
David Majnemerfd9f4772015-08-11 01:15:26 +0000744
745 // Add basic block mapping.
746 VMap[BB] = CBB;
747
748 // Record delta operations that we need to perform to our color mappings.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000749 Orig2Clone.emplace_back(BB, CBB);
David Majnemerfd9f4772015-08-11 01:15:26 +0000750 }
751
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000752 // If nothing was cloned, we're done cloning in this funclet.
753 if (Orig2Clone.empty())
754 continue;
755
David Majnemerfd9f4772015-08-11 01:15:26 +0000756 // Update our color mappings to reflect that one block has lost a color and
757 // another has gained a color.
758 for (auto &BBMapping : Orig2Clone) {
759 BasicBlock *OldBlock = BBMapping.first;
760 BasicBlock *NewBlock = BBMapping.second;
761
David Majnemer8a1c45d2015-12-12 05:38:55 +0000762 BlocksInFunclet.push_back(NewBlock);
763 ColorVector &NewColors = BlockColors[NewBlock];
764 assert(NewColors.empty() && "A new block should only have one color!");
765 NewColors.push_back(FuncletPadBB);
David Majnemerfd9f4772015-08-11 01:15:26 +0000766
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +0000767 DEBUG_WITH_TYPE("winehprepare-coloring",
768 dbgs() << " Assigned color \'" << FuncletPadBB->getName()
769 << "\' to block \'" << NewBlock->getName()
770 << "\'.\n");
771
David Majnemer8a1c45d2015-12-12 05:38:55 +0000772 BlocksInFunclet.erase(
773 std::remove(BlocksInFunclet.begin(), BlocksInFunclet.end(), OldBlock),
774 BlocksInFunclet.end());
775 ColorVector &OldColors = BlockColors[OldBlock];
776 OldColors.erase(
777 std::remove(OldColors.begin(), OldColors.end(), FuncletPadBB),
778 OldColors.end());
Andrew Kaylorfdd48fa2015-11-09 19:59:02 +0000779
780 DEBUG_WITH_TYPE("winehprepare-coloring",
781 dbgs() << " Removed color \'" << FuncletPadBB->getName()
782 << "\' from block \'" << OldBlock->getName()
783 << "\'.\n");
David Majnemerfd9f4772015-08-11 01:15:26 +0000784 }
785
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000786 // Loop over all of the instructions in this funclet, fixing up operand
David Majnemerfd9f4772015-08-11 01:15:26 +0000787 // references as we go. This uses VMap to do all the hard work.
788 for (BasicBlock *BB : BlocksInFunclet)
789 // Loop over all instructions, fixing each one as we find it...
790 for (Instruction &I : *BB)
Joseph Tremoulet39234fc2015-10-07 19:29:56 +0000791 RemapInstruction(&I, VMap,
Duncan P. N. Exon Smithda68cbc2016-04-07 00:26:43 +0000792 RF_IgnoreMissingLocals | RF_NoModuleLevelChanges);
David Majnemer459a64a2015-09-16 18:40:37 +0000793
Joseph Tremoulet71e56762016-01-02 15:22:36 +0000794 // Catchrets targeting cloned blocks need to be updated separately from
795 // the loop above because they are not in the current funclet.
796 SmallVector<CatchReturnInst *, 2> FixupCatchrets;
797 for (auto &BBMapping : Orig2Clone) {
798 BasicBlock *OldBlock = BBMapping.first;
799 BasicBlock *NewBlock = BBMapping.second;
800
801 FixupCatchrets.clear();
802 for (BasicBlock *Pred : predecessors(OldBlock))
803 if (auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
Joseph Tremoulet44b3f962016-01-15 21:16:19 +0000804 if (CatchRet->getCatchSwitchParentPad() == FuncletToken)
Joseph Tremoulet71e56762016-01-02 15:22:36 +0000805 FixupCatchrets.push_back(CatchRet);
806
807 for (CatchReturnInst *CatchRet : FixupCatchrets)
808 CatchRet->setSuccessor(NewBlock);
809 }
810
David Majnemer8a1c45d2015-12-12 05:38:55 +0000811 auto UpdatePHIOnClonedBlock = [&](PHINode *PN, bool IsForOldBlock) {
812 unsigned NumPreds = PN->getNumIncomingValues();
813 for (unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
814 ++PredIdx) {
815 BasicBlock *IncomingBlock = PN->getIncomingBlock(PredIdx);
Joseph Tremoulet71e56762016-01-02 15:22:36 +0000816 bool EdgeTargetsFunclet;
817 if (auto *CRI =
818 dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) {
Joseph Tremoulet44b3f962016-01-15 21:16:19 +0000819 EdgeTargetsFunclet = (CRI->getCatchSwitchParentPad() == FuncletToken);
Joseph Tremoulet71e56762016-01-02 15:22:36 +0000820 } else {
821 ColorVector &IncomingColors = BlockColors[IncomingBlock];
822 assert(!IncomingColors.empty() && "Block not colored!");
823 assert((IncomingColors.size() == 1 ||
824 llvm::all_of(IncomingColors,
825 [&](BasicBlock *Color) {
826 return Color != FuncletPadBB;
827 })) &&
828 "Cloning should leave this funclet's blocks monochromatic");
829 EdgeTargetsFunclet = (IncomingColors.front() == FuncletPadBB);
830 }
831 if (IsForOldBlock != EdgeTargetsFunclet)
David Majnemer8a1c45d2015-12-12 05:38:55 +0000832 continue;
833 PN->removeIncomingValue(IncomingBlock, /*DeletePHIIfEmpty=*/false);
834 // Revisit the next entry.
835 --PredIdx;
836 --PredEnd;
837 }
838 };
839
840 for (auto &BBMapping : Orig2Clone) {
841 BasicBlock *OldBlock = BBMapping.first;
842 BasicBlock *NewBlock = BBMapping.second;
843 for (Instruction &OldI : *OldBlock) {
844 auto *OldPN = dyn_cast<PHINode>(&OldI);
845 if (!OldPN)
846 break;
847 UpdatePHIOnClonedBlock(OldPN, /*IsForOldBlock=*/true);
848 }
849 for (Instruction &NewI : *NewBlock) {
850 auto *NewPN = dyn_cast<PHINode>(&NewI);
851 if (!NewPN)
852 break;
853 UpdatePHIOnClonedBlock(NewPN, /*IsForOldBlock=*/false);
854 }
855 }
856
David Majnemer459a64a2015-09-16 18:40:37 +0000857 // Check to see if SuccBB has PHI nodes. If so, we need to add entries to
858 // the PHI nodes for NewBB now.
859 for (auto &BBMapping : Orig2Clone) {
860 BasicBlock *OldBlock = BBMapping.first;
861 BasicBlock *NewBlock = BBMapping.second;
862 for (BasicBlock *SuccBB : successors(NewBlock)) {
863 for (Instruction &SuccI : *SuccBB) {
864 auto *SuccPN = dyn_cast<PHINode>(&SuccI);
865 if (!SuccPN)
866 break;
867
868 // Ok, we have a PHI node. Figure out what the incoming value was for
869 // the OldBlock.
870 int OldBlockIdx = SuccPN->getBasicBlockIndex(OldBlock);
871 if (OldBlockIdx == -1)
872 break;
873 Value *IV = SuccPN->getIncomingValue(OldBlockIdx);
874
875 // Remap the value if necessary.
876 if (auto *Inst = dyn_cast<Instruction>(IV)) {
877 ValueToValueMapTy::iterator I = VMap.find(Inst);
878 if (I != VMap.end())
879 IV = I->second;
880 }
881
882 SuccPN->addIncoming(IV, NewBlock);
883 }
884 }
885 }
886
887 for (ValueToValueMapTy::value_type VT : VMap) {
888 // If there were values defined in BB that are used outside the funclet,
889 // then we now have to update all uses of the value to use either the
890 // original value, the cloned value, or some PHI derived value. This can
891 // require arbitrary PHI insertion, of which we are prepared to do, clean
892 // these up now.
893 SmallVector<Use *, 16> UsesToRename;
894
895 auto *OldI = dyn_cast<Instruction>(const_cast<Value *>(VT.first));
896 if (!OldI)
897 continue;
898 auto *NewI = cast<Instruction>(VT.second);
899 // Scan all uses of this instruction to see if it is used outside of its
900 // funclet, and if so, record them in UsesToRename.
901 for (Use &U : OldI->uses()) {
902 Instruction *UserI = cast<Instruction>(U.getUser());
903 BasicBlock *UserBB = UserI->getParent();
David Majnemer8a1c45d2015-12-12 05:38:55 +0000904 ColorVector &ColorsForUserBB = BlockColors[UserBB];
David Majnemer459a64a2015-09-16 18:40:37 +0000905 assert(!ColorsForUserBB.empty());
906 if (ColorsForUserBB.size() > 1 ||
907 *ColorsForUserBB.begin() != FuncletPadBB)
908 UsesToRename.push_back(&U);
909 }
910
911 // If there are no uses outside the block, we're done with this
912 // instruction.
913 if (UsesToRename.empty())
914 continue;
915
916 // We found a use of OldI outside of the funclet. Rename all uses of OldI
917 // that are outside its funclet to be uses of the appropriate PHI node
918 // etc.
919 SSAUpdater SSAUpdate;
920 SSAUpdate.Initialize(OldI->getType(), OldI->getName());
921 SSAUpdate.AddAvailableValue(OldI->getParent(), OldI);
922 SSAUpdate.AddAvailableValue(NewI->getParent(), NewI);
923
924 while (!UsesToRename.empty())
925 SSAUpdate.RewriteUseAfterInsertions(*UsesToRename.pop_back_val());
926 }
David Majnemerfd9f4772015-08-11 01:15:26 +0000927 }
David Majnemerb3d9b962015-09-16 18:40:24 +0000928}
David Majnemerfd9f4772015-08-11 01:15:26 +0000929
David Majnemer3bb88c02015-12-15 21:27:27 +0000930void WinEHPrepare::removeImplausibleInstructions(Function &F) {
David Majnemer83f4bb22015-08-17 20:56:39 +0000931 // Remove implausible terminators and replace them with UnreachableInst.
932 for (auto &Funclet : FuncletBlocks) {
933 BasicBlock *FuncletPadBB = Funclet.first;
David Majnemer8a1c45d2015-12-12 05:38:55 +0000934 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
David Majnemer3bb88c02015-12-15 21:27:27 +0000935 Instruction *FirstNonPHI = FuncletPadBB->getFirstNonPHI();
936 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
937 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
938 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
David Majnemer83f4bb22015-08-17 20:56:39 +0000939
940 for (BasicBlock *BB : BlocksInFunclet) {
David Majnemer3bb88c02015-12-15 21:27:27 +0000941 for (Instruction &I : *BB) {
942 CallSite CS(&I);
943 if (!CS)
944 continue;
945
946 Value *FuncletBundleOperand = nullptr;
947 if (auto BU = CS.getOperandBundle(LLVMContext::OB_funclet))
948 FuncletBundleOperand = BU->Inputs.front();
949
950 if (FuncletBundleOperand == FuncletPad)
951 continue;
952
David Majnemer08dd52dc2016-02-26 00:04:25 +0000953 // Skip call sites which are nounwind intrinsics or inline asm.
David Majnemer3bb88c02015-12-15 21:27:27 +0000954 auto *CalledFn =
955 dyn_cast<Function>(CS.getCalledValue()->stripPointerCasts());
Justin Lebar9cbc3012016-07-28 23:58:15 +0000956 if (CalledFn && ((CalledFn->isIntrinsic() && CS.doesNotThrow()) ||
957 CS.isInlineAsm()))
David Majnemer3bb88c02015-12-15 21:27:27 +0000958 continue;
959
960 // This call site was not part of this funclet, remove it.
961 if (CS.isInvoke()) {
962 // Remove the unwind edge if it was an invoke.
963 removeUnwindEdge(BB);
964 // Get a pointer to the new call.
965 BasicBlock::iterator CallI =
966 std::prev(BB->getTerminator()->getIterator());
967 auto *CI = cast<CallInst>(&*CallI);
David Majnemere14e7bc2016-06-25 08:19:55 +0000968 changeToUnreachable(CI, /*UseLLVMTrap=*/false);
David Majnemer3bb88c02015-12-15 21:27:27 +0000969 } else {
David Majnemere14e7bc2016-06-25 08:19:55 +0000970 changeToUnreachable(&I, /*UseLLVMTrap=*/false);
David Majnemer3bb88c02015-12-15 21:27:27 +0000971 }
972
973 // There are no more instructions in the block (except for unreachable),
974 // we are done.
975 break;
976 }
977
David Majnemer83f4bb22015-08-17 20:56:39 +0000978 TerminatorInst *TI = BB->getTerminator();
979 // CatchPadInst and CleanupPadInst can't transfer control to a ReturnInst.
David Majnemer3bb88c02015-12-15 21:27:27 +0000980 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
David Majnemer83f4bb22015-08-17 20:56:39 +0000981 // The token consumed by a CatchReturnInst must match the funclet token.
982 bool IsUnreachableCatchret = false;
983 if (auto *CRI = dyn_cast<CatchReturnInst>(TI))
Joseph Tremoulet8220bcc2015-08-23 00:26:33 +0000984 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000985 // The token consumed by a CleanupReturnInst must match the funclet token.
David Majnemer83f4bb22015-08-17 20:56:39 +0000986 bool IsUnreachableCleanupret = false;
987 if (auto *CRI = dyn_cast<CleanupReturnInst>(TI))
Joseph Tremoulet8220bcc2015-08-23 00:26:33 +0000988 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
Joseph Tremoulet9ce71f72015-09-03 09:09:43 +0000989 if (IsUnreachableRet || IsUnreachableCatchret ||
David Majnemer8a1c45d2015-12-12 05:38:55 +0000990 IsUnreachableCleanupret) {
David Majnemere14e7bc2016-06-25 08:19:55 +0000991 changeToUnreachable(TI, /*UseLLVMTrap=*/false);
David Majnemer8a1c45d2015-12-12 05:38:55 +0000992 } else if (isa<InvokeInst>(TI)) {
David Majnemer3bb88c02015-12-15 21:27:27 +0000993 if (Personality == EHPersonality::MSVC_CXX && CleanupPad) {
994 // Invokes within a cleanuppad for the MSVC++ personality never
995 // transfer control to their unwind edge: the personality will
996 // terminate the program.
David Majnemer8a1c45d2015-12-12 05:38:55 +0000997 removeUnwindEdge(BB);
David Majnemer3bb88c02015-12-15 21:27:27 +0000998 }
David Majnemer83f4bb22015-08-17 20:56:39 +0000999 }
1000 }
1001 }
David Majnemerb3d9b962015-09-16 18:40:24 +00001002}
David Majnemer83f4bb22015-08-17 20:56:39 +00001003
David Majnemerb3d9b962015-09-16 18:40:24 +00001004void WinEHPrepare::cleanupPreparedFunclets(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +00001005 // Clean-up some of the mess we made by removing useles PHI nodes, trivial
1006 // branches, etc.
1007 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001008 BasicBlock *BB = &*FI++;
David Majnemerfd9f4772015-08-11 01:15:26 +00001009 SimplifyInstructionsInBlock(BB);
1010 ConstantFoldTerminator(BB, /*DeleteDeadConditions=*/true);
1011 MergeBlockIntoPredecessor(BB);
1012 }
1013
David Majnemerfd9f4772015-08-11 01:15:26 +00001014 // We might have some unreachable blocks after cleaning up some impossible
1015 // control flow.
1016 removeUnreachableBlocks(F);
David Majnemerb3d9b962015-09-16 18:40:24 +00001017}
David Majnemerfd9f4772015-08-11 01:15:26 +00001018
David Majnemerb3d9b962015-09-16 18:40:24 +00001019void WinEHPrepare::verifyPreparedFunclets(Function &F) {
David Majnemerfd9f4772015-08-11 01:15:26 +00001020 for (BasicBlock &BB : F) {
1021 size_t NumColors = BlockColors[&BB].size();
1022 assert(NumColors == 1 && "Expected monochromatic BB!");
1023 if (NumColors == 0)
1024 report_fatal_error("Uncolored BB!");
1025 if (NumColors > 1)
1026 report_fatal_error("Multicolor BB!");
NAKAMURA Takumided575e2016-01-03 01:41:00 +00001027 assert((DisableDemotion || !(BB.isEHPad() && isa<PHINode>(BB.begin()))) &&
1028 "EH Pad still has a PHI!");
David Majnemerfd9f4772015-08-11 01:15:26 +00001029 }
David Majnemerb3d9b962015-09-16 18:40:24 +00001030}
1031
David Majnemer8a1c45d2015-12-12 05:38:55 +00001032bool WinEHPrepare::prepareExplicitEH(Function &F) {
1033 // Remove unreachable blocks. It is not valuable to assign them a color and
1034 // their existence can trick us into thinking values are alive when they are
1035 // not.
1036 removeUnreachableBlocks(F);
1037
David Majnemerb3d9b962015-09-16 18:40:24 +00001038 // Determine which blocks are reachable from which funclet entries.
David Majnemer8a1c45d2015-12-12 05:38:55 +00001039 colorFunclets(F);
1040
1041 cloneCommonBlocks(F);
David Majnemerb3d9b962015-09-16 18:40:24 +00001042
Reid Klecknercc2f6c32015-11-19 23:23:33 +00001043 if (!DisableDemotion)
David Majnemer459a64a2015-09-16 18:40:37 +00001044 demotePHIsOnFunclets(F);
David Majnemerb3d9b962015-09-16 18:40:24 +00001045
David Majnemer459a64a2015-09-16 18:40:37 +00001046 if (!DisableCleanups) {
David Majnemerdbdc9c22016-01-02 09:26:36 +00001047 DEBUG(verifyFunction(F));
David Majnemer3bb88c02015-12-15 21:27:27 +00001048 removeImplausibleInstructions(F);
David Majnemerb3d9b962015-09-16 18:40:24 +00001049
David Majnemerdbdc9c22016-01-02 09:26:36 +00001050 DEBUG(verifyFunction(F));
David Majnemer459a64a2015-09-16 18:40:37 +00001051 cleanupPreparedFunclets(F);
1052 }
David Majnemerb3d9b962015-09-16 18:40:24 +00001053
David Majnemerdbdc9c22016-01-02 09:26:36 +00001054 DEBUG(verifyPreparedFunclets(F));
1055 // Recolor the CFG to verify that all is well.
1056 DEBUG(colorFunclets(F));
1057 DEBUG(verifyPreparedFunclets(F));
David Majnemerfd9f4772015-08-11 01:15:26 +00001058
1059 BlockColors.clear();
1060 FuncletBlocks.clear();
David Majnemer0ad363e2015-08-18 19:07:12 +00001061
David Majnemerfd9f4772015-08-11 01:15:26 +00001062 return true;
1063}
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001064
1065// TODO: Share loads when one use dominates another, or when a catchpad exit
1066// dominates uses (needs dominators).
1067AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) {
1068 BasicBlock *PHIBlock = PN->getParent();
1069 AllocaInst *SpillSlot = nullptr;
David Majnemer8a1c45d2015-12-12 05:38:55 +00001070 Instruction *EHPad = PHIBlock->getFirstNonPHI();
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001071
David Majnemer8a1c45d2015-12-12 05:38:55 +00001072 if (!isa<TerminatorInst>(EHPad)) {
1073 // If the EHPad isn't a terminator, then we can insert a load in this block
1074 // that will dominate all uses.
Matt Arsenault3c1fc762017-04-10 22:27:50 +00001075 SpillSlot = new AllocaInst(PN->getType(), DL->getAllocaAddrSpace(), nullptr,
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001076 Twine(PN->getName(), ".wineh.spillslot"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001077 &F.getEntryBlock().front());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001078 Value *V = new LoadInst(SpillSlot, Twine(PN->getName(), ".wineh.reload"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001079 &*PHIBlock->getFirstInsertionPt());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001080 PN->replaceAllUsesWith(V);
1081 return SpillSlot;
1082 }
1083
David Majnemer8a1c45d2015-12-12 05:38:55 +00001084 // Otherwise, we have a PHI on a terminator EHPad, and we give up and insert
1085 // loads of the slot before every use.
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001086 DenseMap<BasicBlock *, Value *> Loads;
1087 for (Value::use_iterator UI = PN->use_begin(), UE = PN->use_end();
1088 UI != UE;) {
1089 Use &U = *UI++;
1090 auto *UsingInst = cast<Instruction>(U.getUser());
David Majnemer8a1c45d2015-12-12 05:38:55 +00001091 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001092 // Use is on an EH pad phi. Leave it alone; we'll insert loads and
1093 // stores for it separately.
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001094 continue;
1095 }
1096 replaceUseWithLoad(PN, U, SpillSlot, Loads, F);
1097 }
1098 return SpillSlot;
1099}
1100
1101// TODO: improve store placement. Inserting at def is probably good, but need
1102// to be careful not to introduce interfering stores (needs liveness analysis).
1103// TODO: identify related phi nodes that can share spill slots, and share them
1104// (also needs liveness).
1105void WinEHPrepare::insertPHIStores(PHINode *OriginalPHI,
1106 AllocaInst *SpillSlot) {
1107 // Use a worklist of (Block, Value) pairs -- the given Value needs to be
1108 // stored to the spill slot by the end of the given Block.
1109 SmallVector<std::pair<BasicBlock *, Value *>, 4> Worklist;
1110
1111 Worklist.push_back({OriginalPHI->getParent(), OriginalPHI});
1112
1113 while (!Worklist.empty()) {
1114 BasicBlock *EHBlock;
1115 Value *InVal;
1116 std::tie(EHBlock, InVal) = Worklist.pop_back_val();
1117
1118 PHINode *PN = dyn_cast<PHINode>(InVal);
1119 if (PN && PN->getParent() == EHBlock) {
1120 // The value is defined by another PHI we need to remove, with no room to
1121 // insert a store after the PHI, so each predecessor needs to store its
1122 // incoming value.
1123 for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) {
1124 Value *PredVal = PN->getIncomingValue(i);
1125
1126 // Undef can safely be skipped.
1127 if (isa<UndefValue>(PredVal))
1128 continue;
1129
1130 insertPHIStore(PN->getIncomingBlock(i), PredVal, SpillSlot, Worklist);
1131 }
1132 } else {
1133 // We need to store InVal, which dominates EHBlock, but can't put a store
1134 // in EHBlock, so need to put stores in each predecessor.
1135 for (BasicBlock *PredBlock : predecessors(EHBlock)) {
1136 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist);
1137 }
1138 }
1139 }
1140}
1141
1142void WinEHPrepare::insertPHIStore(
1143 BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot,
1144 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist) {
1145
1146 if (PredBlock->isEHPad() &&
David Majnemer8a1c45d2015-12-12 05:38:55 +00001147 isa<TerminatorInst>(PredBlock->getFirstNonPHI())) {
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001148 // Pred is unsplittable, so we need to queue it on the worklist.
1149 Worklist.push_back({PredBlock, PredVal});
1150 return;
1151 }
1152
1153 // Otherwise, insert the store at the end of the basic block.
1154 new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator());
1155}
1156
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001157void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
1158 DenseMap<BasicBlock *, Value *> &Loads,
1159 Function &F) {
1160 // Lazilly create the spill slot.
1161 if (!SpillSlot)
Matt Arsenault3c1fc762017-04-10 22:27:50 +00001162 SpillSlot = new AllocaInst(V->getType(), DL->getAllocaAddrSpace(), nullptr,
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001163 Twine(V->getName(), ".wineh.spillslot"),
Duncan P. N. Exon Smithf1ff53e2015-10-09 22:56:24 +00001164 &F.getEntryBlock().front());
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001165
1166 auto *UsingInst = cast<Instruction>(U.getUser());
1167 if (auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) {
1168 // If this is a PHI node, we can't insert a load of the value before
1169 // the use. Instead insert the load in the predecessor block
1170 // corresponding to the incoming value.
1171 //
1172 // Note that if there are multiple edges from a basic block to this
1173 // PHI node that we cannot have multiple loads. The problem is that
1174 // the resulting PHI node will have multiple values (from each load)
1175 // coming in from the same block, which is illegal SSA form.
1176 // For this reason, we keep track of and reuse loads we insert.
1177 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U);
Joseph Tremoulet7031c9f2015-08-17 13:51:37 +00001178 if (auto *CatchRet =
1179 dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) {
1180 // Putting a load above a catchret and use on the phi would still leave
1181 // a cross-funclet def/use. We need to split the edge, change the
1182 // catchret to target the new block, and put the load there.
1183 BasicBlock *PHIBlock = UsingInst->getParent();
1184 BasicBlock *NewBlock = SplitEdge(IncomingBlock, PHIBlock);
1185 // SplitEdge gives us:
1186 // IncomingBlock:
1187 // ...
1188 // br label %NewBlock
1189 // NewBlock:
1190 // catchret label %PHIBlock
1191 // But we need:
1192 // IncomingBlock:
1193 // ...
1194 // catchret label %NewBlock
1195 // NewBlock:
1196 // br label %PHIBlock
1197 // So move the terminators to each others' blocks and swap their
1198 // successors.
1199 BranchInst *Goto = cast<BranchInst>(IncomingBlock->getTerminator());
1200 Goto->removeFromParent();
1201 CatchRet->removeFromParent();
1202 IncomingBlock->getInstList().push_back(CatchRet);
1203 NewBlock->getInstList().push_back(Goto);
1204 Goto->setSuccessor(0, PHIBlock);
1205 CatchRet->setSuccessor(NewBlock);
1206 // Update the color mapping for the newly split edge.
Andrew Kaylorce3bcae2016-12-14 19:30:18 +00001207 // Grab a reference to the ColorVector to be inserted before getting the
1208 // reference to the vector we are copying because inserting the new
1209 // element in BlockColors might cause the map to be reallocated.
1210 ColorVector &ColorsForNewBlock = BlockColors[NewBlock];
David Majnemer8a1c45d2015-12-12 05:38:55 +00001211 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
Andrew Kaylorce3bcae2016-12-14 19:30:18 +00001212 ColorsForNewBlock = ColorsForPHIBlock;
Joseph Tremoulet7031c9f2015-08-17 13:51:37 +00001213 for (BasicBlock *FuncletPad : ColorsForPHIBlock)
David Majnemer8a1c45d2015-12-12 05:38:55 +00001214 FuncletBlocks[FuncletPad].push_back(NewBlock);
Joseph Tremoulet7031c9f2015-08-17 13:51:37 +00001215 // Treat the new block as incoming for load insertion.
1216 IncomingBlock = NewBlock;
1217 }
Joseph Tremouletc9ff9142015-08-13 14:30:10 +00001218 Value *&Load = Loads[IncomingBlock];
1219 // Insert the load into the predecessor block
1220 if (!Load)
1221 Load = new LoadInst(SpillSlot, Twine(V->getName(), ".wineh.reload"),
1222 /*Volatile=*/false, IncomingBlock->getTerminator());
1223
1224 U.set(Load);
1225 } else {
1226 // Reload right before the old use.
1227 auto *Load = new LoadInst(SpillSlot, Twine(V->getName(), ".wineh.reload"),
1228 /*Volatile=*/false, UsingInst);
1229 U.set(Load);
1230 }
1231}
Reid Klecknerc71d6272015-09-28 23:56:30 +00001232
David Majnemer8a1c45d2015-12-12 05:38:55 +00001233void WinEHFuncInfo::addIPToStateRange(const InvokeInst *II,
Reid Klecknerc71d6272015-09-28 23:56:30 +00001234 MCSymbol *InvokeBegin,
1235 MCSymbol *InvokeEnd) {
David Majnemer8a1c45d2015-12-12 05:38:55 +00001236 assert(InvokeStateMap.count(II) &&
1237 "should get invoke with precomputed state");
1238 LabelToStateMap[InvokeBegin] = std::make_pair(InvokeStateMap[II], InvokeEnd);
Reid Klecknerc71d6272015-09-28 23:56:30 +00001239}
Chandler Carruthe0115342015-12-29 09:24:39 +00001240
1241WinEHFuncInfo::WinEHFuncInfo() {}