DenseMap<const MachineBasicBlock *, int> llvm::getEHScopeMembership(const MachineFunction &MF) { DenseMap<const MachineBasicBlock *, int> EHScopeMembership; // We don't have anything to do if there aren't any EH pads. if (!MF.hasEHScopes()) return EHScopeMembership; int EntryBBNumber = MF.front().getNumber(); bool IsSEH = isAsynchronousEHPersonality( classifyEHPersonality(MF.getFunction().getPersonalityFn())); const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); SmallVector<const MachineBasicBlock *, 16> EHScopeBlocks; SmallVector<const MachineBasicBlock *, 16> UnreachableBlocks; SmallVector<const MachineBasicBlock *, 16> SEHCatchPads; SmallVector<std::pair<const MachineBasicBlock *, int>, 16> CatchRetSuccessors; for (const MachineBasicBlock &MBB : MF) { if (MBB.isEHScopeEntry()) { EHScopeBlocks.push_back(&MBB); } else if (IsSEH && MBB.isEHPad()) { SEHCatchPads.push_back(&MBB); } else if (MBB.pred_empty()) { UnreachableBlocks.push_back(&MBB); } MachineBasicBlock::const_iterator MBBI = MBB.getFirstTerminator(); // CatchPads are not scopes for SEH so do not consider CatchRet to // transfer control to another scope. if (MBBI == MBB.end() || MBBI->getOpcode() != TII->getCatchReturnOpcode()) continue; // FIXME: SEH CatchPads are not necessarily in the parent function: // they could be inside a finally block. const MachineBasicBlock *Successor = MBBI->getOperand(0).getMBB(); const MachineBasicBlock *SuccessorColor = MBBI->getOperand(1).getMBB(); CatchRetSuccessors.push_back( {Successor, IsSEH ? EntryBBNumber : SuccessorColor->getNumber()}); } // We don't have anything to do if there aren't any EH pads. if (EHScopeBlocks.empty()) return EHScopeMembership; // Identify all the basic blocks reachable from the function entry. collectEHScopeMembers(EHScopeMembership, EntryBBNumber, &MF.front()); // All blocks not part of a scope are in the parent function. for (const MachineBasicBlock *MBB : UnreachableBlocks) collectEHScopeMembers(EHScopeMembership, EntryBBNumber, MBB); // Next, identify all the blocks inside the scopes. for (const MachineBasicBlock *MBB : EHScopeBlocks) collectEHScopeMembers(EHScopeMembership, MBB->getNumber(), MBB); // SEH CatchPads aren't really scopes, handle them separately. for (const MachineBasicBlock *MBB : SEHCatchPads) collectEHScopeMembers(EHScopeMembership, EntryBBNumber, MBB); // Finally, identify all the targets of a catchret. for (std::pair<const MachineBasicBlock *, int> CatchRetPair : CatchRetSuccessors) collectEHScopeMembers(EHScopeMembership, CatchRetPair.second, CatchRetPair.first); return EHScopeMembership; }