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