diff --git a/llvm/lib/CodeGen/MachineFunctionSplitter.cpp b/llvm/lib/CodeGen/MachineFunctionSplitter.cpp --- a/llvm/lib/CodeGen/MachineFunctionSplitter.cpp +++ b/llvm/lib/CodeGen/MachineFunctionSplitter.cpp @@ -23,6 +23,7 @@ // https://groups.google.com/d/msg/llvm-dev/RUegaMg-iqc/wFAVxa6fCgAJ //===----------------------------------------------------------------------===// +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/CodeGen/BasicBlockSectionUtils.h" @@ -77,7 +78,7 @@ }; } // end anonymous namespace -static bool isColdBlock(MachineBasicBlock &MBB, +static bool isColdBlock(const MachineBasicBlock &MBB, const MachineBlockFrequencyInfo *MBFI, ProfileSummaryInfo *PSI) { Optional Count = MBFI->getBlockProfileCount(&MBB); @@ -121,16 +122,28 @@ auto *MBFI = &getAnalysis(); auto *PSI = &getAnalysis().getPSI(); + SmallVector LandingPads; for (auto &MBB : MF) { - // FIXME: We retain the entry block and conservatively keep all landing pad - // blocks as part of the original function. Once D73739 is submitted, we can - // improve the handling of ehpads. - if ((MBB.pred_empty() || MBB.isEHPad())) + if (MBB.isEntryBlock()) continue; - if (isColdBlock(MBB, MBFI, PSI)) + + if (MBB.isEHPad()) + LandingPads.push_back(&MBB); + else if (isColdBlock(MBB, MBFI, PSI)) MBB.setSectionID(MBBSectionID::ColdSectionID); } + // We only split out eh pads if all of them are cold. + bool HasHotLandingPads = false; + for (const MachineBasicBlock *LP : LandingPads) { + if (!isColdBlock(*LP, MBFI, PSI)) + HasHotLandingPads = true; + } + if (!HasHotLandingPads) { + for (MachineBasicBlock *LP : LandingPads) + LP->setSectionID(MBBSectionID::ColdSectionID); + } + auto Comparator = [](const MachineBasicBlock &X, const MachineBasicBlock &Y) { return X.getSectionID().Type < Y.getSectionID().Type; }; diff --git a/llvm/test/CodeGen/X86/machine-function-splitter.ll b/llvm/test/CodeGen/X86/machine-function-splitter.ll --- a/llvm/test/CodeGen/X86/machine-function-splitter.ll +++ b/llvm/test/CodeGen/X86/machine-function-splitter.ll @@ -150,12 +150,12 @@ } define i32 @foo7(i1 zeroext %0) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !prof !14 { -;; Check that cold ehpads are not split out. +;; Check that a single cold ehpad is split out. ; MFS-DEFAULTS-LABEL: foo7 ; MFS-DEFAULTS: .section .text.split.foo7,"ax",@progbits ; MFS-DEFAULTS-NEXT: foo7.cold: -; MFS-DEFAULTS-NOT: callq _Unwind_Resume ; MFS-DEFAULTS: callq baz +; MFS-DEFAULTS: callq _Unwind_Resume@PLT entry: invoke void @_Z1fv() to label %try.cont unwind label %lpad @@ -182,6 +182,47 @@ ret i32 %7 } +define i32 @foo8(i1 zeroext %0) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !prof !14 { +;; Check that all ehpads are treated as hot if one of them is hot. +; MFS-DEFAULTS-LABEL: foo8 +; MFS-DEFAULTS: callq _Unwind_Resume@PLT +; MFS-DEFAULTS: callq _Unwind_Resume@PLT +; MFS-DEFAULTS: .section .text.split.foo8,"ax",@progbits +; MFS-DEFAULTS-NEXT: foo8.cold: +; MFS-DEFAULTS: callq baz +entry: + invoke void @_Z1fv() + to label %try.cont unwind label %lpad1 + +lpad1: + %1 = landingpad { i8*, i32 } + cleanup + catch i8* bitcast (i8** @_ZTIi to i8*) + resume { i8*, i32 } %1 + +try.cont: + br i1 %0, label %hot, label %cold, !prof !17 + +hot: + %2 = call i32 @bar() + invoke void @_Z1fv() + to label %exit unwind label %lpad2, !prof !21 + +lpad2: + %3 = landingpad { i8*, i32 } + cleanup + catch i8* bitcast (i8** @_ZTIi to i8*) + resume { i8*, i32 } %3 + +cold: + %4 = call i32 @baz() + br label %exit + +exit: + %5 = tail call i32 @qux() + ret i32 %5 +} + declare i32 @bar() declare i32 @baz() declare i32 @bam()