LLVM  14.0.0git
X86WinEHState.cpp
Go to the documentation of this file.
1 //===-- X86WinEHState - Insert EH state updates for win32 exceptions ------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // All functions using an MSVC EH personality use an explicitly updated state
10 // number stored in an exception registration stack object. The registration
11 // object is linked into a thread-local chain of registrations stored at fs:00.
12 // This pass adds the registration object and EH state updates.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "X86.h"
18 #include "llvm/Analysis/CFG.h"
22 #include "llvm/IR/CFG.h"
23 #include "llvm/IR/Function.h"
24 #include "llvm/IR/IRBuilder.h"
25 #include "llvm/IR/Instructions.h"
26 #include "llvm/IR/Intrinsics.h"
27 #include "llvm/IR/IntrinsicsX86.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 {
38 const int OverdefinedState = INT_MIN;
39 
40 class WinEHStatePass : public FunctionPass {
41 public:
42  static char ID; // Pass identification, replacement for typeid.
43 
44  WinEHStatePass() : FunctionPass(ID) { }
45 
46  bool runOnFunction(Function &Fn) override;
47 
48  bool doInitialization(Module &M) override;
49 
50  bool doFinalization(Module &M) override;
51 
52  void getAnalysisUsage(AnalysisUsage &AU) const override;
53 
54  StringRef getPassName() const override {
55  return "Windows 32-bit x86 EH state insertion";
56  }
57 
58 private:
59  void emitExceptionRegistrationRecord(Function *F);
60 
61  void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
62  void unlinkExceptionRegistration(IRBuilder<> &Builder);
63  void addStateStores(Function &F, WinEHFuncInfo &FuncInfo);
64  void insertStateNumberStore(Instruction *IP, int State);
65 
66  Value *emitEHLSDA(IRBuilder<> &Builder, Function *F);
67 
68  Function *generateLSDAInEAXThunk(Function *ParentFunc);
69 
70  bool isStateStoreNeeded(EHPersonality Personality, CallBase &Call);
71  void rewriteSetJmpCall(IRBuilder<> &Builder, Function &F, CallBase &Call,
72  Value *State);
73  int getBaseStateForBB(DenseMap<BasicBlock *, ColorVector> &BlockColors,
74  WinEHFuncInfo &FuncInfo, BasicBlock *BB);
75  int getStateForCall(DenseMap<BasicBlock *, ColorVector> &BlockColors,
76  WinEHFuncInfo &FuncInfo, CallBase &Call);
77 
78  // Module-level type getters.
79  Type *getEHLinkRegistrationType();
80  Type *getSEHRegistrationType();
81  Type *getCXXEHRegistrationType();
82 
83  // Per-module data.
84  Module *TheModule = nullptr;
85  StructType *EHLinkRegistrationTy = nullptr;
86  StructType *CXXEHRegistrationTy = nullptr;
87  StructType *SEHRegistrationTy = nullptr;
88  FunctionCallee SetJmp3 = nullptr;
89  FunctionCallee CxxLongjmpUnwind = nullptr;
90 
91  // Per-function state
93  Function *PersonalityFn = nullptr;
94  bool UseStackGuard = false;
95  int ParentBaseState = 0;
96  FunctionCallee SehLongjmpUnwind = nullptr;
97  Constant *Cookie = nullptr;
98 
99  /// The stack allocation containing all EH data, including the link in the
100  /// fs:00 chain and the current state.
101  AllocaInst *RegNode = nullptr;
102 
103  // The allocation containing the EH security guard.
104  AllocaInst *EHGuardNode = nullptr;
105 
106  /// The index of the state field of RegNode.
107  int StateFieldIndex = ~0U;
108 
109  /// The linked list node subobject inside of RegNode.
110  Value *Link = nullptr;
111 };
112 } // namespace
113 
114 FunctionPass *llvm::createX86WinEHStatePass() { return new WinEHStatePass(); }
115 
116 char WinEHStatePass::ID = 0;
117 
118 INITIALIZE_PASS(WinEHStatePass, "x86-winehstate",
119  "Insert stores for EH state numbers", false, false)
120 
121 bool WinEHStatePass::doInitialization(Module &M) {
122  TheModule = &M;
123  return false;
124 }
125 
126 bool WinEHStatePass::doFinalization(Module &M) {
127  assert(TheModule == &M);
128  TheModule = nullptr;
129  EHLinkRegistrationTy = nullptr;
130  CXXEHRegistrationTy = nullptr;
131  SEHRegistrationTy = nullptr;
132  SetJmp3 = nullptr;
133  CxxLongjmpUnwind = nullptr;
134  SehLongjmpUnwind = nullptr;
135  Cookie = nullptr;
136  return false;
137 }
138 
139 void WinEHStatePass::getAnalysisUsage(AnalysisUsage &AU) const {
140  // This pass should only insert a stack allocation, memory accesses, and
141  // localrecovers.
142  AU.setPreservesCFG();
143 }
144 
146  // Don't insert state stores or exception handler thunks for
147  // available_externally functions. The handler needs to reference the LSDA,
148  // which will not be emitted in this case.
149  if (F.hasAvailableExternallyLinkage())
150  return false;
151 
152  // Check the personality. Do nothing if this personality doesn't use funclets.
153  if (!F.hasPersonalityFn())
154  return false;
155  PersonalityFn =
156  dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
157  if (!PersonalityFn)
158  return false;
159  Personality = classifyEHPersonality(PersonalityFn);
160  if (!isFuncletEHPersonality(Personality))
161  return false;
162 
163  // Skip this function if there are no EH pads and we aren't using IR-level
164  // outlining.
165  bool HasPads = false;
166  for (BasicBlock &BB : F) {
167  if (BB.isEHPad()) {
168  HasPads = true;
169  break;
170  }
171  }
172  if (!HasPads)
173  return false;
174 
175  Type *Int8PtrType = Type::getInt8PtrTy(TheModule->getContext());
176  SetJmp3 = TheModule->getOrInsertFunction(
177  "_setjmp3", FunctionType::get(
178  Type::getInt32Ty(TheModule->getContext()),
179  {Int8PtrType, Type::getInt32Ty(TheModule->getContext())},
180  /*isVarArg=*/true));
181 
182  emitExceptionRegistrationRecord(&F);
183 
184  // The state numbers calculated here in IR must agree with what we calculate
185  // later on for the MachineFunction. In particular, if an IR pass deletes an
186  // unreachable EH pad after this point before machine CFG construction, we
187  // will be in trouble. If this assumption is ever broken, we should turn the
188  // numbers into an immutable analysis pass.
189  WinEHFuncInfo FuncInfo;
190  addStateStores(F, FuncInfo);
191 
192  // Reset per-function state.
193  PersonalityFn = nullptr;
194  Personality = EHPersonality::Unknown;
195  UseStackGuard = false;
196  RegNode = nullptr;
197  EHGuardNode = nullptr;
198 
199  return true;
200 }
201 
202 /// Get the common EH registration subobject:
203 /// typedef _EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE)(
204 /// _EXCEPTION_RECORD *, void *, _CONTEXT *, void *);
205 /// struct EHRegistrationNode {
206 /// EHRegistrationNode *Next;
207 /// PEXCEPTION_ROUTINE Handler;
208 /// };
209 Type *WinEHStatePass::getEHLinkRegistrationType() {
210  if (EHLinkRegistrationTy)
211  return EHLinkRegistrationTy;
212  LLVMContext &Context = TheModule->getContext();
213  EHLinkRegistrationTy = StructType::create(Context, "EHRegistrationNode");
214  Type *FieldTys[] = {
215  EHLinkRegistrationTy->getPointerTo(0), // EHRegistrationNode *Next
216  Type::getInt8PtrTy(Context) // EXCEPTION_DISPOSITION (*Handler)(...)
217  };
218  EHLinkRegistrationTy->setBody(FieldTys, false);
219  return EHLinkRegistrationTy;
220 }
221 
222 /// The __CxxFrameHandler3 registration node:
223 /// struct CXXExceptionRegistration {
224 /// void *SavedESP;
225 /// EHRegistrationNode SubRecord;
226 /// int32_t TryLevel;
227 /// };
228 Type *WinEHStatePass::getCXXEHRegistrationType() {
229  if (CXXEHRegistrationTy)
230  return CXXEHRegistrationTy;
231  LLVMContext &Context = TheModule->getContext();
232  Type *FieldTys[] = {
233  Type::getInt8PtrTy(Context), // void *SavedESP
234  getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
235  Type::getInt32Ty(Context) // int32_t TryLevel
236  };
237  CXXEHRegistrationTy =
238  StructType::create(FieldTys, "CXXExceptionRegistration");
239  return CXXEHRegistrationTy;
240 }
241 
242 /// The _except_handler3/4 registration node:
243 /// struct EH4ExceptionRegistration {
244 /// void *SavedESP;
245 /// _EXCEPTION_POINTERS *ExceptionPointers;
246 /// EHRegistrationNode SubRecord;
247 /// int32_t EncodedScopeTable;
248 /// int32_t TryLevel;
249 /// };
250 Type *WinEHStatePass::getSEHRegistrationType() {
251  if (SEHRegistrationTy)
252  return SEHRegistrationTy;
253  LLVMContext &Context = TheModule->getContext();
254  Type *FieldTys[] = {
255  Type::getInt8PtrTy(Context), // void *SavedESP
256  Type::getInt8PtrTy(Context), // void *ExceptionPointers
257  getEHLinkRegistrationType(), // EHRegistrationNode SubRecord
258  Type::getInt32Ty(Context), // int32_t EncodedScopeTable
259  Type::getInt32Ty(Context) // int32_t TryLevel
260  };
261  SEHRegistrationTy = StructType::create(FieldTys, "SEHExceptionRegistration");
262  return SEHRegistrationTy;
263 }
264 
265 // Emit an exception registration record. These are stack allocations with the
266 // common subobject of two pointers: the previous registration record (the old
267 // fs:00) and the personality function for the current frame. The data before
268 // and after that is personality function specific.
269 void WinEHStatePass::emitExceptionRegistrationRecord(Function *F) {
270  assert(Personality == EHPersonality::MSVC_CXX ||
271  Personality == EHPersonality::MSVC_X86SEH);
272 
273  // Struct type of RegNode. Used for GEPing.
274  Type *RegNodeTy;
275 
276  IRBuilder<> Builder(&F->getEntryBlock(), F->getEntryBlock().begin());
277  Type *Int8PtrType = Builder.getInt8PtrTy();
278  Type *Int32Ty = Builder.getInt32Ty();
279  Type *VoidTy = Builder.getVoidTy();
280 
281  if (Personality == EHPersonality::MSVC_CXX) {
282  RegNodeTy = getCXXEHRegistrationType();
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 = -1
289  StateFieldIndex = 2;
290  ParentBaseState = -1;
291  insertStateNumberStore(&*Builder.GetInsertPoint(), ParentBaseState);
292  // Handler = __ehhandler$F
293  Function *Trampoline = generateLSDAInEAXThunk(F);
294  Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 1);
295  linkExceptionRegistration(Builder, Trampoline);
296 
297  CxxLongjmpUnwind = TheModule->getOrInsertFunction(
298  "__CxxLongjmpUnwind",
299  FunctionType::get(VoidTy, Int8PtrType, /*isVarArg=*/false));
300  cast<Function>(CxxLongjmpUnwind.getCallee()->stripPointerCasts())
301  ->setCallingConv(CallingConv::X86_StdCall);
302  } else if (Personality == EHPersonality::MSVC_X86SEH) {
303  // If _except_handler4 is in use, some additional guard checks and prologue
304  // stuff is required.
305  StringRef PersonalityName = PersonalityFn->getName();
306  UseStackGuard = (PersonalityName == "_except_handler4");
307 
308  // Allocate local structures.
309  RegNodeTy = getSEHRegistrationType();
310  RegNode = Builder.CreateAlloca(RegNodeTy);
311  if (UseStackGuard)
312  EHGuardNode = Builder.CreateAlloca(Int32Ty);
313 
314  // SavedESP = llvm.stacksave()
315  Value *SP = Builder.CreateCall(
316  Intrinsic::getDeclaration(TheModule, Intrinsic::stacksave), {});
317  Builder.CreateStore(SP, Builder.CreateStructGEP(RegNodeTy, RegNode, 0));
318  // TryLevel = -2 / -1
319  StateFieldIndex = 4;
320  ParentBaseState = UseStackGuard ? -2 : -1;
321  insertStateNumberStore(&*Builder.GetInsertPoint(), ParentBaseState);
322  // ScopeTable = llvm.x86.seh.lsda(F)
323  Value *LSDA = emitEHLSDA(Builder, F);
324  LSDA = Builder.CreatePtrToInt(LSDA, Int32Ty);
325  // If using _except_handler4, xor the address of the table with
326  // __security_cookie.
327  if (UseStackGuard) {
328  Cookie = TheModule->getOrInsertGlobal("__security_cookie", Int32Ty);
329  Value *Val = Builder.CreateLoad(Int32Ty, Cookie, "cookie");
330  LSDA = Builder.CreateXor(LSDA, Val);
331  }
332  Builder.CreateStore(LSDA, Builder.CreateStructGEP(RegNodeTy, RegNode, 3));
333 
334  // If using _except_handler4, the EHGuard contains: FramePtr xor Cookie.
335  if (UseStackGuard) {
336  Value *Val = Builder.CreateLoad(Int32Ty, Cookie);
337  Value *FrameAddr = Builder.CreateCall(
339  TheModule, Intrinsic::frameaddress,
340  Builder.getInt8PtrTy(
341  TheModule->getDataLayout().getAllocaAddrSpace())),
342  Builder.getInt32(0), "frameaddr");
343  Value *FrameAddrI32 = Builder.CreatePtrToInt(FrameAddr, Int32Ty);
344  FrameAddrI32 = Builder.CreateXor(FrameAddrI32, Val);
345  Builder.CreateStore(FrameAddrI32, EHGuardNode);
346  }
347 
348  // Register the exception handler.
349  Link = Builder.CreateStructGEP(RegNodeTy, RegNode, 2);
350  linkExceptionRegistration(Builder, PersonalityFn);
351 
352  SehLongjmpUnwind = TheModule->getOrInsertFunction(
353  UseStackGuard ? "_seh_longjmp_unwind4" : "_seh_longjmp_unwind",
354  FunctionType::get(Type::getVoidTy(TheModule->getContext()), Int8PtrType,
355  /*isVarArg=*/false));
356  cast<Function>(SehLongjmpUnwind.getCallee()->stripPointerCasts())
357  ->setCallingConv(CallingConv::X86_StdCall);
358  } else {
359  llvm_unreachable("unexpected personality function");
360  }
361 
362  // Insert an unlink before all returns.
363  for (BasicBlock &BB : *F) {
364  Instruction *T = BB.getTerminator();
365  if (!isa<ReturnInst>(T))
366  continue;
367  Builder.SetInsertPoint(T);
368  unlinkExceptionRegistration(Builder);
369  }
370 }
371 
372 Value *WinEHStatePass::emitEHLSDA(IRBuilder<> &Builder, Function *F) {
373  Value *FI8 = Builder.CreateBitCast(F, Type::getInt8PtrTy(F->getContext()));
374  return Builder.CreateCall(
375  Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_lsda), FI8);
376 }
377 
378 /// Generate a thunk that puts the LSDA of ParentFunc in EAX and then calls
379 /// PersonalityFn, forwarding the parameters passed to PEXCEPTION_ROUTINE:
380 /// typedef _EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE)(
381 /// _EXCEPTION_RECORD *, void *, _CONTEXT *, void *);
382 /// We essentially want this code:
383 /// movl $lsda, %eax
384 /// jmpl ___CxxFrameHandler3
385 Function *WinEHStatePass::generateLSDAInEAXThunk(Function *ParentFunc) {
386  LLVMContext &Context = ParentFunc->getContext();
388  Type *Int8PtrType = Type::getInt8PtrTy(Context);
389  Type *ArgTys[5] = {Int8PtrType, Int8PtrType, Int8PtrType, Int8PtrType,
390  Int8PtrType};
391  FunctionType *TrampolineTy =
392  FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 4),
393  /*isVarArg=*/false);
394  FunctionType *TargetFuncTy =
395  FunctionType::get(Int32Ty, makeArrayRef(&ArgTys[0], 5),
396  /*isVarArg=*/false);
397  Function *Trampoline =
399  Twine("__ehhandler$") + GlobalValue::dropLLVMManglingEscape(
400  ParentFunc->getName()),
401  TheModule);
402  if (auto *C = ParentFunc->getComdat())
403  Trampoline->setComdat(C);
404  BasicBlock *EntryBB = BasicBlock::Create(Context, "entry", Trampoline);
405  IRBuilder<> Builder(EntryBB);
406  Value *LSDA = emitEHLSDA(Builder, ParentFunc);
407  Value *CastPersonality =
408  Builder.CreateBitCast(PersonalityFn, TargetFuncTy->getPointerTo());
409  auto AI = Trampoline->arg_begin();
410  Value *Args[5] = {LSDA, &*AI++, &*AI++, &*AI++, &*AI++};
411  CallInst *Call = Builder.CreateCall(TargetFuncTy, CastPersonality, Args);
412  // Can't use musttail due to prototype mismatch, but we can use tail.
413  Call->setTailCall(true);
414  // Set inreg so we pass it in EAX.
415  Call->addParamAttr(0, Attribute::InReg);
416  Builder.CreateRet(Call);
417  return Trampoline;
418 }
419 
420 void WinEHStatePass::linkExceptionRegistration(IRBuilder<> &Builder,
421  Function *Handler) {
422  // Emit the .safeseh directive for this function.
423  Handler->addFnAttr("safeseh");
424 
425  Type *LinkTy = getEHLinkRegistrationType();
426  // Handler = Handler
427  Value *HandlerI8 = Builder.CreateBitCast(Handler, Builder.getInt8PtrTy());
428  Builder.CreateStore(HandlerI8, Builder.CreateStructGEP(LinkTy, Link, 1));
429  // Next = [fs:00]
430  Constant *FSZero =
432  Value *Next = Builder.CreateLoad(LinkTy->getPointerTo(), FSZero);
433  Builder.CreateStore(Next, Builder.CreateStructGEP(LinkTy, Link, 0));
434  // [fs:00] = Link
435  Builder.CreateStore(Link, FSZero);
436 }
437 
438 void WinEHStatePass::unlinkExceptionRegistration(IRBuilder<> &Builder) {
439  // Clone Link into the current BB for better address mode folding.
440  if (auto *GEP = dyn_cast<GetElementPtrInst>(Link)) {
441  GEP = cast<GetElementPtrInst>(GEP->clone());
442  Builder.Insert(GEP);
443  Link = GEP;
444  }
445  Type *LinkTy = getEHLinkRegistrationType();
446  // [fs:00] = Link->Next
447  Value *Next = Builder.CreateLoad(LinkTy->getPointerTo(),
448  Builder.CreateStructGEP(LinkTy, Link, 0));
449  Constant *FSZero =
451  Builder.CreateStore(Next, FSZero);
452 }
453 
454 // Calls to setjmp(p) are lowered to _setjmp3(p, 0) by the frontend.
455 // The idea behind _setjmp3 is that it takes an optional number of personality
456 // specific parameters to indicate how to restore the personality-specific frame
457 // state when longjmp is initiated. Typically, the current TryLevel is saved.
458 void WinEHStatePass::rewriteSetJmpCall(IRBuilder<> &Builder, Function &F,
459  CallBase &Call, Value *State) {
460  // Don't rewrite calls with a weird number of arguments.
461  if (Call.arg_size() != 2)
462  return;
463 
465  Call.getOperandBundlesAsDefs(OpBundles);
466 
467  SmallVector<Value *, 3> OptionalArgs;
468  if (Personality == EHPersonality::MSVC_CXX) {
469  OptionalArgs.push_back(CxxLongjmpUnwind.getCallee());
470  OptionalArgs.push_back(State);
471  OptionalArgs.push_back(emitEHLSDA(Builder, &F));
472  } else if (Personality == EHPersonality::MSVC_X86SEH) {
473  OptionalArgs.push_back(SehLongjmpUnwind.getCallee());
474  OptionalArgs.push_back(State);
475  if (UseStackGuard)
476  OptionalArgs.push_back(Cookie);
477  } else {
478  llvm_unreachable("unhandled personality!");
479  }
480 
482  Args.push_back(
483  Builder.CreateBitCast(Call.getArgOperand(0), Builder.getInt8PtrTy()));
484  Args.push_back(Builder.getInt32(OptionalArgs.size()));
485  Args.append(OptionalArgs.begin(), OptionalArgs.end());
486 
487  CallBase *NewCall;
488  if (auto *CI = dyn_cast<CallInst>(&Call)) {
489  CallInst *NewCI = Builder.CreateCall(SetJmp3, Args, OpBundles);
490  NewCI->setTailCallKind(CI->getTailCallKind());
491  NewCall = NewCI;
492  } else {
493  auto *II = cast<InvokeInst>(&Call);
494  NewCall = Builder.CreateInvoke(
495  SetJmp3, II->getNormalDest(), II->getUnwindDest(), Args, OpBundles);
496  }
497  NewCall->setCallingConv(Call.getCallingConv());
498  NewCall->setAttributes(Call.getAttributes());
499  NewCall->setDebugLoc(Call.getDebugLoc());
500 
501  NewCall->takeName(&Call);
502  Call.replaceAllUsesWith(NewCall);
503  Call.eraseFromParent();
504 }
505 
506 // Figure out what state we should assign calls in this block.
507 int WinEHStatePass::getBaseStateForBB(
508  DenseMap<BasicBlock *, ColorVector> &BlockColors, WinEHFuncInfo &FuncInfo,
509  BasicBlock *BB) {
510  int BaseState = ParentBaseState;
511  auto &BBColors = BlockColors[BB];
512 
513  assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
514  BasicBlock *FuncletEntryBB = BBColors.front();
515  if (auto *FuncletPad =
516  dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI())) {
517  auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad);
518  if (BaseStateI != FuncInfo.FuncletBaseStateMap.end())
519  BaseState = BaseStateI->second;
520  }
521 
522  return BaseState;
523 }
524 
525 // Calculate the state a call-site is in.
526 int WinEHStatePass::getStateForCall(
527  DenseMap<BasicBlock *, ColorVector> &BlockColors, WinEHFuncInfo &FuncInfo,
528  CallBase &Call) {
529  if (auto *II = dyn_cast<InvokeInst>(&Call)) {
530  // Look up the state number of the EH pad this unwinds to.
531  assert(FuncInfo.InvokeStateMap.count(II) && "invoke has no state!");
532  return FuncInfo.InvokeStateMap[II];
533  }
534  // Possibly throwing call instructions have no actions to take after
535  // an unwind. Ensure they are in the -1 state.
536  return getBaseStateForBB(BlockColors, FuncInfo, Call.getParent());
537 }
538 
539 // Calculate the intersection of all the FinalStates for a BasicBlock's
540 // predecessors.
542  int ParentBaseState, BasicBlock *BB) {
543  // The entry block has no predecessors but we know that the prologue always
544  // sets us up with a fixed state.
545  if (&F.getEntryBlock() == BB)
546  return ParentBaseState;
547 
548  // This is an EH Pad, conservatively report this basic block as overdefined.
549  if (BB->isEHPad())
550  return OverdefinedState;
551 
552  int CommonState = OverdefinedState;
553  for (BasicBlock *PredBB : predecessors(BB)) {
554  // We didn't manage to get a state for one of these predecessors,
555  // conservatively report this basic block as overdefined.
556  auto PredEndState = FinalStates.find(PredBB);
557  if (PredEndState == FinalStates.end())
558  return OverdefinedState;
559 
560  // This code is reachable via exceptional control flow,
561  // conservatively report this basic block as overdefined.
562  if (isa<CatchReturnInst>(PredBB->getTerminator()))
563  return OverdefinedState;
564 
565  int PredState = PredEndState->second;
566  assert(PredState != OverdefinedState &&
567  "overdefined BBs shouldn't be in FinalStates");
568  if (CommonState == OverdefinedState)
569  CommonState = PredState;
570 
571  // At least two predecessors have different FinalStates,
572  // conservatively report this basic block as overdefined.
573  if (CommonState != PredState)
574  return OverdefinedState;
575  }
576 
577  return CommonState;
578 }
579 
580 // Calculate the intersection of all the InitialStates for a BasicBlock's
581 // successors.
583  int ParentBaseState, BasicBlock *BB) {
584  // This block rejoins normal control flow,
585  // conservatively report this basic block as overdefined.
586  if (isa<CatchReturnInst>(BB->getTerminator()))
587  return OverdefinedState;
588 
589  int CommonState = OverdefinedState;
590  for (BasicBlock *SuccBB : successors(BB)) {
591  // We didn't manage to get a state for one of these predecessors,
592  // conservatively report this basic block as overdefined.
593  auto SuccStartState = InitialStates.find(SuccBB);
594  if (SuccStartState == InitialStates.end())
595  return OverdefinedState;
596 
597  // This is an EH Pad, conservatively report this basic block as overdefined.
598  if (SuccBB->isEHPad())
599  return OverdefinedState;
600 
601  int SuccState = SuccStartState->second;
602  assert(SuccState != OverdefinedState &&
603  "overdefined BBs shouldn't be in FinalStates");
604  if (CommonState == OverdefinedState)
605  CommonState = SuccState;
606 
607  // At least two successors have different InitialStates,
608  // conservatively report this basic block as overdefined.
609  if (CommonState != SuccState)
610  return OverdefinedState;
611  }
612 
613  return CommonState;
614 }
615 
616 bool WinEHStatePass::isStateStoreNeeded(EHPersonality Personality,
617  CallBase &Call) {
618  // If the function touches memory, it needs a state store.
619  if (isAsynchronousEHPersonality(Personality))
620  return !Call.doesNotAccessMemory();
621 
622  // If the function throws, it needs a state store.
623  return !Call.doesNotThrow();
624 }
625 
626 void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
627  // Mark the registration node. The backend needs to know which alloca it is so
628  // that it can recover the original frame pointer.
629  IRBuilder<> Builder(RegNode->getNextNode());
630  Value *RegNodeI8 = Builder.CreateBitCast(RegNode, Builder.getInt8PtrTy());
631  Builder.CreateCall(
632  Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehregnode),
633  {RegNodeI8});
634 
635  if (EHGuardNode) {
636  IRBuilder<> Builder(EHGuardNode->getNextNode());
637  Value *EHGuardNodeI8 =
638  Builder.CreateBitCast(EHGuardNode, Builder.getInt8PtrTy());
639  Builder.CreateCall(
640  Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehguard),
641  {EHGuardNodeI8});
642  }
643 
644  // Calculate state numbers.
645  if (isAsynchronousEHPersonality(Personality))
646  calculateSEHStateNumbers(&F, FuncInfo);
647  else
648  calculateWinCXXEHStateNumbers(&F, FuncInfo);
649 
650  // Iterate all the instructions and emit state number stores.
653 
654  // InitialStates yields the state of the first call-site for a BasicBlock.
655  DenseMap<BasicBlock *, int> InitialStates;
656  // FinalStates yields the state of the last call-site for a BasicBlock.
657  DenseMap<BasicBlock *, int> FinalStates;
658  // Worklist used to revisit BasicBlocks with indeterminate
659  // Initial/Final-States.
660  std::deque<BasicBlock *> Worklist;
661  // Fill in InitialStates and FinalStates for BasicBlocks with call-sites.
662  for (BasicBlock *BB : RPOT) {
663  int InitialState = OverdefinedState;
664  int FinalState;
665  if (&F.getEntryBlock() == BB)
666  InitialState = FinalState = ParentBaseState;
667  for (Instruction &I : *BB) {
668  auto *Call = dyn_cast<CallBase>(&I);
669  if (!Call || !isStateStoreNeeded(Personality, *Call))
670  continue;
671 
672  int State = getStateForCall(BlockColors, FuncInfo, *Call);
673  if (InitialState == OverdefinedState)
674  InitialState = State;
675  FinalState = State;
676  }
677  // No call-sites in this basic block? That's OK, we will come back to these
678  // in a later pass.
679  if (InitialState == OverdefinedState) {
680  Worklist.push_back(BB);
681  continue;
682  }
683  LLVM_DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
684  << " InitialState=" << InitialState << '\n');
685  LLVM_DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
686  << " FinalState=" << FinalState << '\n');
687  InitialStates.insert({BB, InitialState});
688  FinalStates.insert({BB, FinalState});
689  }
690 
691  // Try to fill-in InitialStates and FinalStates which have no call-sites.
692  while (!Worklist.empty()) {
693  BasicBlock *BB = Worklist.front();
694  Worklist.pop_front();
695  // This BasicBlock has already been figured out, nothing more we can do.
696  if (InitialStates.count(BB) != 0)
697  continue;
698 
699  int PredState = getPredState(FinalStates, F, ParentBaseState, BB);
700  if (PredState == OverdefinedState)
701  continue;
702 
703  // We successfully inferred this BasicBlock's state via it's predecessors;
704  // enqueue it's successors to see if we can infer their states.
705  InitialStates.insert({BB, PredState});
706  FinalStates.insert({BB, PredState});
707  for (BasicBlock *SuccBB : successors(BB))
708  Worklist.push_back(SuccBB);
709  }
710 
711  // Try to hoist stores from successors.
712  for (BasicBlock *BB : RPOT) {
713  int SuccState = getSuccState(InitialStates, F, ParentBaseState, BB);
714  if (SuccState == OverdefinedState)
715  continue;
716 
717  // Update our FinalState to reflect the common InitialState of our
718  // successors.
719  FinalStates.insert({BB, SuccState});
720  }
721 
722  // Finally, insert state stores before call-sites which transition us to a new
723  // state.
724  for (BasicBlock *BB : RPOT) {
725  auto &BBColors = BlockColors[BB];
726  BasicBlock *FuncletEntryBB = BBColors.front();
727  if (isa<CleanupPadInst>(FuncletEntryBB->getFirstNonPHI()))
728  continue;
729 
730  int PrevState = getPredState(FinalStates, F, ParentBaseState, BB);
731  LLVM_DEBUG(dbgs() << "X86WinEHState: " << BB->getName()
732  << " PrevState=" << PrevState << '\n');
733 
734  for (Instruction &I : *BB) {
735  auto *Call = dyn_cast<CallBase>(&I);
736  if (!Call || !isStateStoreNeeded(Personality, *Call))
737  continue;
738 
739  int State = getStateForCall(BlockColors, FuncInfo, *Call);
740  if (State != PrevState)
741  insertStateNumberStore(&I, State);
742  PrevState = State;
743  }
744 
745  // We might have hoisted a state store into this block, emit it now.
746  auto EndState = FinalStates.find(BB);
747  if (EndState != FinalStates.end())
748  if (EndState->second != PrevState)
749  insertStateNumberStore(BB->getTerminator(), EndState->second);
750  }
751 
752  SmallVector<CallBase *, 1> SetJmp3Calls;
753  for (BasicBlock *BB : RPOT) {
754  for (Instruction &I : *BB) {
755  auto *Call = dyn_cast<CallBase>(&I);
756  if (!Call)
757  continue;
758  if (Call->getCalledOperand()->stripPointerCasts() !=
759  SetJmp3.getCallee()->stripPointerCasts())
760  continue;
761 
762  SetJmp3Calls.push_back(Call);
763  }
764  }
765 
766  for (CallBase *Call : SetJmp3Calls) {
767  auto &BBColors = BlockColors[Call->getParent()];
768  BasicBlock *FuncletEntryBB = BBColors.front();
769  bool InCleanup = isa<CleanupPadInst>(FuncletEntryBB->getFirstNonPHI());
770 
771  IRBuilder<> Builder(Call);
772  Value *State;
773  if (InCleanup) {
774  Value *StateField = Builder.CreateStructGEP(RegNode->getAllocatedType(),
775  RegNode, StateFieldIndex);
776  State = Builder.CreateLoad(Builder.getInt32Ty(), StateField);
777  } else {
778  State = Builder.getInt32(getStateForCall(BlockColors, FuncInfo, *Call));
779  }
780  rewriteSetJmpCall(Builder, F, *Call, State);
781  }
782 }
783 
784 void WinEHStatePass::insertStateNumberStore(Instruction *IP, int State) {
786  Value *StateField = Builder.CreateStructGEP(RegNode->getAllocatedType(),
787  RegNode, StateFieldIndex);
788  Builder.CreateStore(Builder.getInt32(State), StateField);
789 }
llvm::EHPersonality::MSVC_CXX
@ MSVC_CXX
llvm::isAsynchronousEHPersonality
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
Definition: EHPersonalities.h:50
Int32Ty
IntegerType * Int32Ty
Definition: NVVMIntrRange.cpp:67
llvm::predecessors
pred_range predecessors(BasicBlock *BB)
Definition: CFG.h:127
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::Intrinsic::getDeclaration
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1379
llvm::Type::getInt8PtrTy
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:293
llvm::GlobalValue::dropLLVMManglingEscape
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
Definition: GlobalValue.h:488
T
llvm::Function
Definition: Function.h:62
Pass.h
llvm::WinEHFuncInfo::InvokeStateMap
DenseMap< const InvokeInst *, int > InvokeStateMap
Definition: WinEHFuncInfo.h:93
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::CallInst::setTailCallKind
void setTailCallKind(TailCallKind TCK)
Definition: Instructions.h:1678
llvm::IRBuilder<>
llvm::FunctionType::get
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:363
llvm::Function::getContext
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:321
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Module.h
EHPersonalities.h
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::count
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:145
getSuccState
static int getSuccState(DenseMap< BasicBlock *, int > &InitialStates, Function &F, int ParentBaseState, BasicBlock *BB)
Definition: X86WinEHState.cpp:582
llvm::codeview::Link
@ Link
Definition: CodeView.h:154
llvm::StructType::create
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition: Type.cpp:515
llvm::successors
succ_range successors(Instruction *I)
Definition: CFG.h:262
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:241
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::classifyEHPersonality
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Definition: EHPersonalities.cpp:21
llvm::WinEHFuncInfo::FuncletBaseStateMap
DenseMap< const FuncletPadInst *, int > FuncletBaseStateMap
Definition: WinEHFuncInfo.h:92
X86.h
Intrinsics.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::CallBase::setAttributes
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
Definition: InstrTypes.h:1462
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
IP
Definition: NVPTXLowerArgs.cpp:166
llvm::GlobalObject::getComdat
const Comdat * getComdat() const
Definition: GlobalObject.h:123
llvm::Instruction
Definition: Instruction.h:45
llvm::BasicBlock::getFirstNonPHI
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
Definition: BasicBlock.cpp:216
llvm::GlobalValue::InternalLinkage
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:55
llvm::MCID::Call
@ Call
Definition: MCInstrDesc.h:153
CFG.h
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::WinEHFuncInfo
Definition: WinEHFuncInfo.h:90
llvm::createX86WinEHStatePass
FunctionPass * createX86WinEHStatePass()
Return an IR pass that inserts EH registration stack objects and explicit EH state updates.
Definition: X86WinEHState.cpp:114
llvm::colorEHFunclets
DenseMap< BasicBlock *, ColorVector > colorEHFunclets(Function &F)
If an EH funclet personality is in use (see isFuncletEHPersonality), this will recompute which blocks...
Definition: EHPersonalities.cpp:81
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::DenseMap
Definition: DenseMap.h:714
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::GlobalObject::setComdat
void setComdat(Comdat *C)
Definition: GlobalObject.h:125
llvm::Instruction::setDebugLoc
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Definition: Instruction.h:367
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:139
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineModuleInfo.h
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:650
CFG.h
llvm::StructType
Class to represent struct types.
Definition: DerivedTypes.h:213
getPredState
static int getPredState(DenseMap< BasicBlock *, int > &FinalStates, Function &F, int ParentBaseState, BasicBlock *BB)
Definition: X86WinEHState.cpp:541
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:100
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:207
llvm::EHPersonality
EHPersonality
Definition: EHPersonalities.h:22
llvm::EHPersonality::MSVC_X86SEH
@ MSVC_X86SEH
llvm::BasicBlock::front
const Instruction & front() const
Definition: BasicBlock.h:308
llvm::EHPersonality::Unknown
@ Unknown
llvm::CallingConv::X86_StdCall
@ X86_StdCall
X86_StdCall - stdcall is the calling conventions mostly used by the Win32 API.
Definition: CallingConv.h:102
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::Constant::getNullValue
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:348
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::end
iterator end()
Definition: DenseMap.h:83
Function.h
llvm::Type::getPointerTo
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
Definition: Type.cpp:776
llvm::Function::arg_begin
arg_iterator arg_begin()
Definition: Function.h:749
llvm::ReversePostOrderTraversal
Definition: PostOrderIterator.h:290
INITIALIZE_PASS
INITIALIZE_PASS(WinEHStatePass, "x86-winehstate", "Insert stores for EH state numbers", false, false) bool WinEHStatePass
Definition: X86WinEHState.cpp:118
WinEHFuncInfo.h
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:476
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:224
Instructions.h
PostOrderIterator.h
llvm::Function::addFnAttr
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition: Function.cpp:536
llvm::FunctionCallee
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1161
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1475
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
GEP
Hexagon Common GEP
Definition: HexagonCommonGEP.cpp:172
llvm::Value::takeName
void takeName(Value *V)
Transfer the name from V to this value.
Definition: Value.cpp:382
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::AllocaInst
an instruction to allocate memory on the stack
Definition: Instructions.h:62
llvm::calculateSEHStateNumbers
void calculateSEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
Definition: WinEHPrepare.cpp:451
llvm::calculateWinCXXEHStateNumbers
void calculateWinCXXEHStateNumbers(const Function *ParentFn, WinEHFuncInfo &FuncInfo)
Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which describes the state number...
Definition: WinEHPrepare.cpp:469
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
Debug.h
llvm::isFuncletEHPersonality
bool isFuncletEHPersonality(EHPersonality Pers)
Returns true if this is a personality function that invokes handler funclets (which must return to it...
Definition: EHPersonalities.h:65
llvm::CallBase::setCallingConv
void setCallingConv(CallingConv::ID CC)
Definition: InstrTypes.h:1443
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:103
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37