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