1 //===-- X86WinEHState - Insert EH state updates for win32 exceptions ------===//
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 // All functions using an MSVC EH personality use an explicitly updated state
11 // number stored in an exception registration stack object. The registration
12 // object is linked into a thread-local chain of registrations stored at fs:00.
13 // This pass adds the registration object and EH state updates.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "X86.h"
18 #include "llvm/ADT/PostOrderIterator.h"
19 #include "llvm/Analysis/CFG.h"
20 #include "llvm/Analysis/EHPersonalities.h"
21 #include "llvm/CodeGen/MachineModuleInfo.h"
22 #include "llvm/CodeGen/WinEHFuncInfo.h"
23 #include "llvm/IR/CallSite.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/Instructions.h"
26 #include "llvm/IR/IntrinsicInst.h"
27 #include "llvm/IR/IRBuilder.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/Pass.h"
30 #include "llvm/Support/Debug.h"
31 #include <deque>
32 
33 using namespace llvm;
34 
35 #define DEBUG_TYPE "winehstate"
36 
37 namespace llvm {
38 void initializeWinEHStatePassPass(PassRegistry &);
39 }
40 
41 namespace {
42 const int OverdefinedState = INT_MIN;
43 
44 class WinEHStatePass : public FunctionPass {
45 public:
46   static char ID; // Pass identification, replacement for typeid.
47 
48   WinEHStatePass() : FunctionPass(ID) {
49     initializeWinEHStatePassPass(*PassRegistry::getPassRegistry());
50   }
51 
52   bool runOnFunction(Function &Fn) override;
53 
54   bool doInitialization(Module &M) override;
55 
56   bool doFinalization(Module &M) override;
57 
58   void getAnalysisUsage(AnalysisUsage &AU) const override;
59 
60   const char *getPassName() const override {
61     return "Windows 32-bit x86 EH state insertion";
62   }
63 
64 private:
65   void emitExceptionRegistrationRecord(Function *F);
66 
67   void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
68   void unlinkExceptionRegistration(IRBuilder<> &Builder);
69   void addStateStores(Function &F, WinEHFuncInfo &FuncInfo);
70   void insertStateNumberStore(Instruction *IP, int State);
71 
72   Value *emitEHLSDA(IRBuilder<> &Builder, Function *F);
73 
74   Function *generateLSDAInEAXThunk(Function *ParentFunc);
75 
76   // Module-level type getters.
77   Type *getEHLinkRegistrationType();
78   Type *getSEHRegistrationType();
79   Type *getCXXEHRegistrationType();
80 
81   // Per-module data.
82   Module *TheModule = nullptr;
83   StructType *EHLinkRegistrationTy = nullptr;
84   StructType *CXXEHRegistrationTy = nullptr;
85   StructType *SEHRegistrationTy = nullptr;
86   Function *FrameRecover = nullptr;
87   Function *FrameAddress = nullptr;
88   Function *FrameEscape = nullptr;
89 
90   // Per-function state
91   EHPersonality Personality = EHPersonality::Unknown;
92   Function *PersonalityFn = nullptr;
93   bool UseStackGuard = false;
94   int ParentBaseState;
95 
96   /// The stack allocation containing all EH data, including the link in the
97   /// fs:00 chain and the current state.
98   AllocaInst *RegNode = nullptr;
99 
100   /// The index of the state field of RegNode.
101   int StateFieldIndex = ~0U;
102 
103   /// The linked list node subobject inside of RegNode.
104   Value *Link = nullptr;
105 };
106 }
107 
108 FunctionPass *llvm::createX86WinEHStatePass() { return new WinEHStatePass(); }
109 
110 char WinEHStatePass::ID = 0;
111 
112 INITIALIZE_PASS(WinEHStatePass, "x86-winehstate",
113                 "Insert stores for EH state numbers", false, false)
114 
115 bool WinEHStatePass::doInitialization(Module &M) {
116   TheModule = &M;
117   return false;
118 }
119 
120 bool WinEHStatePass::doFinalization(Module &M) {
121   assert(TheModule == &M);
122   TheModule = nullptr;
123   EHLinkRegistrationTy = nullptr;
124   CXXEHRegistrationTy = nullptr;
125   SEHRegistrationTy = nullptr;
126   FrameEscape = nullptr;
127   FrameRecover = nullptr;
128   FrameAddress = nullptr;
129   return false;
130 }
131 
132 void WinEHStatePass::getAnalysisUsage(AnalysisUsage &AU) const {
133   // This pass should only insert a stack allocation, memory accesses, and
134   // localrecovers.
135   AU.setPreservesCFG();
136 }
137 
138 bool WinEHStatePass::runOnFunction(Function &F) {
139   // Check the personality. Do nothing if this personality doesn't use funclets.
140   if (!F.hasPersonalityFn())
141     return false;
142   PersonalityFn =
143       dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
144   if (!PersonalityFn)
145     return false;
146   Personality = classifyEHPersonality(PersonalityFn);
147   if (!isFuncletEHPersonality(Personality))
148     return false;
149 
150   // Skip this function if there are no EH pads and we aren't using IR-level
151   // outlining.
152   bool HasPads = false;
153   for (BasicBlock &BB : F) {
154     if (BB.isEHPad()) {
155       HasPads = true;
156       break;
157     }
158   }
159   if (!HasPads)
160     return false;
161 
162   FrameEscape = Intrinsic::getDeclaration(TheModule, Intrinsic::localescape);
163   FrameRecover = Intrinsic::getDeclaration(TheModule, Intrinsic::localrecover);
164   FrameAddress = Intrinsic::getDeclaration(TheModule, Intrinsic::frameaddress);
165 
166   // Disable frame pointer elimination in this function.
167   // FIXME: Do the nested handlers need to keep the parent ebp in ebp, or can we
168   // use an arbitrary register?
169   F.addFnAttr("no-frame-pointer-elim", "true");
170 
171   emitExceptionRegistrationRecord(&F);
172 
173   // The state numbers calculated here in IR must agree with what we calculate
174   // later on for the MachineFunction. In particular, if an IR pass deletes an
175   // unreachable EH pad after this point before machine CFG construction, we
176   // will be in trouble. If this assumption is ever broken, we should turn the
177   // numbers into an immutable analysis pass.
178   WinEHFuncInfo FuncInfo;
179   addStateStores(F, FuncInfo);
180 
181   // Reset per-function state.
182   PersonalityFn = nullptr;
183   Personality = EHPersonality::Unknown;
184   UseStackGuard = false;
185   return true;
186 }
187 
188 /// Get the common EH registration subobject:
189 ///   typedef _EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE)(
190 ///       _EXCEPTION_RECORD *, void *, _CONTEXT *, void *);
191 ///   struct EHRegistrationNode {
192 ///     EHRegistrationNode *Next;
193 ///     PEXCEPTION_ROUTINE Handler;
194 ///   };
195 Type *WinEHStatePass::getEHLinkRegistrationType() {
196   if (EHLinkRegistrationTy)
197     return EHLinkRegistrationTy;
198   LLVMContext &Context = TheModule->getContext();
199   EHLinkRegistrationTy = StructType::create(Context, "EHRegistrationNode");
200   Type *FieldTys[] = {
201       EHLinkRegistrationTy->getPointerTo(0), // EHRegistrationNode *Next
202       Type::getInt8PtrTy(Context) // EXCEPTION_DISPOSITION (*Handler)(...)
203   };
204   EHLinkRegistrationTy->setBody(FieldTys, false);
205   return EHLinkRegistrationTy;
206 }
207 
208 /// The __CxxFrameHandler3 registration node:
209 ///   struct CXXExceptionRegistration {
210 ///     void *SavedESP;
211 ///     EHRegistrationNode SubRecord;
212 ///     int32_t TryLevel;
213 ///   };
214 Type *WinEHStatePass::getCXXEHRegistrationType() {
215   if (CXXEHRegistrationTy)
216     return CXXEHRegistrationTy;
217   LLVMContext &Context = TheModule->getContext();
218   Type *FieldTys[] = {
219       Type::getInt8PtrTy(Context), // void *SavedESP
220       getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
221       Type::getInt32Ty(Context)    // int32_t TryLevel
222   };
223   CXXEHRegistrationTy =
224       StructType::create(FieldTys, "CXXExceptionRegistration");
225   return CXXEHRegistrationTy;
226 }
227 
228 /// The _except_handler3/4 registration node:
229 ///   struct EH4ExceptionRegistration {
230 ///     void *SavedESP;
231 ///     _EXCEPTION_POINTERS *ExceptionPointers;
232 ///     EHRegistrationNode SubRecord;
233 ///     int32_t EncodedScopeTable;
234 ///     int32_t TryLevel;
235 ///   };
236 Type *WinEHStatePass::getSEHRegistrationType() {
237   if (SEHRegistrationTy)
238     return SEHRegistrationTy;
239   LLVMContext &Context = TheModule->getContext();
240   Type *FieldTys[] = {
241       Type::getInt8PtrTy(Context), // void *SavedESP
242       Type::getInt8PtrTy(Context), // void *ExceptionPointers
243       getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
244       Type::getInt32Ty(Context),   // int32_t EncodedScopeTable
245       Type::getInt32Ty(Context)    // int32_t TryLevel
246   };
247   SEHRegistrationTy = StructType::create(FieldTys, "SEHExceptionRegistration");
248   return SEHRegistrationTy;
249 }
250 
251 // Emit an exception registration record. These are stack allocations with the
252 // common subobject of two pointers: the previous registration record (the old
253 // fs:00) and the personality function for the current frame. The data before
254 // and after that is personality function specific.
255 void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
256   assert(Personality == EHPersonality::MSVC_CXX ||
257          Personality == EHPersonality::MSVC_X86SEH);
258 
259   // Struct type of RegNode. Used for GEPing.
260   Type *RegNodeTy;
261 
262   IRBuilder<> Builder(&F->getEntryBlock(), F->getEntryBlock().begin());
263   Type *Int8PtrType = Builder.getInt8PtrTy();
264   if (Personality == EHPersonality::MSVC_CXX) {
265     RegNodeTy = getCXXEHRegistrationType();
266     RegNode = Builder.CreateAlloca(RegNodeTy);
267     // SavedESP = llvm.stacksave()
268     Value *SP = Builder.CreateCall(
269         Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
270     Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
271     // TryLevel = -1
272     StateFieldIndex = 2;
273     ParentBaseState = -1;
274     insertStateNumberStore(&*Builder.GetInsertPoint(), ParentBaseState);
275     // Handler = __ehhandler$F
276     Function *Trampoline = generateLSDAInEAXThunk(F);
277     Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 1);
278     linkExceptionRegistration(Builder, Trampoline);
279   } else if (Personality == EHPersonality::MSVC_X86SEH) {
280     // If _except_handler4 is in use, some additional guard checks and prologue
281     // stuff is required.
282     RegNodeTy = getSEHRegistrationType();
283     RegNode = Builder.CreateAlloca(RegNodeTy);
284     // SavedESP = llvm.stacksave()
285     Value *SP = Builder.CreateCall(
286         Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
287     Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
288     // TryLevel = -2 / -1
289     StateFieldIndex = 4;
290     StringRef PersonalityName = PersonalityFn->getName();
291     UseStackGuard = (PersonalityName == "_except_handler4");
292     ParentBaseState = UseStackGuard ? -2 : -1;
293     insertStateNumberStore(&*Builder.GetInsertPoint(), ParentBaseState);
294     // ScopeTable = llvm.x86.seh.lsda(F)
295     Value *FI8 = Builder.CreateBitCast(F, Int8PtrType);
296     Value *LSDA = Builder.CreateCall(
297         Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_lsda), FI8);
298     Type *Int32Ty = Type::getInt32Ty(TheModule->getContext());
299     LSDA = Builder.CreatePtrToInt(LSDA, Int32Ty);
300     // If using _except_handler4, xor the address of the table with
301     // __security_cookie.
302     if (UseStackGuard) {
303       Value *Cookie =
304           TheModule->getOrInsertGlobal("__security_cookie", Int32Ty);
305       Value *Val = Builder.CreateLoad(Int32Ty, Cookie);
306       LSDA = Builder.CreateXor(LSDA, Val);
307     }
308     Builder.CreateStore(LSDA, Builder.CreateStructGEP(RegNodeTy, RegNode, 3));
309     Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 2);
310     linkExceptionRegistration(Builder, PersonalityFn);
311   } else {
312     llvm_unreachable("unexpected personality function");
313   }
314 
315   // Insert an unlink before all returns.
316   for (BasicBlock &BB : *F) {
317     TerminatorInst *T = BB.getTerminator();
318     if (!isa<ReturnInst>(T))
319       continue;
320     Builder.SetInsertPoint(T);
321     unlinkExceptionRegistration(Builder);
322   }
323 }
324 
325 Value *WinEHStatePass::emitEHLSDA(IRBuilder<> &Builder, Function *F) {
326   Value *FI8 = Builder.CreateBitCast(F, Type::getInt8PtrTy(F->getContext()));
327   return Builder.CreateCall(
328       Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_lsda), FI8);
329 }
330 
331 /// Generate a thunk that puts the LSDA of ParentFunc in EAX and then calls
332 /// PersonalityFn, forwarding the parameters passed to PEXCEPTION_ROUTINE:
333 ///   typedef _EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE)(
334 ///       _EXCEPTION_RECORD *, void *, _CONTEXT *, void *);
335 /// We essentially want this code:
336 ///   movl $lsda, %eax
337 ///   jmpl ___CxxFrameHandler3
338 Function *WinEHStatePass::generateLSDAInEAXThunk(Function *ParentFunc) {
339   LLVMContext &Context = ParentFunc->getContext();
340   Type *Int32Ty = Type::getInt32Ty(Context);
341   Type *Int8PtrType = Type::getInt8PtrTy(Context);
342   Type *ArgTys[5] = {Int8PtrType, Int8PtrType, Int8PtrType, Int8PtrType,
343                      Int8PtrType};
344   FunctionType *TrampolineTy =
345       FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 4),
346                         /*isVarArg=*/false);
347   FunctionType *TargetFuncTy =
348       FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 5),
349                         /*isVarArg=*/false);
350   Function *Trampoline =
351       Function::Create(TrampolineTy, GlobalValue::InternalLinkage,
352                        Twine("__ehhandler$") + GlobalValue::getRealLinkageName(
353                                                    ParentFunc->getName()),
354                        TheModule);
355   BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", Trampoline);
356   IRBuilder<> Builder(EntryBB);
357   Value *LSDA = emitEHLSDA(Builder, ParentFunc);
358   Value *CastPersonality =
359       Builder.CreateBitCast(PersonalityFn, TargetFuncTy->getPointerTo());
360   auto AI = Trampoline->arg_begin();
361   Value *Args[5] = {LSDA, &*AI++, &*AI++, &*AI++, &*AI++};
362   CallInst *Call = Builder.CreateCall(CastPersonality, Args);
363   // Can't use musttail due to prototype mismatch, but we can use tail.
364   Call->setTailCall(true);
365   // Set inreg so we pass it in EAX.
366   Call->addAttribute(1, Attribute::InReg);
367   Builder.CreateRet(Call);
368   return Trampoline;
369 }
370 
371 void WinEHStatePass::linkExceptionRegistration(IRBuilder<> &Builder,
372                                                Function *Handler) {
373   // Emit the .safeseh directive for this function.
374   Handler->addFnAttr("safeseh");
375 
376   Type *LinkTy = getEHLinkRegistrationType();
377   // Handler = Handler
378   Value *HandlerI8 = Builder.CreateBitCast(Handler, Builder.getInt8PtrTy());
379   Builder.CreateStore(HandlerI8, Builder.CreateStructGEP(LinkTy, Link, 1));
380   // Next = [fs:00]
381   Constant *FSZero =
382       Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
383   Value *Next = Builder.CreateLoad(FSZero);
384   Builder.CreateStore(Next, Builder.CreateStructGEP(LinkTy, Link, 0));
385   // [fs:00] = Link
386   Builder.CreateStore(Link, FSZero);
387 }
388 
389 void WinEHStatePass::unlinkExceptionRegistration(IRBuilder<> &Builder) {
390   // Clone Link into the current BB for better address mode folding.
391   if (auto *GEP = dyn_cast<GetElementPtrInst>(Link)) {
392     GEP = cast<GetElementPtrInst>(GEP->clone());
393     Builder.Insert(GEP);
394     Link = GEP;
395   }
396   Type *LinkTy = getEHLinkRegistrationType();
397   // [fs:00] = Link->Next
398   Value *Next =
399       Builder.CreateLoad(Builder.CreateStructGEP(LinkTy, Link, 0));
400   Constant *FSZero =
401       Constant::getNullValue(LinkTy->getPointerTo()->getPointerTo(257));
402   Builder.CreateStore(Next, FSZero);
403 }
404 
405 // Figure out what state we should assign calls in this block.
406 static int getBaseStateForBB(DenseMap<BasicBlock *, ColorVector> &BlockColors,
407                              WinEHFuncInfo &FuncInfo, BasicBlock *BB) {
408   int BaseState = -1;
409   auto &BBColors = BlockColors[BB];
410 
411   assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
412   BasicBlock *FuncletEntryBB = BBColors.front();
413   if (auto *FuncletPad =
414           dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI())) {
415     auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad);
416     if (BaseStateI != FuncInfo.FuncletBaseStateMap.end())
417       BaseState = BaseStateI->second;
418   }
419 
420   return BaseState;
421 }
422 
423 // Calculate the state a call-site is in.
424 static int getStateForCallSite(DenseMap<BasicBlock *, ColorVector> &BlockColors,
425                                WinEHFuncInfo &FuncInfo, CallSite CS) {
426   if (auto *II = dyn_cast<InvokeInst>(CS.getInstruction())) {
427     // Look up the state number of the EH pad this unwinds to.
428     assert(FuncInfo.InvokeStateMap.count(II) && "invoke has no state!");
429     return FuncInfo.InvokeStateMap[II];
430   }
431   // Possibly throwing call instructions have no actions to take after
432   // an unwind. Ensure they are in the -1 state.
433   return getBaseStateForBB(BlockColors, FuncInfo, CS.getParent());
434 }
435 
436 // Calculate the intersection of all the FinalStates for a BasicBlock's
437 // predecessors.
438 static int getPredState(DenseMap<BasicBlock *, int> &FinalStates, Function &F,
439                         int ParentBaseState, BasicBlock *BB) {
440   // The entry block has no predecessors but we know that the prologue always
441   // sets us up with a fixed state.
442   if (&F.getEntryBlock() == BB)
443     return ParentBaseState;
444 
445   // This is an EH Pad, conservatively report this basic block as overdefined.
446   if (BB->isEHPad())
447     return OverdefinedState;
448 
449   int CommonState = OverdefinedState;
450   for (BasicBlock *PredBB : predecessors(BB)) {
451     // We didn't manage to get a state for one of these predecessors,
452     // conservatively report this basic block as overdefined.
453     auto PredEndState = FinalStates.find(PredBB);
454     if (PredEndState == FinalStates.end())
455       return OverdefinedState;
456 
457     // This code is reachable via exceptional control flow,
458     // conservatively report this basic block as overdefined.
459     if (isa<CatchReturnInst>(PredBB->getTerminator()))
460       return OverdefinedState;
461 
462     int PredState = PredEndState->second;
463     assert(PredState != OverdefinedState &&
464            "overdefined BBs shouldn't be in FinalStates");
465     if (CommonState == OverdefinedState)
466       CommonState = PredState;
467 
468     // At least two predecessors have different FinalStates,
469     // conservatively report this basic block as overdefined.
470     if (CommonState != PredState)
471       return OverdefinedState;
472   }
473 
474   return CommonState;
475 }
476 
477 // Calculate the intersection of all the InitialStates for a BasicBlock's
478 // successors.
479 static int getSuccState(DenseMap<BasicBlock *, int> &InitialStates, Function &F,
480                         int ParentBaseState, BasicBlock *BB) {
481   // This block rejoins normal control flow,
482   // conservatively report this basic block as overdefined.
483   if (isa<CatchReturnInst>(BB->getTerminator()))
484     return OverdefinedState;
485 
486   int CommonState = OverdefinedState;
487   for (BasicBlock *SuccBB : successors(BB)) {
488     // We didn't manage to get a state for one of these predecessors,
489     // conservatively report this basic block as overdefined.
490     auto SuccStartState = InitialStates.find(SuccBB);
491     if (SuccStartState == InitialStates.end())
492       return OverdefinedState;
493 
494     // This is an EH Pad, conservatively report this basic block as overdefined.
495     if (SuccBB->isEHPad())
496       return OverdefinedState;
497 
498     int SuccState = SuccStartState->second;
499     assert(SuccState != OverdefinedState &&
500            "overdefined BBs shouldn't be in FinalStates");
501     if (CommonState == OverdefinedState)
502       CommonState = SuccState;
503 
504     // At least two successors have different InitialStates,
505     // conservatively report this basic block as overdefined.
506     if (CommonState != SuccState)
507       return OverdefinedState;
508   }
509 
510   return CommonState;
511 }
512 
513 static bool isStateStoreNeeded(EHPersonality Personality, CallSite CS) {
514   if (!CS)
515     return false;
516 
517   if (isAsynchronousEHPersonality(Personality))
518     return !CS.doesNotAccessMemory();
519 
520   return !CS.doesNotThrow();
521 }
522 
523 void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
524   // Mark the registration node. The backend needs to know which alloca it is so
525   // that it can recover the original frame pointer.
526   IRBuilder<> Builder(RegNode->getParent(), std::next(RegNode->getIterator()));
527   Value *RegNodeI8 = Builder.CreateBitCast(RegNode, Builder.getInt8PtrTy());
528   Builder.CreateCall(
529       Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehregnode),
530       {RegNodeI8});
531 
532   // Calculate state numbers.
533   if (isAsynchronousEHPersonality(Personality))
534     calculateSEHStateNumbers(&F, FuncInfo);
535   else
536     calculateWinCXXEHStateNumbers(&F, FuncInfo);
537 
538   // Iterate all the instructions and emit state number stores.
539   DenseMap<BasicBlock *, ColorVector> BlockColors = colorEHFunclets(F);
540   ReversePostOrderTraversal<Function *> RPOT(&F);
541 
542   // InitialStates yields the state of the first call-site for a BasicBlock.
543   DenseMap<BasicBlock *, int> InitialStates;
544   // FinalStates yields the state of the last call-site for a BasicBlock.
545   DenseMap<BasicBlock *, int> FinalStates;
546   // Worklist used to revisit BasicBlocks with indeterminate
547   // Initial/Final-States.
548   std::deque<BasicBlock *> Worklist;
549   // Fill in InitialStates and FinalStates for BasicBlocks with call-sites.
550   for (BasicBlock *BB : RPOT) {
551     int InitialState = OverdefinedState;
552     int FinalState;
553     if (&F.getEntryBlock() == BB)
554       InitialState = FinalState = ParentBaseState;
555     for (Instruction &I : *BB) {
556       CallSite CS(&I);
557       if (!isStateStoreNeeded(Personality, CS))
558         continue;
559 
560       int State = getStateForCallSite(BlockColors, FuncInfo, CS);
561       if (InitialState == OverdefinedState)
562         InitialState = State;
563       FinalState = State;
564     }
565     // No call-sites in this basic block? That's OK, we will come back to these
566     // in a later pass.
567     if (InitialState == OverdefinedState) {
568       Worklist.push_back(BB);
569       continue;
570     }
571     DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
572                  << " InitialState=" << InitialState << '\n');
573     DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
574                  << " FinalState=" << FinalState << '\n');
575     InitialStates.insert({BB, InitialState});
576     FinalStates.insert({BB, FinalState});
577   }
578 
579   // Try to fill-in InitialStates and FinalStates which have no call-sites.
580   while (!Worklist.empty()) {
581     BasicBlock *BB = Worklist.front();
582     Worklist.pop_front();
583     // This BasicBlock has already been figured out, nothing more we can do.
584     if (InitialStates.count(BB) != 0)
585       continue;
586 
587     int PredState = getPredState(FinalStates, F, ParentBaseState, BB);
588     if (PredState == OverdefinedState)
589       continue;
590 
591     // We successfully inferred this BasicBlock's state via it's predecessors;
592     // enqueue it's successors to see if we can infer their states.
593     InitialStates.insert({BB, PredState});
594     FinalStates.insert({BB, PredState});
595     for (BasicBlock *SuccBB : successors(BB))
596       Worklist.push_back(SuccBB);
597   }
598 
599   // Try to hoist stores from successors.
600   for (BasicBlock *BB : RPOT) {
601     int SuccState = getSuccState(InitialStates, F, ParentBaseState, BB);
602     if (SuccState == OverdefinedState)
603       continue;
604 
605     // Update our FinalState to reflect the common InitialState of our
606     // successors.
607     FinalStates.insert({BB, SuccState});
608   }
609 
610   // Finally, insert state stores before call-sites which transition us to a new
611   // state.
612   for (BasicBlock *BB : RPOT) {
613     auto &BBColors = BlockColors[BB];
614     BasicBlock *FuncletEntryBB = BBColors.front();
615     if (isa<CleanupPadInst>(FuncletEntryBB->getFirstNonPHI()))
616       continue;
617 
618     int PrevState = getPredState(FinalStates, F, ParentBaseState, BB);
619     DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
620                  << " PrevState=" << PrevState << '\n');
621 
622     for (Instruction &I : *BB) {
623       CallSite CS(&I);
624       if (!isStateStoreNeeded(Personality, CS))
625         continue;
626 
627       int State = getStateForCallSite(BlockColors, FuncInfo, CS);
628       if (State != PrevState)
629         insertStateNumberStore(&I, State);
630       PrevState = State;
631     }
632 
633     // We might have hoisted a state store into this block, emit it now.
634     auto EndState = FinalStates.find(BB);
635     if (EndState != FinalStates.end())
636       if (EndState->second != PrevState)
637         insertStateNumberStore(BB->getTerminator(), EndState->second);
638   }
639 }
640 
641 void WinEHStatePass::insertStateNumberStore(Instruction *IP, int State) {
642   IRBuilder<> Builder(IP);
643   Value *StateField =
644       Builder.CreateStructGEP(nullptr, RegNode, StateFieldIndex);
645   Builder.CreateStore(Builder.getInt32(State), StateField);
646 }
647