Index: llvm/trunk/lib/CodeGen/Analysis.cpp =================================================================== --- llvm/trunk/lib/CodeGen/Analysis.cpp +++ llvm/trunk/lib/CodeGen/Analysis.cpp @@ -629,9 +629,9 @@ return true; } -static void -collectEHScopeMembers(DenseMap &ScopeMembership, - int Scope, const MachineBasicBlock *MBB) { +static void collectEHScopeMembers( + DenseMap &EHScopeMembership, int EHScope, + const MachineBasicBlock *MBB) { SmallVector Worklist = {MBB}; while (!Worklist.empty()) { const MachineBasicBlock *Visiting = Worklist.pop_back_val(); @@ -640,11 +640,11 @@ continue; // Add this MBB to our scope. - auto P = ScopeMembership.insert(std::make_pair(Visiting, Scope)); + auto P = EHScopeMembership.insert(std::make_pair(Visiting, EHScope)); // Don't revisit blocks. if (!P.second) { - assert(P.first->second == Scope && "MBB is part of two scopes!"); + assert(P.first->second == EHScope && "MBB is part of two scopes!"); continue; } @@ -660,24 +660,24 @@ DenseMap llvm::getEHScopeMembership(const MachineFunction &MF) { - DenseMap ScopeMembership; + DenseMap EHScopeMembership; // We don't have anything to do if there aren't any EH pads. if (!MF.hasEHScopes()) - return ScopeMembership; + return EHScopeMembership; int EntryBBNumber = MF.front().getNumber(); bool IsSEH = isAsynchronousEHPersonality( classifyEHPersonality(MF.getFunction().getPersonalityFn())); const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); - SmallVector ScopeBlocks; + SmallVector EHScopeBlocks; SmallVector UnreachableBlocks; SmallVector SEHCatchPads; SmallVector, 16> CatchRetSuccessors; for (const MachineBasicBlock &MBB : MF) { if (MBB.isEHScopeEntry()) { - ScopeBlocks.push_back(&MBB); + EHScopeBlocks.push_back(&MBB); } else if (IsSEH && MBB.isEHPad()) { SEHCatchPads.push_back(&MBB); } else if (MBB.pred_empty()) { @@ -700,24 +700,24 @@ } // We don't have anything to do if there aren't any EH pads. - if (ScopeBlocks.empty()) - return ScopeMembership; + if (EHScopeBlocks.empty()) + return EHScopeMembership; // Identify all the basic blocks reachable from the function entry. - collectEHScopeMembers(ScopeMembership, EntryBBNumber, &MF.front()); + collectEHScopeMembers(EHScopeMembership, EntryBBNumber, &MF.front()); // All blocks not part of a scope are in the parent function. for (const MachineBasicBlock *MBB : UnreachableBlocks) - collectEHScopeMembers(ScopeMembership, EntryBBNumber, MBB); + collectEHScopeMembers(EHScopeMembership, EntryBBNumber, MBB); // Next, identify all the blocks inside the scopes. - for (const MachineBasicBlock *MBB : ScopeBlocks) - collectEHScopeMembers(ScopeMembership, MBB->getNumber(), MBB); + 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(ScopeMembership, EntryBBNumber, MBB); + collectEHScopeMembers(EHScopeMembership, EntryBBNumber, MBB); // Finally, identify all the targets of a catchret. for (std::pair CatchRetPair : CatchRetSuccessors) - collectEHScopeMembers(ScopeMembership, CatchRetPair.second, + collectEHScopeMembers(EHScopeMembership, CatchRetPair.second, CatchRetPair.first); - return ScopeMembership; + return EHScopeMembership; } Index: llvm/trunk/lib/CodeGen/BranchFolding.h =================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.h +++ llvm/trunk/lib/CodeGen/BranchFolding.h @@ -75,7 +75,7 @@ std::vector MergePotentials; SmallPtrSet TriedMerging; - DenseMap FuncletMembership; + DenseMap EHScopeMembership; class SameTailElt { MPIterator MPIter; Index: llvm/trunk/lib/CodeGen/BranchFolding.cpp =================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp @@ -164,7 +164,7 @@ // Remove the block. MF->erase(MBB); - FuncletMembership.erase(MBB); + EHScopeMembership.erase(MBB); if (MLI) MLI->removeBlock(MBB); } @@ -199,8 +199,8 @@ MadeChange |= MBB.CorrectExtraCFGEdges(TBB, FBB, !Cond.empty()); } - // Recalculate funclet membership. - FuncletMembership = getEHScopeMembership(MF); + // Recalculate EH scope membership. + EHScopeMembership = getEHScopeMembership(MF); bool MadeChangeThisIteration = true; while (MadeChangeThisIteration) { @@ -475,11 +475,11 @@ if (UpdateLiveIns) computeAndAddLiveIns(LiveRegs, *NewMBB); - // Add the new block to the funclet. - const auto &FuncletI = FuncletMembership.find(&CurMBB); - if (FuncletI != FuncletMembership.end()) { - auto n = FuncletI->second; - FuncletMembership[NewMBB] = n; + // Add the new block to the EH scope. + const auto &EHScopeI = EHScopeMembership.find(&CurMBB); + if (EHScopeI != EHScopeMembership.end()) { + auto n = EHScopeI->second; + EHScopeMembership[NewMBB] = n; } return NewMBB; @@ -626,7 +626,7 @@ /// SuccBB A common successor of MBB1, MBB2 which are in a canonical form /// relative to SuccBB /// PredBB The layout predecessor of SuccBB, if any. -/// FuncletMembership map from block to funclet #. +/// EHScopeMembership map from block to EH scope #. /// AfterPlacement True if we are merging blocks after layout. Stricter /// thresholds apply to prevent undoing tail-duplication. static bool @@ -635,15 +635,15 @@ MachineBasicBlock::iterator &I1, MachineBasicBlock::iterator &I2, MachineBasicBlock *SuccBB, MachineBasicBlock *PredBB, - DenseMap &FuncletMembership, + DenseMap &EHScopeMembership, bool AfterPlacement) { - // It is never profitable to tail-merge blocks from two different funclets. - if (!FuncletMembership.empty()) { - auto Funclet1 = FuncletMembership.find(MBB1); - assert(Funclet1 != FuncletMembership.end()); - auto Funclet2 = FuncletMembership.find(MBB2); - assert(Funclet2 != FuncletMembership.end()); - if (Funclet1->second != Funclet2->second) + // It is never profitable to tail-merge blocks from two different EH scopes. + if (!EHScopeMembership.empty()) { + auto EHScope1 = EHScopeMembership.find(MBB1); + assert(EHScope1 != EHScopeMembership.end()); + auto EHScope2 = EHScopeMembership.find(MBB2); + assert(EHScope2 != EHScopeMembership.end()); + if (EHScope1->second != EHScope2->second) return false; } @@ -743,7 +743,7 @@ MinCommonTailLength, CommonTailLen, TrialBBI1, TrialBBI2, SuccBB, PredBB, - FuncletMembership, + EHScopeMembership, AfterBlockPlacement)) { if (CommonTailLen > maxCommonTailLength) { SameTails.clear(); @@ -1292,8 +1292,8 @@ // Make sure blocks are numbered in order MF.RenumberBlocks(); - // Renumbering blocks alters funclet membership, recalculate it. - FuncletMembership = getEHScopeMembership(MF); + // Renumbering blocks alters EH scope membership, recalculate it. + EHScopeMembership = getEHScopeMembership(MF); for (MachineFunction::iterator I = std::next(MF.begin()), E = MF.end(); I != E; ) { @@ -1412,14 +1412,14 @@ MachineFunction::iterator FallThrough = MBB->getIterator(); ++FallThrough; - // Make sure MBB and FallThrough belong to the same funclet. - bool SameFunclet = true; - if (!FuncletMembership.empty() && FallThrough != MF.end()) { - auto MBBFunclet = FuncletMembership.find(MBB); - assert(MBBFunclet != FuncletMembership.end()); - auto FallThroughFunclet = FuncletMembership.find(&*FallThrough); - assert(FallThroughFunclet != FuncletMembership.end()); - SameFunclet = MBBFunclet->second == FallThroughFunclet->second; + // Make sure MBB and FallThrough belong to the same EH scope. + bool SameEHScope = true; + if (!EHScopeMembership.empty() && FallThrough != MF.end()) { + auto MBBEHScope = EHScopeMembership.find(MBB); + assert(MBBEHScope != EHScopeMembership.end()); + auto FallThroughEHScope = EHScopeMembership.find(&*FallThrough); + assert(FallThroughEHScope != EHScopeMembership.end()); + SameEHScope = MBBEHScope->second == FallThroughEHScope->second; } // If this block is empty, make everyone use its fall-through, not the block @@ -1427,7 +1427,7 @@ // points to this block. Blocks with their addresses taken shouldn't be // optimized away. if (IsEmptyBlock(MBB) && !MBB->isEHPad() && !MBB->hasAddressTaken() && - SameFunclet) { + SameEHScope) { salvageDebugInfoFromEmptyBlock(TII, *MBB); // Dead block? Leave for cleanup later. if (MBB->pred_empty()) return MadeChange; Index: llvm/trunk/lib/CodeGen/FuncletLayout.cpp =================================================================== --- llvm/trunk/lib/CodeGen/FuncletLayout.cpp +++ llvm/trunk/lib/CodeGen/FuncletLayout.cpp @@ -41,6 +41,9 @@ "Contiguously Lay Out Funclets", false, false) bool FuncletLayout::runOnMachineFunction(MachineFunction &F) { + // Even though this gets information from getEHScopeMembership(), this pass is + // only necessary for funclet-based EH personalities, in which these EH scopes + // are outlined at the end. DenseMap FuncletMembership = getEHScopeMembership(F); if (FuncletMembership.empty())