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