1 //===-- WinEHPrepare - Prepare exception handling for code generation ---===// 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 // This pass lowers LLVM IR exception handling into something closer to what the 10 // backend wants for functions using a personality function from a runtime 11 // provided by MSVC. Functions with other personality functions are left alone 12 // and may be prepared by other passes. In particular, all supported MSVC 13 // personality functions require cleanup code to be outlined, and the C++ 14 // personality requires catch handler code to be outlined. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #include "llvm/ADT/DenseMap.h" 19 #include "llvm/ADT/MapVector.h" 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/Analysis/CFG.h" 22 #include "llvm/Analysis/EHPersonalities.h" 23 #include "llvm/CodeGen/MachineBasicBlock.h" 24 #include "llvm/CodeGen/Passes.h" 25 #include "llvm/CodeGen/WinEHFuncInfo.h" 26 #include "llvm/IR/Verifier.h" 27 #include "llvm/InitializePasses.h" 28 #include "llvm/MC/MCSymbol.h" 29 #include "llvm/Pass.h" 30 #include "llvm/Support/CommandLine.h" 31 #include "llvm/Support/Debug.h" 32 #include "llvm/Support/raw_ostream.h" 33 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 34 #include "llvm/Transforms/Utils/Cloning.h" 35 #include "llvm/Transforms/Utils/Local.h" 36 #include "llvm/Transforms/Utils/SSAUpdater.h" 37 38 using namespace llvm; 39 40 #define DEBUG_TYPE "winehprepare" 41 42 static cl::opt<bool> DisableDemotion( 43 "disable-demotion", cl::Hidden, 44 cl::desc( 45 "Clone multicolor basic blocks but do not demote cross scopes"), 46 cl::init(false)); 47 48 static cl::opt<bool> DisableCleanups( 49 "disable-cleanups", cl::Hidden, 50 cl::desc("Do not remove implausible terminators or other similar cleanups"), 51 cl::init(false)); 52 53 static cl::opt<bool> DemoteCatchSwitchPHIOnlyOpt( 54 "demote-catchswitch-only", cl::Hidden, 55 cl::desc("Demote catchswitch BBs only (for wasm EH)"), cl::init(false)); 56 57 namespace { 58 59 class WinEHPrepare : public FunctionPass { 60 public: 61 static char ID; // Pass identification, replacement for typeid. 62 WinEHPrepare(bool DemoteCatchSwitchPHIOnly = false) 63 : FunctionPass(ID), DemoteCatchSwitchPHIOnly(DemoteCatchSwitchPHIOnly) {} 64 65 bool runOnFunction(Function &Fn) override; 66 67 bool doFinalization(Module &M) override; 68 69 void getAnalysisUsage(AnalysisUsage &AU) const override; 70 71 StringRef getPassName() const override { 72 return "Windows exception handling preparation"; 73 } 74 75 private: 76 void insertPHIStores(PHINode *OriginalPHI, AllocaInst *SpillSlot); 77 void 78 insertPHIStore(BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot, 79 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist); 80 AllocaInst *insertPHILoads(PHINode *PN, Function &F); 81 void replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot, 82 DenseMap<BasicBlock *, Value *> &Loads, Function &F); 83 bool prepareExplicitEH(Function &F); 84 void colorFunclets(Function &F); 85 86 void demotePHIsOnFunclets(Function &F, bool DemoteCatchSwitchPHIOnly); 87 void cloneCommonBlocks(Function &F); 88 void removeImplausibleInstructions(Function &F); 89 void cleanupPreparedFunclets(Function &F); 90 void verifyPreparedFunclets(Function &F); 91 92 bool DemoteCatchSwitchPHIOnly; 93 94 // All fields are reset by runOnFunction. 95 EHPersonality Personality = EHPersonality::Unknown; 96 97 const DataLayout *DL = nullptr; 98 DenseMap<BasicBlock *, ColorVector> BlockColors; 99 MapVector<BasicBlock *, std::vector<BasicBlock *>> FuncletBlocks; 100 }; 101 102 } // end anonymous namespace 103 104 char WinEHPrepare::ID = 0; 105 INITIALIZE_PASS(WinEHPrepare, DEBUG_TYPE, "Prepare Windows exceptions", 106 false, false) 107 108 FunctionPass *llvm::createWinEHPass(bool DemoteCatchSwitchPHIOnly) { 109 return new WinEHPrepare(DemoteCatchSwitchPHIOnly); 110 } 111 112 bool WinEHPrepare::runOnFunction(Function &Fn) { 113 if (!Fn.hasPersonalityFn()) 114 return false; 115 116 // Classify the personality to see what kind of preparation we need. 117 Personality = classifyEHPersonality(Fn.getPersonalityFn()); 118 119 // Do nothing if this is not a scope-based personality. 120 if (!isScopedEHPersonality(Personality)) 121 return false; 122 123 DL = &Fn.getParent()->getDataLayout(); 124 return prepareExplicitEH(Fn); 125 } 126 127 bool WinEHPrepare::doFinalization(Module &M) { return false; } 128 129 void WinEHPrepare::getAnalysisUsage(AnalysisUsage &AU) const {} 130 131 static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState, 132 const BasicBlock *BB) { 133 CxxUnwindMapEntry UME; 134 UME.ToState = ToState; 135 UME.Cleanup = BB; 136 FuncInfo.CxxUnwindMap.push_back(UME); 137 return FuncInfo.getLastStateNumber(); 138 } 139 140 static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow, 141 int TryHigh, int CatchHigh, 142 ArrayRef<const CatchPadInst *> Handlers) { 143 WinEHTryBlockMapEntry TBME; 144 TBME.TryLow = TryLow; 145 TBME.TryHigh = TryHigh; 146 TBME.CatchHigh = CatchHigh; 147 assert(TBME.TryLow <= TBME.TryHigh); 148 for (const CatchPadInst *CPI : Handlers) { 149 WinEHHandlerType HT; 150 Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0)); 151 if (TypeInfo->isNullValue()) 152 HT.TypeDescriptor = nullptr; 153 else 154 HT.TypeDescriptor = cast<GlobalVariable>(TypeInfo->stripPointerCasts()); 155 HT.Adjectives = cast<ConstantInt>(CPI->getArgOperand(1))->getZExtValue(); 156 HT.Handler = CPI->getParent(); 157 if (auto *AI = 158 dyn_cast<AllocaInst>(CPI->getArgOperand(2)->stripPointerCasts())) 159 HT.CatchObj.Alloca = AI; 160 else 161 HT.CatchObj.Alloca = nullptr; 162 TBME.HandlerArray.push_back(HT); 163 } 164 FuncInfo.TryBlockMap.push_back(TBME); 165 } 166 167 static BasicBlock *getCleanupRetUnwindDest(const CleanupPadInst *CleanupPad) { 168 for (const User *U : CleanupPad->users()) 169 if (const auto *CRI = dyn_cast<CleanupReturnInst>(U)) 170 return CRI->getUnwindDest(); 171 return nullptr; 172 } 173 174 static void calculateStateNumbersForInvokes(const Function *Fn, 175 WinEHFuncInfo &FuncInfo) { 176 auto *F = const_cast<Function *>(Fn); 177 DenseMap<BasicBlock *, ColorVector> BlockColors = colorEHFunclets(*F); 178 for (BasicBlock &BB : *F) { 179 auto *II = dyn_cast<InvokeInst>(BB.getTerminator()); 180 if (!II) 181 continue; 182 183 auto &BBColors = BlockColors[&BB]; 184 assert(BBColors.size() == 1 && "multi-color BB not removed by preparation"); 185 BasicBlock *FuncletEntryBB = BBColors.front(); 186 187 BasicBlock *FuncletUnwindDest; 188 auto *FuncletPad = 189 dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI()); 190 assert(FuncletPad || FuncletEntryBB == &Fn->getEntryBlock()); 191 if (!FuncletPad) 192 FuncletUnwindDest = nullptr; 193 else if (auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad)) 194 FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest(); 195 else if (auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad)) 196 FuncletUnwindDest = getCleanupRetUnwindDest(CleanupPad); 197 else 198 llvm_unreachable("unexpected funclet pad!"); 199 200 BasicBlock *InvokeUnwindDest = II->getUnwindDest(); 201 int BaseState = -1; 202 if (FuncletUnwindDest == InvokeUnwindDest) { 203 auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad); 204 if (BaseStateI != FuncInfo.FuncletBaseStateMap.end()) 205 BaseState = BaseStateI->second; 206 } 207 208 if (BaseState != -1) { 209 FuncInfo.InvokeStateMap[II] = BaseState; 210 } else { 211 Instruction *PadInst = InvokeUnwindDest->getFirstNonPHI(); 212 assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!"); 213 FuncInfo.InvokeStateMap[II] = FuncInfo.EHPadStateMap[PadInst]; 214 } 215 } 216 } 217 218 // Given BB which ends in an unwind edge, return the EHPad that this BB belongs 219 // to. If the unwind edge came from an invoke, return null. 220 static const BasicBlock *getEHPadFromPredecessor(const BasicBlock *BB, 221 Value *ParentPad) { 222 const Instruction *TI = BB->getTerminator(); 223 if (isa<InvokeInst>(TI)) 224 return nullptr; 225 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) { 226 if (CatchSwitch->getParentPad() != ParentPad) 227 return nullptr; 228 return BB; 229 } 230 assert(!TI->isEHPad() && "unexpected EHPad!"); 231 auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad(); 232 if (CleanupPad->getParentPad() != ParentPad) 233 return nullptr; 234 return CleanupPad->getParent(); 235 } 236 237 // Starting from a EHPad, Backward walk through control-flow graph 238 // to produce two primary outputs: 239 // FuncInfo.EHPadStateMap[] and FuncInfo.CxxUnwindMap[] 240 static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo, 241 const Instruction *FirstNonPHI, 242 int ParentState) { 243 const BasicBlock *BB = FirstNonPHI->getParent(); 244 assert(BB->isEHPad() && "not a funclet!"); 245 246 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) { 247 assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 && 248 "shouldn't revist catch funclets!"); 249 250 SmallVector<const CatchPadInst *, 2> Handlers; 251 for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) { 252 auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI()); 253 Handlers.push_back(CatchPad); 254 } 255 int TryLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr); 256 FuncInfo.EHPadStateMap[CatchSwitch] = TryLow; 257 for (const BasicBlock *PredBlock : predecessors(BB)) 258 if ((PredBlock = getEHPadFromPredecessor(PredBlock, 259 CatchSwitch->getParentPad()))) 260 calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(), 261 TryLow); 262 int CatchLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr); 263 264 // catchpads are separate funclets in C++ EH due to the way rethrow works. 265 int TryHigh = CatchLow - 1; 266 267 // MSVC FrameHandler3/4 on x64&Arm64 expect Catch Handlers in $tryMap$ 268 // stored in pre-order (outer first, inner next), not post-order 269 // Add to map here. Fix the CatchHigh after children are processed 270 const Module *Mod = BB->getParent()->getParent(); 271 bool IsPreOrder = Triple(Mod->getTargetTriple()).isArch64Bit(); 272 if (IsPreOrder) 273 addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchLow, Handlers); 274 unsigned TBMEIdx = FuncInfo.TryBlockMap.size() - 1; 275 276 for (const auto *CatchPad : Handlers) { 277 FuncInfo.FuncletBaseStateMap[CatchPad] = CatchLow; 278 for (const User *U : CatchPad->users()) { 279 const auto *UserI = cast<Instruction>(U); 280 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) { 281 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest(); 282 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest()) 283 calculateCXXStateNumbers(FuncInfo, UserI, CatchLow); 284 } 285 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) { 286 BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad); 287 // If a nested cleanup pad reports a null unwind destination and the 288 // enclosing catch pad doesn't it must be post-dominated by an 289 // unreachable instruction. 290 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest()) 291 calculateCXXStateNumbers(FuncInfo, UserI, CatchLow); 292 } 293 } 294 } 295 int CatchHigh = FuncInfo.getLastStateNumber(); 296 // Now child Catches are processed, update CatchHigh 297 if (IsPreOrder) 298 FuncInfo.TryBlockMap[TBMEIdx].CatchHigh = CatchHigh; 299 else // PostOrder 300 addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchHigh, Handlers); 301 302 LLVM_DEBUG(dbgs() << "TryLow[" << BB->getName() << "]: " << TryLow << '\n'); 303 LLVM_DEBUG(dbgs() << "TryHigh[" << BB->getName() << "]: " << TryHigh 304 << '\n'); 305 LLVM_DEBUG(dbgs() << "CatchHigh[" << BB->getName() << "]: " << CatchHigh 306 << '\n'); 307 } else { 308 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI); 309 310 // It's possible for a cleanup to be visited twice: it might have multiple 311 // cleanupret instructions. 312 if (FuncInfo.EHPadStateMap.count(CleanupPad)) 313 return; 314 315 int CleanupState = addUnwindMapEntry(FuncInfo, ParentState, BB); 316 FuncInfo.EHPadStateMap[CleanupPad] = CleanupState; 317 LLVM_DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB " 318 << BB->getName() << '\n'); 319 for (const BasicBlock *PredBlock : predecessors(BB)) { 320 if ((PredBlock = getEHPadFromPredecessor(PredBlock, 321 CleanupPad->getParentPad()))) { 322 calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(), 323 CleanupState); 324 } 325 } 326 for (const User *U : CleanupPad->users()) { 327 const auto *UserI = cast<Instruction>(U); 328 if (UserI->isEHPad()) 329 report_fatal_error("Cleanup funclets for the MSVC++ personality cannot " 330 "contain exceptional actions"); 331 } 332 } 333 } 334 335 static int addSEHExcept(WinEHFuncInfo &FuncInfo, int ParentState, 336 const Function *Filter, const BasicBlock *Handler) { 337 SEHUnwindMapEntry Entry; 338 Entry.ToState = ParentState; 339 Entry.IsFinally = false; 340 Entry.Filter = Filter; 341 Entry.Handler = Handler; 342 FuncInfo.SEHUnwindMap.push_back(Entry); 343 return FuncInfo.SEHUnwindMap.size() - 1; 344 } 345 346 static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState, 347 const BasicBlock *Handler) { 348 SEHUnwindMapEntry Entry; 349 Entry.ToState = ParentState; 350 Entry.IsFinally = true; 351 Entry.Filter = nullptr; 352 Entry.Handler = Handler; 353 FuncInfo.SEHUnwindMap.push_back(Entry); 354 return FuncInfo.SEHUnwindMap.size() - 1; 355 } 356 357 // Starting from a EHPad, Backward walk through control-flow graph 358 // to produce two primary outputs: 359 // FuncInfo.EHPadStateMap[] and FuncInfo.SEHUnwindMap[] 360 static void calculateSEHStateNumbers(WinEHFuncInfo &FuncInfo, 361 const Instruction *FirstNonPHI, 362 int ParentState) { 363 const BasicBlock *BB = FirstNonPHI->getParent(); 364 assert(BB->isEHPad() && "no a funclet!"); 365 366 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) { 367 assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 && 368 "shouldn't revist catch funclets!"); 369 370 // Extract the filter function and the __except basic block and create a 371 // state for them. 372 assert(CatchSwitch->getNumHandlers() == 1 && 373 "SEH doesn't have multiple handlers per __try"); 374 const auto *CatchPad = 375 cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI()); 376 const BasicBlock *CatchPadBB = CatchPad->getParent(); 377 const Constant *FilterOrNull = 378 cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts()); 379 const Function *Filter = dyn_cast<Function>(FilterOrNull); 380 assert((Filter || FilterOrNull->isNullValue()) && 381 "unexpected filter value"); 382 int TryState = addSEHExcept(FuncInfo, ParentState, Filter, CatchPadBB); 383 384 // Everything in the __try block uses TryState as its parent state. 385 FuncInfo.EHPadStateMap[CatchSwitch] = TryState; 386 LLVM_DEBUG(dbgs() << "Assigning state #" << TryState << " to BB " 387 << CatchPadBB->getName() << '\n'); 388 for (const BasicBlock *PredBlock : predecessors(BB)) 389 if ((PredBlock = getEHPadFromPredecessor(PredBlock, 390 CatchSwitch->getParentPad()))) 391 calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(), 392 TryState); 393 394 // Everything in the __except block unwinds to ParentState, just like code 395 // outside the __try. 396 for (const User *U : CatchPad->users()) { 397 const auto *UserI = cast<Instruction>(U); 398 if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI)) { 399 BasicBlock *UnwindDest = InnerCatchSwitch->getUnwindDest(); 400 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest()) 401 calculateSEHStateNumbers(FuncInfo, UserI, ParentState); 402 } 403 if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI)) { 404 BasicBlock *UnwindDest = getCleanupRetUnwindDest(InnerCleanupPad); 405 // If a nested cleanup pad reports a null unwind destination and the 406 // enclosing catch pad doesn't it must be post-dominated by an 407 // unreachable instruction. 408 if (!UnwindDest || UnwindDest == CatchSwitch->getUnwindDest()) 409 calculateSEHStateNumbers(FuncInfo, UserI, ParentState); 410 } 411 } 412 } else { 413 auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI); 414 415 // It's possible for a cleanup to be visited twice: it might have multiple 416 // cleanupret instructions. 417 if (FuncInfo.EHPadStateMap.count(CleanupPad)) 418 return; 419 420 int CleanupState = addSEHFinally(FuncInfo, ParentState, BB); 421 FuncInfo.EHPadStateMap[CleanupPad] = CleanupState; 422 LLVM_DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB " 423 << BB->getName() << '\n'); 424 for (const BasicBlock *PredBlock : predecessors(BB)) 425 if ((PredBlock = 426 getEHPadFromPredecessor(PredBlock, CleanupPad->getParentPad()))) 427 calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(), 428 CleanupState); 429 for (const User *U : CleanupPad->users()) { 430 const auto *UserI = cast<Instruction>(U); 431 if (UserI->isEHPad()) 432 report_fatal_error("Cleanup funclets for the SEH personality cannot " 433 "contain exceptional actions"); 434 } 435 } 436 } 437 438 static bool isTopLevelPadForMSVC(const Instruction *EHPad) { 439 if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad)) 440 return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) && 441 CatchSwitch->unwindsToCaller(); 442 if (auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad)) 443 return isa<ConstantTokenNone>(CleanupPad->getParentPad()) && 444 getCleanupRetUnwindDest(CleanupPad) == nullptr; 445 if (isa<CatchPadInst>(EHPad)) 446 return false; 447 llvm_unreachable("unexpected EHPad!"); 448 } 449 450 void llvm::calculateSEHStateNumbers(const Function *Fn, 451 WinEHFuncInfo &FuncInfo) { 452 // Don't compute state numbers twice. 453 if (!FuncInfo.SEHUnwindMap.empty()) 454 return; 455 456 for (const BasicBlock &BB : *Fn) { 457 if (!BB.isEHPad()) 458 continue; 459 const Instruction *FirstNonPHI = BB.getFirstNonPHI(); 460 if (!isTopLevelPadForMSVC(FirstNonPHI)) 461 continue; 462 ::calculateSEHStateNumbers(FuncInfo, FirstNonPHI, -1); 463 } 464 465 calculateStateNumbersForInvokes(Fn, FuncInfo); 466 } 467 468 void llvm::calculateWinCXXEHStateNumbers(const Function *Fn, 469 WinEHFuncInfo &FuncInfo) { 470 // Return if it's already been done. 471 if (!FuncInfo.EHPadStateMap.empty()) 472 return; 473 474 for (const BasicBlock &BB : *Fn) { 475 if (!BB.isEHPad()) 476 continue; 477 const Instruction *FirstNonPHI = BB.getFirstNonPHI(); 478 if (!isTopLevelPadForMSVC(FirstNonPHI)) 479 continue; 480 calculateCXXStateNumbers(FuncInfo, FirstNonPHI, -1); 481 } 482 483 calculateStateNumbersForInvokes(Fn, FuncInfo); 484 } 485 486 static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int HandlerParentState, 487 int TryParentState, ClrHandlerType HandlerType, 488 uint32_t TypeToken, const BasicBlock *Handler) { 489 ClrEHUnwindMapEntry Entry; 490 Entry.HandlerParentState = HandlerParentState; 491 Entry.TryParentState = TryParentState; 492 Entry.Handler = Handler; 493 Entry.HandlerType = HandlerType; 494 Entry.TypeToken = TypeToken; 495 FuncInfo.ClrEHUnwindMap.push_back(Entry); 496 return FuncInfo.ClrEHUnwindMap.size() - 1; 497 } 498 499 void llvm::calculateClrEHStateNumbers(const Function *Fn, 500 WinEHFuncInfo &FuncInfo) { 501 // Return if it's already been done. 502 if (!FuncInfo.EHPadStateMap.empty()) 503 return; 504 505 // This numbering assigns one state number to each catchpad and cleanuppad. 506 // It also computes two tree-like relations over states: 507 // 1) Each state has a "HandlerParentState", which is the state of the next 508 // outer handler enclosing this state's handler (same as nearest ancestor 509 // per the ParentPad linkage on EH pads, but skipping over catchswitches). 510 // 2) Each state has a "TryParentState", which: 511 // a) for a catchpad that's not the last handler on its catchswitch, is 512 // the state of the next catchpad on that catchswitch 513 // b) for all other pads, is the state of the pad whose try region is the 514 // next outer try region enclosing this state's try region. The "try 515 // regions are not present as such in the IR, but will be inferred 516 // based on the placement of invokes and pads which reach each other 517 // by exceptional exits 518 // Catchswitches do not get their own states, but each gets mapped to the 519 // state of its first catchpad. 520 521 // Step one: walk down from outermost to innermost funclets, assigning each 522 // catchpad and cleanuppad a state number. Add an entry to the 523 // ClrEHUnwindMap for each state, recording its HandlerParentState and 524 // handler attributes. Record the TryParentState as well for each catchpad 525 // that's not the last on its catchswitch, but initialize all other entries' 526 // TryParentStates to a sentinel -1 value that the next pass will update. 527 528 // Seed a worklist with pads that have no parent. 529 SmallVector<std::pair<const Instruction *, int>, 8> Worklist; 530 for (const BasicBlock &BB : *Fn) { 531 const Instruction *FirstNonPHI = BB.getFirstNonPHI(); 532 const Value *ParentPad; 533 if (const auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI)) 534 ParentPad = CPI->getParentPad(); 535 else if (const auto *CSI = dyn_cast<CatchSwitchInst>(FirstNonPHI)) 536 ParentPad = CSI->getParentPad(); 537 else 538 continue; 539 if (isa<ConstantTokenNone>(ParentPad)) 540 Worklist.emplace_back(FirstNonPHI, -1); 541 } 542 543 // Use the worklist to visit all pads, from outer to inner. Record 544 // HandlerParentState for all pads. Record TryParentState only for catchpads 545 // that aren't the last on their catchswitch (setting all other entries' 546 // TryParentStates to an initial value of -1). This loop is also responsible 547 // for setting the EHPadStateMap entry for all catchpads, cleanuppads, and 548 // catchswitches. 549 while (!Worklist.empty()) { 550 const Instruction *Pad; 551 int HandlerParentState; 552 std::tie(Pad, HandlerParentState) = Worklist.pop_back_val(); 553 554 if (const auto *Cleanup = dyn_cast<CleanupPadInst>(Pad)) { 555 // Create the entry for this cleanup with the appropriate handler 556 // properties. Finally and fault handlers are distinguished by arity. 557 ClrHandlerType HandlerType = 558 (Cleanup->getNumArgOperands() ? ClrHandlerType::Fault 559 : ClrHandlerType::Finally); 560 int CleanupState = addClrEHHandler(FuncInfo, HandlerParentState, -1, 561 HandlerType, 0, Pad->getParent()); 562 // Queue any child EH pads on the worklist. 563 for (const User *U : Cleanup->users()) 564 if (const auto *I = dyn_cast<Instruction>(U)) 565 if (I->isEHPad()) 566 Worklist.emplace_back(I, CleanupState); 567 // Remember this pad's state. 568 FuncInfo.EHPadStateMap[Cleanup] = CleanupState; 569 } else { 570 // Walk the handlers of this catchswitch in reverse order since all but 571 // the last need to set the following one as its TryParentState. 572 const auto *CatchSwitch = cast<CatchSwitchInst>(Pad); 573 int CatchState = -1, FollowerState = -1; 574 SmallVector<const BasicBlock *, 4> CatchBlocks(CatchSwitch->handlers()); 575 for (auto CBI = CatchBlocks.rbegin(), CBE = CatchBlocks.rend(); 576 CBI != CBE; ++CBI, FollowerState = CatchState) { 577 const BasicBlock *CatchBlock = *CBI; 578 // Create the entry for this catch with the appropriate handler 579 // properties. 580 const auto *Catch = cast<CatchPadInst>(CatchBlock->getFirstNonPHI()); 581 uint32_t TypeToken = static_cast<uint32_t>( 582 cast<ConstantInt>(Catch->getArgOperand(0))->getZExtValue()); 583 CatchState = 584 addClrEHHandler(FuncInfo, HandlerParentState, FollowerState, 585 ClrHandlerType::Catch, TypeToken, CatchBlock); 586 // Queue any child EH pads on the worklist. 587 for (const User *U : Catch->users()) 588 if (const auto *I = dyn_cast<Instruction>(U)) 589 if (I->isEHPad()) 590 Worklist.emplace_back(I, CatchState); 591 // Remember this catch's state. 592 FuncInfo.EHPadStateMap[Catch] = CatchState; 593 } 594 // Associate the catchswitch with the state of its first catch. 595 assert(CatchSwitch->getNumHandlers()); 596 FuncInfo.EHPadStateMap[CatchSwitch] = CatchState; 597 } 598 } 599 600 // Step two: record the TryParentState of each state. For cleanuppads that 601 // don't have cleanuprets, we may need to infer this from their child pads, 602 // so visit pads in descendant-most to ancestor-most order. 603 for (auto Entry = FuncInfo.ClrEHUnwindMap.rbegin(), 604 End = FuncInfo.ClrEHUnwindMap.rend(); 605 Entry != End; ++Entry) { 606 const Instruction *Pad = 607 Entry->Handler.get<const BasicBlock *>()->getFirstNonPHI(); 608 // For most pads, the TryParentState is the state associated with the 609 // unwind dest of exceptional exits from it. 610 const BasicBlock *UnwindDest; 611 if (const auto *Catch = dyn_cast<CatchPadInst>(Pad)) { 612 // If a catch is not the last in its catchswitch, its TryParentState is 613 // the state associated with the next catch in the switch, even though 614 // that's not the unwind dest of exceptions escaping the catch. Those 615 // cases were already assigned a TryParentState in the first pass, so 616 // skip them. 617 if (Entry->TryParentState != -1) 618 continue; 619 // Otherwise, get the unwind dest from the catchswitch. 620 UnwindDest = Catch->getCatchSwitch()->getUnwindDest(); 621 } else { 622 const auto *Cleanup = cast<CleanupPadInst>(Pad); 623 UnwindDest = nullptr; 624 for (const User *U : Cleanup->users()) { 625 if (auto *CleanupRet = dyn_cast<CleanupReturnInst>(U)) { 626 // Common and unambiguous case -- cleanupret indicates cleanup's 627 // unwind dest. 628 UnwindDest = CleanupRet->getUnwindDest(); 629 break; 630 } 631 632 // Get an unwind dest for the user 633 const BasicBlock *UserUnwindDest = nullptr; 634 if (auto *Invoke = dyn_cast<InvokeInst>(U)) { 635 UserUnwindDest = Invoke->getUnwindDest(); 636 } else if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(U)) { 637 UserUnwindDest = CatchSwitch->getUnwindDest(); 638 } else if (auto *ChildCleanup = dyn_cast<CleanupPadInst>(U)) { 639 int UserState = FuncInfo.EHPadStateMap[ChildCleanup]; 640 int UserUnwindState = 641 FuncInfo.ClrEHUnwindMap[UserState].TryParentState; 642 if (UserUnwindState != -1) 643 UserUnwindDest = FuncInfo.ClrEHUnwindMap[UserUnwindState] 644 .Handler.get<const BasicBlock *>(); 645 } 646 647 // Not having an unwind dest for this user might indicate that it 648 // doesn't unwind, so can't be taken as proof that the cleanup itself 649 // may unwind to caller (see e.g. SimplifyUnreachable and 650 // RemoveUnwindEdge). 651 if (!UserUnwindDest) 652 continue; 653 654 // Now we have an unwind dest for the user, but we need to see if it 655 // unwinds all the way out of the cleanup or if it stays within it. 656 const Instruction *UserUnwindPad = UserUnwindDest->getFirstNonPHI(); 657 const Value *UserUnwindParent; 658 if (auto *CSI = dyn_cast<CatchSwitchInst>(UserUnwindPad)) 659 UserUnwindParent = CSI->getParentPad(); 660 else 661 UserUnwindParent = 662 cast<CleanupPadInst>(UserUnwindPad)->getParentPad(); 663 664 // The unwind stays within the cleanup iff it targets a child of the 665 // cleanup. 666 if (UserUnwindParent == Cleanup) 667 continue; 668 669 // This unwind exits the cleanup, so its dest is the cleanup's dest. 670 UnwindDest = UserUnwindDest; 671 break; 672 } 673 } 674 675 // Record the state of the unwind dest as the TryParentState. 676 int UnwindDestState; 677 678 // If UnwindDest is null at this point, either the pad in question can 679 // be exited by unwind to caller, or it cannot be exited by unwind. In 680 // either case, reporting such cases as unwinding to caller is correct. 681 // This can lead to EH tables that "look strange" -- if this pad's is in 682 // a parent funclet which has other children that do unwind to an enclosing 683 // pad, the try region for this pad will be missing the "duplicate" EH 684 // clause entries that you'd expect to see covering the whole parent. That 685 // should be benign, since the unwind never actually happens. If it were 686 // an issue, we could add a subsequent pass that pushes unwind dests down 687 // from parents that have them to children that appear to unwind to caller. 688 if (!UnwindDest) { 689 UnwindDestState = -1; 690 } else { 691 UnwindDestState = FuncInfo.EHPadStateMap[UnwindDest->getFirstNonPHI()]; 692 } 693 694 Entry->TryParentState = UnwindDestState; 695 } 696 697 // Step three: transfer information from pads to invokes. 698 calculateStateNumbersForInvokes(Fn, FuncInfo); 699 } 700 701 void WinEHPrepare::colorFunclets(Function &F) { 702 BlockColors = colorEHFunclets(F); 703 704 // Invert the map from BB to colors to color to BBs. 705 for (BasicBlock &BB : F) { 706 ColorVector &Colors = BlockColors[&BB]; 707 for (BasicBlock *Color : Colors) 708 FuncletBlocks[Color].push_back(&BB); 709 } 710 } 711 712 void WinEHPrepare::demotePHIsOnFunclets(Function &F, 713 bool DemoteCatchSwitchPHIOnly) { 714 // Strip PHI nodes off of EH pads. 715 SmallVector<PHINode *, 16> PHINodes; 716 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) { 717 BasicBlock *BB = &*FI++; 718 if (!BB->isEHPad()) 719 continue; 720 if (DemoteCatchSwitchPHIOnly && !isa<CatchSwitchInst>(BB->getFirstNonPHI())) 721 continue; 722 723 for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) { 724 Instruction *I = &*BI++; 725 auto *PN = dyn_cast<PHINode>(I); 726 // Stop at the first non-PHI. 727 if (!PN) 728 break; 729 730 AllocaInst *SpillSlot = insertPHILoads(PN, F); 731 if (SpillSlot) 732 insertPHIStores(PN, SpillSlot); 733 734 PHINodes.push_back(PN); 735 } 736 } 737 738 for (auto *PN : PHINodes) { 739 // There may be lingering uses on other EH PHIs being removed 740 PN->replaceAllUsesWith(UndefValue::get(PN->getType())); 741 PN->eraseFromParent(); 742 } 743 } 744 745 void WinEHPrepare::cloneCommonBlocks(Function &F) { 746 // We need to clone all blocks which belong to multiple funclets. Values are 747 // remapped throughout the funclet to propagate both the new instructions 748 // *and* the new basic blocks themselves. 749 for (auto &Funclets : FuncletBlocks) { 750 BasicBlock *FuncletPadBB = Funclets.first; 751 std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second; 752 Value *FuncletToken; 753 if (FuncletPadBB == &F.getEntryBlock()) 754 FuncletToken = ConstantTokenNone::get(F.getContext()); 755 else 756 FuncletToken = FuncletPadBB->getFirstNonPHI(); 757 758 std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone; 759 ValueToValueMapTy VMap; 760 for (BasicBlock *BB : BlocksInFunclet) { 761 ColorVector &ColorsForBB = BlockColors[BB]; 762 // We don't need to do anything if the block is monochromatic. 763 size_t NumColorsForBB = ColorsForBB.size(); 764 if (NumColorsForBB == 1) 765 continue; 766 767 DEBUG_WITH_TYPE("winehprepare-coloring", 768 dbgs() << " Cloning block \'" << BB->getName() 769 << "\' for funclet \'" << FuncletPadBB->getName() 770 << "\'.\n"); 771 772 // Create a new basic block and copy instructions into it! 773 BasicBlock *CBB = 774 CloneBasicBlock(BB, VMap, Twine(".for.", FuncletPadBB->getName())); 775 // Insert the clone immediately after the original to ensure determinism 776 // and to keep the same relative ordering of any funclet's blocks. 777 CBB->insertInto(&F, BB->getNextNode()); 778 779 // Add basic block mapping. 780 VMap[BB] = CBB; 781 782 // Record delta operations that we need to perform to our color mappings. 783 Orig2Clone.emplace_back(BB, CBB); 784 } 785 786 // If nothing was cloned, we're done cloning in this funclet. 787 if (Orig2Clone.empty()) 788 continue; 789 790 // Update our color mappings to reflect that one block has lost a color and 791 // another has gained a color. 792 for (auto &BBMapping : Orig2Clone) { 793 BasicBlock *OldBlock = BBMapping.first; 794 BasicBlock *NewBlock = BBMapping.second; 795 796 BlocksInFunclet.push_back(NewBlock); 797 ColorVector &NewColors = BlockColors[NewBlock]; 798 assert(NewColors.empty() && "A new block should only have one color!"); 799 NewColors.push_back(FuncletPadBB); 800 801 DEBUG_WITH_TYPE("winehprepare-coloring", 802 dbgs() << " Assigned color \'" << FuncletPadBB->getName() 803 << "\' to block \'" << NewBlock->getName() 804 << "\'.\n"); 805 806 BlocksInFunclet.erase( 807 std::remove(BlocksInFunclet.begin(), BlocksInFunclet.end(), OldBlock), 808 BlocksInFunclet.end()); 809 ColorVector &OldColors = BlockColors[OldBlock]; 810 OldColors.erase( 811 std::remove(OldColors.begin(), OldColors.end(), FuncletPadBB), 812 OldColors.end()); 813 814 DEBUG_WITH_TYPE("winehprepare-coloring", 815 dbgs() << " Removed color \'" << FuncletPadBB->getName() 816 << "\' from block \'" << OldBlock->getName() 817 << "\'.\n"); 818 } 819 820 // Loop over all of the instructions in this funclet, fixing up operand 821 // references as we go. This uses VMap to do all the hard work. 822 for (BasicBlock *BB : BlocksInFunclet) 823 // Loop over all instructions, fixing each one as we find it... 824 for (Instruction &I : *BB) 825 RemapInstruction(&I, VMap, 826 RF_IgnoreMissingLocals | RF_NoModuleLevelChanges); 827 828 // Catchrets targeting cloned blocks need to be updated separately from 829 // the loop above because they are not in the current funclet. 830 SmallVector<CatchReturnInst *, 2> FixupCatchrets; 831 for (auto &BBMapping : Orig2Clone) { 832 BasicBlock *OldBlock = BBMapping.first; 833 BasicBlock *NewBlock = BBMapping.second; 834 835 FixupCatchrets.clear(); 836 for (BasicBlock *Pred : predecessors(OldBlock)) 837 if (auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator())) 838 if (CatchRet->getCatchSwitchParentPad() == FuncletToken) 839 FixupCatchrets.push_back(CatchRet); 840 841 for (CatchReturnInst *CatchRet : FixupCatchrets) 842 CatchRet->setSuccessor(NewBlock); 843 } 844 845 auto UpdatePHIOnClonedBlock = [&](PHINode *PN, bool IsForOldBlock) { 846 unsigned NumPreds = PN->getNumIncomingValues(); 847 for (unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd; 848 ++PredIdx) { 849 BasicBlock *IncomingBlock = PN->getIncomingBlock(PredIdx); 850 bool EdgeTargetsFunclet; 851 if (auto *CRI = 852 dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) { 853 EdgeTargetsFunclet = (CRI->getCatchSwitchParentPad() == FuncletToken); 854 } else { 855 ColorVector &IncomingColors = BlockColors[IncomingBlock]; 856 assert(!IncomingColors.empty() && "Block not colored!"); 857 assert((IncomingColors.size() == 1 || 858 llvm::all_of(IncomingColors, 859 [&](BasicBlock *Color) { 860 return Color != FuncletPadBB; 861 })) && 862 "Cloning should leave this funclet's blocks monochromatic"); 863 EdgeTargetsFunclet = (IncomingColors.front() == FuncletPadBB); 864 } 865 if (IsForOldBlock != EdgeTargetsFunclet) 866 continue; 867 PN->removeIncomingValue(IncomingBlock, /*DeletePHIIfEmpty=*/false); 868 // Revisit the next entry. 869 --PredIdx; 870 --PredEnd; 871 } 872 }; 873 874 for (auto &BBMapping : Orig2Clone) { 875 BasicBlock *OldBlock = BBMapping.first; 876 BasicBlock *NewBlock = BBMapping.second; 877 for (PHINode &OldPN : OldBlock->phis()) { 878 UpdatePHIOnClonedBlock(&OldPN, /*IsForOldBlock=*/true); 879 } 880 for (PHINode &NewPN : NewBlock->phis()) { 881 UpdatePHIOnClonedBlock(&NewPN, /*IsForOldBlock=*/false); 882 } 883 } 884 885 // Check to see if SuccBB has PHI nodes. If so, we need to add entries to 886 // the PHI nodes for NewBB now. 887 for (auto &BBMapping : Orig2Clone) { 888 BasicBlock *OldBlock = BBMapping.first; 889 BasicBlock *NewBlock = BBMapping.second; 890 for (BasicBlock *SuccBB : successors(NewBlock)) { 891 for (PHINode &SuccPN : SuccBB->phis()) { 892 // Ok, we have a PHI node. Figure out what the incoming value was for 893 // the OldBlock. 894 int OldBlockIdx = SuccPN.getBasicBlockIndex(OldBlock); 895 if (OldBlockIdx == -1) 896 break; 897 Value *IV = SuccPN.getIncomingValue(OldBlockIdx); 898 899 // Remap the value if necessary. 900 if (auto *Inst = dyn_cast<Instruction>(IV)) { 901 ValueToValueMapTy::iterator I = VMap.find(Inst); 902 if (I != VMap.end()) 903 IV = I->second; 904 } 905 906 SuccPN.addIncoming(IV, NewBlock); 907 } 908 } 909 } 910 911 for (ValueToValueMapTy::value_type VT : VMap) { 912 // If there were values defined in BB that are used outside the funclet, 913 // then we now have to update all uses of the value to use either the 914 // original value, the cloned value, or some PHI derived value. This can 915 // require arbitrary PHI insertion, of which we are prepared to do, clean 916 // these up now. 917 SmallVector<Use *, 16> UsesToRename; 918 919 auto *OldI = dyn_cast<Instruction>(const_cast<Value *>(VT.first)); 920 if (!OldI) 921 continue; 922 auto *NewI = cast<Instruction>(VT.second); 923 // Scan all uses of this instruction to see if it is used outside of its 924 // funclet, and if so, record them in UsesToRename. 925 for (Use &U : OldI->uses()) { 926 Instruction *UserI = cast<Instruction>(U.getUser()); 927 BasicBlock *UserBB = UserI->getParent(); 928 ColorVector &ColorsForUserBB = BlockColors[UserBB]; 929 assert(!ColorsForUserBB.empty()); 930 if (ColorsForUserBB.size() > 1 || 931 *ColorsForUserBB.begin() != FuncletPadBB) 932 UsesToRename.push_back(&U); 933 } 934 935 // If there are no uses outside the block, we're done with this 936 // instruction. 937 if (UsesToRename.empty()) 938 continue; 939 940 // We found a use of OldI outside of the funclet. Rename all uses of OldI 941 // that are outside its funclet to be uses of the appropriate PHI node 942 // etc. 943 SSAUpdater SSAUpdate; 944 SSAUpdate.Initialize(OldI->getType(), OldI->getName()); 945 SSAUpdate.AddAvailableValue(OldI->getParent(), OldI); 946 SSAUpdate.AddAvailableValue(NewI->getParent(), NewI); 947 948 while (!UsesToRename.empty()) 949 SSAUpdate.RewriteUseAfterInsertions(*UsesToRename.pop_back_val()); 950 } 951 } 952 } 953 954 void WinEHPrepare::removeImplausibleInstructions(Function &F) { 955 // Remove implausible terminators and replace them with UnreachableInst. 956 for (auto &Funclet : FuncletBlocks) { 957 BasicBlock *FuncletPadBB = Funclet.first; 958 std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second; 959 Instruction *FirstNonPHI = FuncletPadBB->getFirstNonPHI(); 960 auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI); 961 auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad); 962 auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad); 963 964 for (BasicBlock *BB : BlocksInFunclet) { 965 for (Instruction &I : *BB) { 966 auto *CB = dyn_cast<CallBase>(&I); 967 if (!CB) 968 continue; 969 970 Value *FuncletBundleOperand = nullptr; 971 if (auto BU = CB->getOperandBundle(LLVMContext::OB_funclet)) 972 FuncletBundleOperand = BU->Inputs.front(); 973 974 if (FuncletBundleOperand == FuncletPad) 975 continue; 976 977 // Skip call sites which are nounwind intrinsics or inline asm. 978 auto *CalledFn = 979 dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts()); 980 if (CalledFn && ((CalledFn->isIntrinsic() && CB->doesNotThrow()) || 981 CB->isInlineAsm())) 982 continue; 983 984 // This call site was not part of this funclet, remove it. 985 if (isa<InvokeInst>(CB)) { 986 // Remove the unwind edge if it was an invoke. 987 removeUnwindEdge(BB); 988 // Get a pointer to the new call. 989 BasicBlock::iterator CallI = 990 std::prev(BB->getTerminator()->getIterator()); 991 auto *CI = cast<CallInst>(&*CallI); 992 changeToUnreachable(CI, /*UseLLVMTrap=*/false); 993 } else { 994 changeToUnreachable(&I, /*UseLLVMTrap=*/false); 995 } 996 997 // There are no more instructions in the block (except for unreachable), 998 // we are done. 999 break; 1000 } 1001 1002 Instruction *TI = BB->getTerminator(); 1003 // CatchPadInst and CleanupPadInst can't transfer control to a ReturnInst. 1004 bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad; 1005 // The token consumed by a CatchReturnInst must match the funclet token. 1006 bool IsUnreachableCatchret = false; 1007 if (auto *CRI = dyn_cast<CatchReturnInst>(TI)) 1008 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad; 1009 // The token consumed by a CleanupReturnInst must match the funclet token. 1010 bool IsUnreachableCleanupret = false; 1011 if (auto *CRI = dyn_cast<CleanupReturnInst>(TI)) 1012 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad; 1013 if (IsUnreachableRet || IsUnreachableCatchret || 1014 IsUnreachableCleanupret) { 1015 changeToUnreachable(TI, /*UseLLVMTrap=*/false); 1016 } else if (isa<InvokeInst>(TI)) { 1017 if (Personality == EHPersonality::MSVC_CXX && CleanupPad) { 1018 // Invokes within a cleanuppad for the MSVC++ personality never 1019 // transfer control to their unwind edge: the personality will 1020 // terminate the program. 1021 removeUnwindEdge(BB); 1022 } 1023 } 1024 } 1025 } 1026 } 1027 1028 void WinEHPrepare::cleanupPreparedFunclets(Function &F) { 1029 // Clean-up some of the mess we made by removing useles PHI nodes, trivial 1030 // branches, etc. 1031 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) { 1032 BasicBlock *BB = &*FI++; 1033 SimplifyInstructionsInBlock(BB); 1034 ConstantFoldTerminator(BB, /*DeleteDeadConditions=*/true); 1035 MergeBlockIntoPredecessor(BB); 1036 } 1037 1038 // We might have some unreachable blocks after cleaning up some impossible 1039 // control flow. 1040 removeUnreachableBlocks(F); 1041 } 1042 1043 #ifndef NDEBUG 1044 void WinEHPrepare::verifyPreparedFunclets(Function &F) { 1045 for (BasicBlock &BB : F) { 1046 size_t NumColors = BlockColors[&BB].size(); 1047 assert(NumColors == 1 && "Expected monochromatic BB!"); 1048 if (NumColors == 0) 1049 report_fatal_error("Uncolored BB!"); 1050 if (NumColors > 1) 1051 report_fatal_error("Multicolor BB!"); 1052 assert((DisableDemotion || !(BB.isEHPad() && isa<PHINode>(BB.begin()))) && 1053 "EH Pad still has a PHI!"); 1054 } 1055 } 1056 #endif 1057 1058 bool WinEHPrepare::prepareExplicitEH(Function &F) { 1059 // Remove unreachable blocks. It is not valuable to assign them a color and 1060 // their existence can trick us into thinking values are alive when they are 1061 // not. 1062 removeUnreachableBlocks(F); 1063 1064 // Determine which blocks are reachable from which funclet entries. 1065 colorFunclets(F); 1066 1067 cloneCommonBlocks(F); 1068 1069 if (!DisableDemotion) 1070 demotePHIsOnFunclets(F, DemoteCatchSwitchPHIOnly || 1071 DemoteCatchSwitchPHIOnlyOpt); 1072 1073 if (!DisableCleanups) { 1074 assert(!verifyFunction(F, &dbgs())); 1075 removeImplausibleInstructions(F); 1076 1077 assert(!verifyFunction(F, &dbgs())); 1078 cleanupPreparedFunclets(F); 1079 } 1080 1081 LLVM_DEBUG(verifyPreparedFunclets(F)); 1082 // Recolor the CFG to verify that all is well. 1083 LLVM_DEBUG(colorFunclets(F)); 1084 LLVM_DEBUG(verifyPreparedFunclets(F)); 1085 1086 BlockColors.clear(); 1087 FuncletBlocks.clear(); 1088 1089 return true; 1090 } 1091 1092 // TODO: Share loads when one use dominates another, or when a catchpad exit 1093 // dominates uses (needs dominators). 1094 AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) { 1095 BasicBlock *PHIBlock = PN->getParent(); 1096 AllocaInst *SpillSlot = nullptr; 1097 Instruction *EHPad = PHIBlock->getFirstNonPHI(); 1098 1099 if (!EHPad->isTerminator()) { 1100 // If the EHPad isn't a terminator, then we can insert a load in this block 1101 // that will dominate all uses. 1102 SpillSlot = new AllocaInst(PN->getType(), DL->getAllocaAddrSpace(), nullptr, 1103 Twine(PN->getName(), ".wineh.spillslot"), 1104 &F.getEntryBlock().front()); 1105 Value *V = new LoadInst(PN->getType(), SpillSlot, 1106 Twine(PN->getName(), ".wineh.reload"), 1107 &*PHIBlock->getFirstInsertionPt()); 1108 PN->replaceAllUsesWith(V); 1109 return SpillSlot; 1110 } 1111 1112 // Otherwise, we have a PHI on a terminator EHPad, and we give up and insert 1113 // loads of the slot before every use. 1114 DenseMap<BasicBlock *, Value *> Loads; 1115 for (Value::use_iterator UI = PN->use_begin(), UE = PN->use_end(); 1116 UI != UE;) { 1117 Use &U = *UI++; 1118 auto *UsingInst = cast<Instruction>(U.getUser()); 1119 if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) { 1120 // Use is on an EH pad phi. Leave it alone; we'll insert loads and 1121 // stores for it separately. 1122 continue; 1123 } 1124 replaceUseWithLoad(PN, U, SpillSlot, Loads, F); 1125 } 1126 return SpillSlot; 1127 } 1128 1129 // TODO: improve store placement. Inserting at def is probably good, but need 1130 // to be careful not to introduce interfering stores (needs liveness analysis). 1131 // TODO: identify related phi nodes that can share spill slots, and share them 1132 // (also needs liveness). 1133 void WinEHPrepare::insertPHIStores(PHINode *OriginalPHI, 1134 AllocaInst *SpillSlot) { 1135 // Use a worklist of (Block, Value) pairs -- the given Value needs to be 1136 // stored to the spill slot by the end of the given Block. 1137 SmallVector<std::pair<BasicBlock *, Value *>, 4> Worklist; 1138 1139 Worklist.push_back({OriginalPHI->getParent(), OriginalPHI}); 1140 1141 while (!Worklist.empty()) { 1142 BasicBlock *EHBlock; 1143 Value *InVal; 1144 std::tie(EHBlock, InVal) = Worklist.pop_back_val(); 1145 1146 PHINode *PN = dyn_cast<PHINode>(InVal); 1147 if (PN && PN->getParent() == EHBlock) { 1148 // The value is defined by another PHI we need to remove, with no room to 1149 // insert a store after the PHI, so each predecessor needs to store its 1150 // incoming value. 1151 for (unsigned i = 0, e = PN->getNumIncomingValues(); i < e; ++i) { 1152 Value *PredVal = PN->getIncomingValue(i); 1153 1154 // Undef can safely be skipped. 1155 if (isa<UndefValue>(PredVal)) 1156 continue; 1157 1158 insertPHIStore(PN->getIncomingBlock(i), PredVal, SpillSlot, Worklist); 1159 } 1160 } else { 1161 // We need to store InVal, which dominates EHBlock, but can't put a store 1162 // in EHBlock, so need to put stores in each predecessor. 1163 for (BasicBlock *PredBlock : predecessors(EHBlock)) { 1164 insertPHIStore(PredBlock, InVal, SpillSlot, Worklist); 1165 } 1166 } 1167 } 1168 } 1169 1170 void WinEHPrepare::insertPHIStore( 1171 BasicBlock *PredBlock, Value *PredVal, AllocaInst *SpillSlot, 1172 SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist) { 1173 1174 if (PredBlock->isEHPad() && PredBlock->getFirstNonPHI()->isTerminator()) { 1175 // Pred is unsplittable, so we need to queue it on the worklist. 1176 Worklist.push_back({PredBlock, PredVal}); 1177 return; 1178 } 1179 1180 // Otherwise, insert the store at the end of the basic block. 1181 new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator()); 1182 } 1183 1184 void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot, 1185 DenseMap<BasicBlock *, Value *> &Loads, 1186 Function &F) { 1187 // Lazilly create the spill slot. 1188 if (!SpillSlot) 1189 SpillSlot = new AllocaInst(V->getType(), DL->getAllocaAddrSpace(), nullptr, 1190 Twine(V->getName(), ".wineh.spillslot"), 1191 &F.getEntryBlock().front()); 1192 1193 auto *UsingInst = cast<Instruction>(U.getUser()); 1194 if (auto *UsingPHI = dyn_cast<PHINode>(UsingInst)) { 1195 // If this is a PHI node, we can't insert a load of the value before 1196 // the use. Instead insert the load in the predecessor block 1197 // corresponding to the incoming value. 1198 // 1199 // Note that if there are multiple edges from a basic block to this 1200 // PHI node that we cannot have multiple loads. The problem is that 1201 // the resulting PHI node will have multiple values (from each load) 1202 // coming in from the same block, which is illegal SSA form. 1203 // For this reason, we keep track of and reuse loads we insert. 1204 BasicBlock *IncomingBlock = UsingPHI->getIncomingBlock(U); 1205 if (auto *CatchRet = 1206 dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) { 1207 // Putting a load above a catchret and use on the phi would still leave 1208 // a cross-funclet def/use. We need to split the edge, change the 1209 // catchret to target the new block, and put the load there. 1210 BasicBlock *PHIBlock = UsingInst->getParent(); 1211 BasicBlock *NewBlock = SplitEdge(IncomingBlock, PHIBlock); 1212 // SplitEdge gives us: 1213 // IncomingBlock: 1214 // ... 1215 // br label %NewBlock 1216 // NewBlock: 1217 // catchret label %PHIBlock 1218 // But we need: 1219 // IncomingBlock: 1220 // ... 1221 // catchret label %NewBlock 1222 // NewBlock: 1223 // br label %PHIBlock 1224 // So move the terminators to each others' blocks and swap their 1225 // successors. 1226 BranchInst *Goto = cast<BranchInst>(IncomingBlock->getTerminator()); 1227 Goto->removeFromParent(); 1228 CatchRet->removeFromParent(); 1229 IncomingBlock->getInstList().push_back(CatchRet); 1230 NewBlock->getInstList().push_back(Goto); 1231 Goto->setSuccessor(0, PHIBlock); 1232 CatchRet->setSuccessor(NewBlock); 1233 // Update the color mapping for the newly split edge. 1234 // Grab a reference to the ColorVector to be inserted before getting the 1235 // reference to the vector we are copying because inserting the new 1236 // element in BlockColors might cause the map to be reallocated. 1237 ColorVector &ColorsForNewBlock = BlockColors[NewBlock]; 1238 ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock]; 1239 ColorsForNewBlock = ColorsForPHIBlock; 1240 for (BasicBlock *FuncletPad : ColorsForPHIBlock) 1241 FuncletBlocks[FuncletPad].push_back(NewBlock); 1242 // Treat the new block as incoming for load insertion. 1243 IncomingBlock = NewBlock; 1244 } 1245 Value *&Load = Loads[IncomingBlock]; 1246 // Insert the load into the predecessor block 1247 if (!Load) 1248 Load = new LoadInst(V->getType(), SpillSlot, 1249 Twine(V->getName(), ".wineh.reload"), 1250 /*isVolatile=*/false, IncomingBlock->getTerminator()); 1251 1252 U.set(Load); 1253 } else { 1254 // Reload right before the old use. 1255 auto *Load = new LoadInst(V->getType(), SpillSlot, 1256 Twine(V->getName(), ".wineh.reload"), 1257 /*isVolatile=*/false, UsingInst); 1258 U.set(Load); 1259 } 1260 } 1261 1262 void WinEHFuncInfo::addIPToStateRange(const InvokeInst *II, 1263 MCSymbol *InvokeBegin, 1264 MCSymbol *InvokeEnd) { 1265 assert(InvokeStateMap.count(II) && 1266 "should get invoke with precomputed state"); 1267 LabelToStateMap[InvokeBegin] = std::make_pair(InvokeStateMap[II], InvokeEnd); 1268 } 1269 1270 WinEHFuncInfo::WinEHFuncInfo() {} 1271