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