Index: clang/include/clang/Basic/CodeGenOptions.def =================================================================== --- clang/include/clang/Basic/CodeGenOptions.def +++ clang/include/clang/Basic/CodeGenOptions.def @@ -124,6 +124,7 @@ ///< linker. CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants. CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled. +CODEGENOPT(SplitColdCode , 1, 0) ///< Set when -fsplit-cold-code is enabled. CODEGENOPT(MSVolatile , 1, 0) ///< Set when /volatile:ms is enabled. CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled. CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is Index: clang/include/clang/Basic/DiagnosticFrontendKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -258,6 +258,10 @@ "as the %select{aliasee|resolver}2">, InGroup; +def warn_fe_ignored_opt_split_cold_code : Warning< + "'%0' has no effect when %select{optimizing for minimum size|optimizations are disabled}1">, + InGroup; + let CategoryName = "Instrumentation Issue" in { def warn_profile_data_out_of_date : Warning< "profile data may be out of date: of %0 function%s0, %1 %plural{1:has|:have}1" Index: clang/include/clang/Driver/CC1Options.td =================================================================== --- clang/include/clang/Driver/CC1Options.td +++ clang/include/clang/Driver/CC1Options.td @@ -227,6 +227,10 @@ HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">; def fmerge_functions : Flag<["-"], "fmerge-functions">, HelpText<"Permit merging of identical functions when optimizing.">; +def fsplit_cold_code : Flag<["-"], "fsplit-cold-code">, + HelpText<"Permit splitting of cold code when optimizing (off by default).">; +def fno_split_cold_code : Flag<["-"], "fno-split-cold-code">, + HelpText<"Disable splitting of cold code when optimizing.">; def femit_coverage_notes : Flag<["-"], "femit-coverage-notes">, HelpText<"Emit a gcov coverage notes file when compiling.">; def femit_coverage_data: Flag<["-"], "femit-coverage-data">, Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -58,6 +58,7 @@ #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MD5.h" +#include "llvm/Transforms/IPO/HotColdSplitting.h" using namespace clang; using namespace CodeGen; @@ -1345,6 +1346,9 @@ if (D->hasAttr()) B.addAttribute(llvm::Attribute::MinSize); + + if (CodeGenOpts.SplitColdCode) + B.addAttribute(llvm::getHotColdSplittingAttrKind()); } F->addAttributes(llvm::AttributeList::FunctionIndex, B); Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -1333,6 +1333,17 @@ Opts.PassPlugins = Args.getAllArgValues(OPT_fpass_plugin_EQ); + // -f[no-]split-cold-code + // This may only be enabled when optimizing, and when small code size + // increases are tolerable. + Opts.SplitColdCode = + (Opts.OptimizationLevel > 0) && (Opts.OptimizeSize != 2) && + Args.hasFlag(OPT_fsplit_cold_code, OPT_fno_split_cold_code, false); + if (Arg *A = Args.getLastArg(OPT_fsplit_cold_code)) + if (!Opts.SplitColdCode) + Diags.Report(diag::warn_fe_ignored_opt_split_cold_code) + << A->getAsString(Args) << (Opts.OptimizeSize != 2); + return Success; } Index: clang/test/CodeGen/split-cold-code.c =================================================================== --- /dev/null +++ clang/test/CodeGen/split-cold-code.c @@ -0,0 +1,72 @@ +// === Old PM === +// No splitting at -O0. +// RUN: %clang_cc1 -O0 -fsplit-cold-code -mllvm -debug-pass=Structure \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=NO-SPLIT %s +// +// No splitting at -Oz. +// RUN: %clang_cc1 -Oz -fsplit-cold-code -mllvm -debug-pass=Structure \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=NO-SPLIT %s +// +// No splitting by default, even at -O3. +// RUN: %clang_cc1 -O3 -mllvm -debug-pass=Structure \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=NO-SPLIT %s +// +// No splitting when it's explicitly disabled. +// RUN: %clang_cc1 -O3 -fno-split-cold-code -mllvm -debug-pass=Structure \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=NO-SPLIT %s +// +// Split at -O1. +// RUN: %clang_cc1 -O1 -fsplit-cold-code -mllvm -debug-pass=Structure \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=SPLIT %s +// +// Split at -Os. +// RUN: %clang_cc1 -Os -fsplit-cold-code -mllvm -debug-pass=Structure \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=SPLIT %s +// +// Split at -O2. +// RUN: %clang_cc1 -O2 -fsplit-cold-code -mllvm -debug-pass=Structure \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=SPLIT %s +// +// Split at -O3. +// RUN: %clang_cc1 -O3 -fsplit-cold-code -mllvm -debug-pass=Structure \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=SPLIT %s + +// === New PM (ditto) === +// No splitting at -O0. +// RUN: %clang_cc1 -O0 -fsplit-cold-code -fexperimental-new-pass-manager -fdebug-pass-manager \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=NO-SPLIT %s +// +// No splitting at -Oz. +// RUN: %clang_cc1 -Oz -fsplit-cold-code -fexperimental-new-pass-manager -fdebug-pass-manager \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=NO-SPLIT %s +// +// No splitting by default, even at -O3. +// RUN: %clang_cc1 -O3 -fexperimental-new-pass-manager -fdebug-pass-manager \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=NO-SPLIT %s +// +// No splitting when it's explicitly disabled. +// RUN: %clang_cc1 -O3 -fno-split-cold-code -fexperimental-new-pass-manager -fdebug-pass-manager \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=NO-SPLIT %s +// +// Split at -O1. +// RUN: %clang_cc1 -O1 -fsplit-cold-code -fexperimental-new-pass-manager -fdebug-pass-manager \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=SPLIT %s +// +// Split at -Os. +// RUN: %clang_cc1 -Os -fsplit-cold-code -fexperimental-new-pass-manager -fdebug-pass-manager \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=SPLIT %s +// +// Split at -O2. +// RUN: %clang_cc1 -O2 -fsplit-cold-code -fexperimental-new-pass-manager -fdebug-pass-manager \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=SPLIT %s +// +// Split at -O3. +// RUN: %clang_cc1 -O3 -fsplit-cold-code -fexperimental-new-pass-manager -fdebug-pass-manager \ +// RUN: -emit-llvm -o - %s 2>&1 | FileCheck --check-prefix=SPLIT %s + +// NO-SPLIT-NOT: "hot-cold-split" + +// SPLIT: "hot-cold-split" + +__attribute__((used)) +void foo() {} Index: clang/test/Frontend/split-cold-code.c =================================================================== --- /dev/null +++ clang/test/Frontend/split-cold-code.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -O0 -fsplit-cold-code %s 2>&1 | FileCheck %s --check-prefix=O0 +// O0: warning: '-fsplit-cold-code' has no effect when optimizations are disabled + +// RUN: %clang_cc1 -Oz -fsplit-cold-code %s 2>&1 | FileCheck %s --check-prefix=Oz +// Oz: warning: '-fsplit-cold-code' has no effect when optimizing for minimum size Index: llvm/include/llvm/Transforms/IPO/HotColdSplitting.h =================================================================== --- llvm/include/llvm/Transforms/IPO/HotColdSplitting.h +++ llvm/include/llvm/Transforms/IPO/HotColdSplitting.h @@ -12,12 +12,16 @@ #ifndef LLVM_TRANSFORMS_IPO_HOTCOLDSPLITTING_H #define LLVM_TRANSFORMS_IPO_HOTCOLDSPLITTING_H +#include "llvm/ADT/StringRef.h" #include "llvm/IR/PassManager.h" namespace llvm { class Module; +/// Get the attribute kind used to mark functions for hot/cold splitting. +StringRef getHotColdSplittingAttrKind(); + /// Pass to outline cold regions. class HotColdSplittingPass : public PassInfoMixin { public: Index: llvm/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/lib/Passes/PassBuilder.cpp +++ llvm/lib/Passes/PassBuilder.cpp @@ -211,7 +211,6 @@ EnableCHR("enable-chr-npm", cl::init(true), cl::Hidden, cl::desc("Enable control height reduction optimization (CHR)")); -extern cl::opt EnableHotColdSplit; extern cl::opt EnableOrderFileInstrumentation; extern cl::opt FlattenedProfileUsed; @@ -899,7 +898,7 @@ // Split out cold code. Splitting is done late to avoid hiding context from // other optimizations and inadvertently regressing performance. The tradeoff // is that this has a higher code size cost than splitting early. - if (EnableHotColdSplit && !LTOPreLink) + if (!LTOPreLink) MPM.addPass(HotColdSplittingPass()); // LoopSink pass sinks instructions hoisted by LICM, which serves as a @@ -1250,8 +1249,7 @@ // Enable splitting late in the FullLTO post-link pipeline. This is done in // the same stage in the old pass manager (\ref addLateLTOOptimizationPasses). - if (EnableHotColdSplit) - MPM.addPass(HotColdSplittingPass()); + MPM.addPass(HotColdSplittingPass()); // Add late LTO optimization passes. // Delete basic blocks, which optimization passes may have killed. Index: llvm/lib/Transforms/IPO/HotColdSplitting.cpp =================================================================== --- llvm/lib/Transforms/IPO/HotColdSplitting.cpp +++ llvm/lib/Transforms/IPO/HotColdSplitting.cpp @@ -235,6 +235,9 @@ // Returns false if the function should not be considered for hot-cold split // optimization. bool HotColdSplitting::shouldOutlineFrom(const Function &F) const { + if (!F.hasFnAttribute(getHotColdSplittingAttrKind())) + return false; + if (F.hasFnAttribute(Attribute::AlwaysInline)) return false; @@ -802,3 +805,7 @@ ModulePass *llvm::createHotColdSplittingPass() { return new HotColdSplittingLegacyPass(); } + +StringRef llvm::getHotColdSplittingAttrKind() { + return "hot-cold-split"; +} Index: llvm/lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -107,9 +107,6 @@ EnablePerformThinLTO("perform-thinlto", cl::init(false), cl::Hidden, cl::desc("Enable performing ThinLTO.")); -cl::opt EnableHotColdSplit("hot-cold-split", cl::init(false), cl::Hidden, - cl::desc("Enable hot-cold splitting pass")); - static cl::opt UseLoopVersioningLICM( "enable-loop-versioning-licm", cl::init(false), cl::Hidden, cl::desc("Enable the experimental Loop Versioning LICM pass")); @@ -756,7 +753,7 @@ // See comment in the new PM for justification of scheduling splitting at // this stage (\ref buildModuleSimplificationPipeline). - if (EnableHotColdSplit && !(PrepareForLTO || PrepareForThinLTO)) + if (!(PrepareForLTO || PrepareForThinLTO)) MPM.add(createHotColdSplittingPass()); if (MergeFunctions) @@ -956,8 +953,7 @@ legacy::PassManagerBase &PM) { // See comment in the new PM for justification of scheduling splitting at // this stage (\ref buildLTODefaultPipeline). - if (EnableHotColdSplit) - PM.add(createHotColdSplittingPass()); + PM.add(createHotColdSplittingPass()); // Delete basic blocks, which optimization passes may have killed. PM.add(createCFGSimplificationPass()); Index: llvm/test/Other/X86/lto-hot-cold-split.ll =================================================================== --- llvm/test/Other/X86/lto-hot-cold-split.ll +++ llvm/test/Other/X86/lto-hot-cold-split.ll @@ -1,6 +1,6 @@ ; RUN: opt -module-summary %s -o %t.bc -; RUN: llvm-lto -hot-cold-split=true -thinlto-action=run %t.bc -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=OLDPM-ANYLTO-POSTLINK-Os -; RUN: llvm-lto -hot-cold-split=true %t.bc -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=OLDPM-ANYLTO-POSTLINK-Os +; RUN: llvm-lto -thinlto-action=run %t.bc -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=OLDPM-ANYLTO-POSTLINK-Os +; RUN: llvm-lto %t.bc -debug-pass=Structure 2>&1 | FileCheck %s -check-prefix=OLDPM-ANYLTO-POSTLINK-Os ; REQUIRES: asserts Index: llvm/test/Other/new-pm-defaults.ll =================================================================== --- llvm/test/Other/new-pm-defaults.ll +++ llvm/test/Other/new-pm-defaults.ll @@ -9,19 +9,24 @@ ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes='default' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O1 +; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O1 \ +; RUN: --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes='default' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2 +; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2 \ +; RUN: --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes='default' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 +; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \ +; RUN: --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes='default' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-Os +; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-Os \ +; RUN: --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes='default' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-Oz +; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-Oz \ +; RUN: --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes='lto-pre-link' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O2 @@ -30,37 +35,39 @@ ; RUN: -passes-ep-peephole='no-op-function' \ ; RUN: -passes='default' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \ -; RUN: --check-prefix=CHECK-EP-PEEPHOLE +; RUN: --check-prefix=CHECK-EP-PEEPHOLE --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes-ep-late-loop-optimizations='no-op-loop' \ ; RUN: -passes='default' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \ -; RUN: --check-prefix=CHECK-EP-LOOP-LATE +; RUN: --check-prefix=CHECK-EP-LOOP-LATE --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes-ep-loop-optimizer-end='no-op-loop' \ ; RUN: -passes='default' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \ -; RUN: --check-prefix=CHECK-EP-LOOP-END +; RUN: --check-prefix=CHECK-EP-LOOP-END --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes-ep-scalar-optimizer-late='no-op-function' \ ; RUN: -passes='default' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \ -; RUN: --check-prefix=CHECK-EP-SCALAR-LATE +; RUN: --check-prefix=CHECK-EP-SCALAR-LATE --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes-ep-cgscc-optimizer-late='no-op-cgscc' \ ; RUN: -passes='default' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \ -; RUN: --check-prefix=CHECK-EP-CGSCC-LATE +; RUN: --check-prefix=CHECK-EP-CGSCC-LATE --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes-ep-vectorizer-start='no-op-function' \ ; RUN: -passes='default' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \ -; RUN: --check-prefix=CHECK-EP-VECTORIZER-START +; RUN: --check-prefix=CHECK-EP-VECTORIZER-START \ +; RUN: --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes-ep-pipeline-start='no-op-module' \ ; RUN: -passes='default' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \ -; RUN: --check-prefix=CHECK-EP-PIPELINE-START +; RUN: --check-prefix=CHECK-EP-PIPELINE-START \ +; RUN: --check-prefix=CHECK-O-NOPRELINK ; RUN: opt -disable-verify -debug-pass-manager \ ; RUN: -passes-ep-pipeline-start='no-op-module' \ ; RUN: -passes='lto-pre-link' -S %s 2>&1 \ @@ -70,7 +77,8 @@ ; RUN: -passes-ep-optimizer-last='no-op-function' \ ; RUN: -passes='default' -S %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O --check-prefix=CHECK-O3 \ -; RUN: --check-prefix=CHECK-EP-OPTIMIZER-LAST +; RUN: --check-prefix=CHECK-EP-OPTIMIZER-LAST \ +; RUN: --check-prefix=CHECK-O-NOPRELINK ; CHECK-O: Running analysis: PassInstrumentationAnalysis ; CHECK-O-NEXT: Starting llvm::Module pass manager run. @@ -225,6 +233,7 @@ ; CHECK-O-NEXT: Running pass: EliminateAvailableExternallyPass ; CHECK-O-NEXT: Running pass: ReversePostOrderFunctionAttrsPass ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}GlobalsAA +; CHECK-O-NOPRELINK-NEXT: Running pass: HotColdSplittingPass ; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> ; CHECK-O-NEXT: Starting llvm::Function pass manager run. ; CHECK-O-NEXT: Running pass: Float2IntPass Index: llvm/test/Other/new-pm-lto-defaults.ll =================================================================== --- llvm/test/Other/new-pm-lto-defaults.ll +++ llvm/test/Other/new-pm-lto-defaults.ll @@ -90,6 +90,7 @@ ; CHECK-O2-NEXT: Running analysis: DemandedBitsAnalysis ; CHECK-O2-NEXT: Running pass: CrossDSOCFIPass ; CHECK-O2-NEXT: Running pass: LowerTypeTestsPass +; CHECK-O2-NEXT: Running pass: HotColdSplittingPass ; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}SimplifyCFGPass> ; CHECK-O2-NEXT: Running pass: EliminateAvailableExternallyPass ; CHECK-O2-NEXT: Running pass: GlobalDCEPass Index: llvm/test/Other/new-pm-pgo.ll =================================================================== --- llvm/test/Other/new-pm-pgo.ll +++ llvm/test/Other/new-pm-pgo.ll @@ -1,7 +1,6 @@ ; RUN: opt -debug-pass-manager -passes='default' -pgo-kind=pgo-instr-gen-pipeline -profile-file='temp' %s 2>&1 |FileCheck %s --check-prefixes=GEN ; RUN: llvm-profdata merge %S/Inputs/new-pm-pgo.proftext -o %t.profdata ; RUN: opt -debug-pass-manager -passes='default' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t.profdata' %s 2>&1 |FileCheck %s --check-prefixes=USE -; RUN: opt -debug-pass-manager -passes='default' -hot-cold-split -pgo-kind=pgo-instr-use-pipeline -profile-file='%t.profdata' %s 2>&1 |FileCheck %s --check-prefixes=USE --check-prefixes=SPLIT ; RUN: opt -debug-pass-manager -passes='default' -pgo-kind=pgo-sample-use-pipeline -profile-file='%S/Inputs/new-pm-pgo.prof' %s 2>&1 \ ; RUN: |FileCheck %s --check-prefixes=SAMPLE_USE,SAMPLE_USE_O ; RUN: opt -debug-pass-manager -passes='thinlto-pre-link' -pgo-kind=pgo-sample-use-pipeline -profile-file='%S/Inputs/new-pm-pgo.prof' %s 2>&1 \ @@ -26,7 +25,7 @@ ; SAMPLE_USE_POST_LINK-NOT: Running pass: GlobalOptPass ; SAMPLE_USE_POST_LINK: Running pass: PGOIndirectCallPromotion ; SAMPLE_GEN: Running pass: ModuleToFunctionPassAdaptor<{{.*}}AddDiscriminatorsPass{{.*}}> -; SPLIT: Running pass: HotColdSplittingPass +; USE: Running pass: HotColdSplittingPass define void @foo() { ret void Index: llvm/test/Other/new-pm-thinlto-defaults.ll =================================================================== --- llvm/test/Other/new-pm-thinlto-defaults.ll +++ llvm/test/Other/new-pm-thinlto-defaults.ll @@ -200,6 +200,7 @@ ; CHECK-POSTLINK-O-NEXT: Running pass: EliminateAvailableExternallyPass ; CHECK-POSTLINK-O-NEXT: Running pass: ReversePostOrderFunctionAttrsPass ; CHECK-POSTLINK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}GlobalsAA +; CHECK-POSTLINK-O-NEXT: Running pass: HotColdSplittingPass ; CHECK-POSTLINK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> ; CHECK-POSTLINK-O-NEXT: Starting llvm::Function pass manager run. ; CHECK-POSTLINK-O-NEXT: Running pass: Float2IntPass Index: llvm/test/Other/opt-O2-pipeline.ll =================================================================== --- llvm/test/Other/opt-O2-pipeline.ll +++ llvm/test/Other/opt-O2-pipeline.ll @@ -258,6 +258,8 @@ ; CHECK-NEXT: Strip Unused Function Prototypes ; CHECK-NEXT: Dead Global Elimination ; CHECK-NEXT: Merge Duplicate Global Constants +; CHECK-NEXT: Hot Cold Splitting +; CHECK-NEXT: Unnamed pass: implement Pass::getPassName() ; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Natural Loop Information Index: llvm/test/Other/opt-O3-pipeline.ll =================================================================== --- llvm/test/Other/opt-O3-pipeline.ll +++ llvm/test/Other/opt-O3-pipeline.ll @@ -263,6 +263,8 @@ ; CHECK-NEXT: Strip Unused Function Prototypes ; CHECK-NEXT: Dead Global Elimination ; CHECK-NEXT: Merge Duplicate Global Constants +; CHECK-NEXT: Hot Cold Splitting +; CHECK-NEXT: Unnamed pass: implement Pass::getPassName() ; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Natural Loop Information Index: llvm/test/Other/opt-Os-pipeline.ll =================================================================== --- llvm/test/Other/opt-Os-pipeline.ll +++ llvm/test/Other/opt-Os-pipeline.ll @@ -245,6 +245,8 @@ ; CHECK-NEXT: Strip Unused Function Prototypes ; CHECK-NEXT: Dead Global Elimination ; CHECK-NEXT: Merge Duplicate Global Constants +; CHECK-NEXT: Hot Cold Splitting +; CHECK-NEXT: Unnamed pass: implement Pass::getPassName() ; CHECK-NEXT: FunctionPass Manager ; CHECK-NEXT: Dominator Tree Construction ; CHECK-NEXT: Natural Loop Information Index: llvm/test/Other/opt-hot-cold-split.ll =================================================================== --- llvm/test/Other/opt-hot-cold-split.ll +++ llvm/test/Other/opt-hot-cold-split.ll @@ -1,8 +1,8 @@ -; RUN: opt -mtriple=x86_64-- -Os -hot-cold-split=true -debug-pass=Structure < %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=DEFAULT-Os -; RUN: opt -mtriple=x86_64-- -Os -hot-cold-split=true -passes='lto-pre-link' -debug-pass-manager < %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=LTO-PRELINK-Os -; RUN: opt -mtriple=x86_64-- -Os -hot-cold-split=true -passes='thinlto-pre-link' -debug-pass-manager < %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=THINLTO-PRELINK-Os -; RUN: opt -mtriple=x86_64-- -Os -hot-cold-split=true -passes='lto' -debug-pass-manager < %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=LTO-POSTLINK-Os -; RUN: opt -mtriple=x86_64-- -Os -hot-cold-split=true -passes='thinlto' -debug-pass-manager < %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=THINLTO-POSTLINK-Os +; RUN: opt -mtriple=x86_64-- -Os -debug-pass=Structure < %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=DEFAULT-Os +; RUN: opt -mtriple=x86_64-- -Os -passes='lto-pre-link' -debug-pass-manager < %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=LTO-PRELINK-Os +; RUN: opt -mtriple=x86_64-- -Os -passes='thinlto-pre-link' -debug-pass-manager < %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=THINLTO-PRELINK-Os +; RUN: opt -mtriple=x86_64-- -Os -passes='lto' -debug-pass-manager < %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=LTO-POSTLINK-Os +; RUN: opt -mtriple=x86_64-- -Os -passes='thinlto' -debug-pass-manager < %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=THINLTO-POSTLINK-Os ; REQUIRES: asserts Index: llvm/test/Other/pass-pipelines.ll =================================================================== --- llvm/test/Other/pass-pipelines.ll +++ llvm/test/Other/pass-pipelines.ll @@ -11,11 +11,6 @@ ; RUN: -pgo-kind=pgo-instr-use-pipeline -profile-file='%t.profdata' \ ; RUN: -O2 %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O2 --check-prefix=PGOUSE -; RUN: opt -disable-output -disable-verify -debug-pass=Structure \ -; RUN: -pgo-kind=pgo-instr-use-pipeline -profile-file='%t.profdata' \ -; RUN: -hot-cold-split \ -; RUN: -O2 %s 2>&1 \ -; RUN: | FileCheck %s --check-prefix=CHECK-O2 --check-prefix=PGOUSE --check-prefix=SPLIT ; ; In the first pipeline there should just be a function pass manager, no other ; pass managers. @@ -99,7 +94,7 @@ ; the runtime unrolling though. ; CHECK-O2: Loop Pass Manager ; CHECK-O2-NEXT: Loop Invariant Code Motion -; SPLIT: Hot Cold Splitting +; CHECK-O2: Hot Cold Splitting ; CHECK-O2: FunctionPass Manager ; CHECK-O2: Loop Pass Manager ; CHECK-O2-NEXT: Loop Sink Index: llvm/test/Transforms/CodeExtractor/extract-assume.ll =================================================================== --- llvm/test/Transforms/CodeExtractor/extract-assume.ll +++ llvm/test/Transforms/CodeExtractor/extract-assume.ll @@ -9,7 +9,7 @@ declare void @fun2(i32) #0 -define void @fun(i32 %x) { +define void @fun(i32 %x) "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.else Index: llvm/test/Transforms/HotColdSplit/X86/do-not-split.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/X86/do-not-split.ll +++ llvm/test/Transforms/HotColdSplit/X86/do-not-split.ll @@ -9,7 +9,7 @@ ; The cold region is too small to split. ; CHECK-LABEL: @foo ; CHECK-NOT: foo.cold.1 -define void @foo() { +define void @foo() "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.end @@ -23,7 +23,7 @@ ; The cold region is still too small to split. ; CHECK-LABEL: @bar ; CHECK-NOT: bar.cold.1 -define void @bar() { +define void @bar() "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.end @@ -38,7 +38,7 @@ ; Make sure we don't try to outline the entire function. ; CHECK-LABEL: @fun ; CHECK-NOT: fun.cold.1 -define void @fun() { +define void @fun() "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.end @@ -53,7 +53,7 @@ ; Do not split `noinline` functions. ; CHECK-LABEL: @noinline_func ; CHECK-NOT: noinline_func.cold.1 -define void @noinline_func() noinline { +define void @noinline_func() noinline "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.end @@ -68,7 +68,7 @@ ; Do not split `alwaysinline` functions. ; CHECK-LABEL: @alwaysinline_func ; CHECK-NOT: alwaysinline_func.cold.1 -define void @alwaysinline_func() alwaysinline { +define void @alwaysinline_func() alwaysinline "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.end @@ -83,7 +83,7 @@ ; Don't outline infinite loops. ; CHECK-LABEL: @infinite_loop ; CHECK-NOT: infinite_loop.cold.1 -define void @infinite_loop() { +define void @infinite_loop() "hot-cold-split" { entry: br label %loop @@ -95,7 +95,7 @@ ; Don't count debug intrinsics towards the outlining threshold. ; CHECK-LABEL: @dont_count_debug_intrinsics ; CHECK-NOT: dont_count_debug_intrinsics.cold.1 -define void @dont_count_debug_intrinsics(i32 %arg1) !dbg !6 { +define void @dont_count_debug_intrinsics(i32 %arg1) "hot-cold-split" !dbg !6 { entry: %var = add i32 0, 0, !dbg !11 br i1 undef, label %if.then, label %if.end @@ -112,7 +112,7 @@ ; CHECK-LABEL: @minsize ; CHECK-NOT: minsize.cold.1 -define void @minsize() minsize { +define void @minsize() minsize "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.end @@ -126,7 +126,7 @@ ; CHECK-LABEL: @sanitize_address ; CHECK-NOT: sanitize_address.cold.1 -define void @sanitize_address() sanitize_address { +define void @sanitize_address() sanitize_address "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.end @@ -140,7 +140,7 @@ ; CHECK-LABEL: @sanitize_hwaddress ; CHECK-NOT: sanitize_hwaddress.cold.1 -define void @sanitize_hwaddress() sanitize_hwaddress { +define void @sanitize_hwaddress() sanitize_hwaddress "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.end @@ -154,7 +154,7 @@ ; CHECK-LABEL: @sanitize_thread ; CHECK-NOT: sanitize_thread.cold.1 -define void @sanitize_thread() sanitize_thread { +define void @sanitize_thread() sanitize_thread "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.end @@ -168,7 +168,7 @@ ; CHECK-LABEL: @sanitize_memory ; CHECK-NOT: sanitize_memory.cold.1 -define void @sanitize_memory() sanitize_memory { +define void @sanitize_memory() sanitize_memory "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.end @@ -184,7 +184,7 @@ ; CHECK-LABEL: @nosanitize_call ; CHECK-NOT: nosanitize_call.cold.1 -define void @nosanitize_call() sanitize_memory { +define void @nosanitize_call() sanitize_memory "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.end Index: llvm/test/Transforms/HotColdSplit/addr-taken.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/addr-taken.ll +++ llvm/test/Transforms/HotColdSplit/addr-taken.ll @@ -4,12 +4,12 @@ target triple = "x86_64-apple-macosx10.14.0" ; CHECK: define {{.*}} @foo{{.*}}#[[outlined_func_attr:[0-9]+]] -define void @foo() noreturn cold { +define void @foo() noreturn cold "hot-cold-split" { unreachable } ; CHECK: define {{.*}} @bar.cold.1{{.*}}#[[outlined_func_attr]] -define void @bar() { +define void @bar() "hot-cold-split" { br i1 undef, label %normal, label %exit normal: Index: llvm/test/Transforms/HotColdSplit/apply-noreturn-bonus.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/apply-noreturn-bonus.ll +++ llvm/test/Transforms/HotColdSplit/apply-noreturn-bonus.ll @@ -3,7 +3,7 @@ declare void @sink() cold -define void @foo(i32 %arg) { +define void @foo(i32 %arg) "hot-cold-split" { entry: br i1 undef, label %cold1, label %exit Index: llvm/test/Transforms/HotColdSplit/apply-penalty-for-inputs.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/apply-penalty-for-inputs.ll +++ llvm/test/Transforms/HotColdSplit/apply-penalty-for-inputs.ll @@ -5,7 +5,7 @@ @g = global i32 0 -define void @foo(i32 %arg) { +define void @foo(i32 %arg) "hot-cold-split" { %local = load i32, i32* @g br i1 undef, label %cold, label %exit @@ -21,7 +21,7 @@ ret void } -define void @bar(i32* %p1, i32 %p2, i32 %p3) { +define void @bar(i32* %p1, i32 %p2, i32 %p3) "hot-cold-split" { br i1 undef, label %cold, label %exit cold: Index: llvm/test/Transforms/HotColdSplit/apply-penalty-for-outputs.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/apply-penalty-for-outputs.ll +++ llvm/test/Transforms/HotColdSplit/apply-penalty-for-outputs.ll @@ -5,7 +5,7 @@ @g = global i32 0 -define i32 @foo(i32 %arg) { +define i32 @foo(i32 %arg) "hot-cold-split" { entry: br i1 undef, label %cold, label %exit Index: llvm/test/Transforms/HotColdSplit/apply-successor-penalty.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/apply-successor-penalty.ll +++ llvm/test/Transforms/HotColdSplit/apply-successor-penalty.ll @@ -4,7 +4,7 @@ declare void @sink() cold ; CHECK-LABEL: Outlining in one_non_region_successor -define void @one_non_region_successor(i32 %arg) { +define void @one_non_region_successor(i32 %arg) "hot-cold-split" { entry: br i1 undef, label %cold1, label %exit @@ -30,7 +30,7 @@ } ; CHECK-LABEL: Outlining in two_non_region_successor -define void @two_non_region_successors(i32 %arg) { +define void @two_non_region_successors(i32 %arg) "hot-cold-split" { entry: br i1 undef, label %cold1, label %exit1 Index: llvm/test/Transforms/HotColdSplit/coldentrycount.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/coldentrycount.ll +++ llvm/test/Transforms/HotColdSplit/coldentrycount.ll @@ -8,7 +8,7 @@ ; CHECK-LABEL: @fun ; CHECK: call void @fun.cold.1 -define void @fun() !prof !14 { +define void @fun() "hot-cold-split" !prof !14 { entry: br i1 undef, label %if.then, label %if.else Index: llvm/test/Transforms/HotColdSplit/delete-use-without-def-dbg-val.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/delete-use-without-def-dbg-val.ll +++ llvm/test/Transforms/HotColdSplit/delete-use-without-def-dbg-val.ll @@ -9,7 +9,7 @@ ; CHECK-LABEL: define {{.*}}@foo.cold ; CHECK-NOT: call {{.*}}llvm.dbg.value -define void @foo() !dbg !6 { +define void @foo() "hot-cold-split" !dbg !6 { entry: br i1 undef, label %if.then, label %if.end Index: llvm/test/Transforms/HotColdSplit/duplicate-phi-preds-crash.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/duplicate-phi-preds-crash.ll +++ llvm/test/Transforms/HotColdSplit/duplicate-phi-preds-crash.ll @@ -18,7 +18,7 @@ ; CHECK: call {{.*}}@realloc2.cold.1(i64 %size, i8* %ptr, i8** %retval.0.ce.loc) ; CHECK-LABEL: cleanup: ; CHECK-NEXT: phi i8* [ null, %if.then ], [ %call, %if.end ], [ %retval.0.ce.reload, %codeRepl ] -define i8* @realloc2(i8* %ptr, i64 %size) { +define i8* @realloc2(i8* %ptr, i64 %size) "hot-cold-split" { entry: %0 = add i64 %size, -1 %1 = icmp ugt i64 %0, 184549375 Index: llvm/test/Transforms/HotColdSplit/eh-pads.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/eh-pads.ll +++ llvm/test/Transforms/HotColdSplit/eh-pads.ll @@ -6,7 +6,7 @@ ; CHECK-LABEL: define {{.*}}@foo( ; CHECK: landingpad ; CHECK: sideeffect(i32 2) -define void @foo(i32 %cond) personality i8 0 { +define void @foo(i32 %cond) "hot-cold-split" personality i8 0 { entry: invoke void @llvm.donothing() to label %normal unwind label %exception @@ -30,7 +30,7 @@ ; ; CHECK-LABEL: define {{.*}}@bar( ; CHECK: landingpad -define void @bar(i32 %cond) personality i8 0 { +define void @bar(i32 %cond) "hot-cold-split" personality i8 0 { entry: br i1 undef, label %exit, label %continue @@ -54,7 +54,7 @@ ret void } -define void @baz() personality i8 0 { +define void @baz() "hot-cold-split" personality i8 0 { entry: br i1 undef, label %exit, label %cold1 Index: llvm/test/Transforms/HotColdSplit/eh-typeid-for.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/eh-typeid-for.ll +++ llvm/test/Transforms/HotColdSplit/eh-typeid-for.ll @@ -6,7 +6,7 @@ ; CHECK-LABEL: @fun ; CHECK-NOT: call {{.*}}@fun.cold.1 -define void @fun() { +define void @fun() "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.else Index: llvm/test/Transforms/HotColdSplit/forward-dfs-reaches-marked-block.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/forward-dfs-reaches-marked-block.ll +++ llvm/test/Transforms/HotColdSplit/forward-dfs-reaches-marked-block.ll @@ -5,7 +5,7 @@ ; CHECK-LABEL: define {{.*}}@fun ; CHECK: call {{.*}}@fun.cold.1( -define void @fun() { +define void @fun() "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.else Index: llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-1.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-1.ll +++ llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-1.ll @@ -9,7 +9,7 @@ declare void @cold_use2(i8*, i8*) cold ; CHECK-LABEL: define {{.*}}@foo( -define void @foo() { +define void @foo() "hot-cold-split" { entry: %local1 = alloca i256 %local2 = alloca i256 Index: llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-2.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-2.ll +++ llvm/test/Transforms/HotColdSplit/lifetime-markers-on-inputs-2.ll @@ -34,7 +34,7 @@ ; \ / ; exit ; (lt.end) -define void @only_lifetime_start_is_cold() { +define void @only_lifetime_start_is_cold() "hot-cold-split" { ; CHECK-LABEL: @only_lifetime_start_is_cold( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256 @@ -43,7 +43,7 @@ ; CHECK: codeRepl: ; CHECK-NEXT: [[LT_CAST:%.*]] = bitcast i256* [[LOCAL1]] to i8* ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[LT_CAST]]) -; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @only_lifetime_start_is_cold.cold.1(i8* [[LOCAL1_CAST]]) #3 +; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @only_lifetime_start_is_cold.cold.1(i8* [[LOCAL1_CAST]]) #4 ; CHECK-NEXT: br i1 [[TARGETBLOCK]], label [[NO_EXTRACT1]], label [[EXIT:%.*]] ; CHECK: no-extract1: ; CHECK-NEXT: br label [[EXIT]] @@ -95,7 +95,7 @@ ; (lt.end) ; \ / ; exit -define void @only_lifetime_end_is_cold() { +define void @only_lifetime_end_is_cold() "hot-cold-split" { ; CHECK-LABEL: @only_lifetime_end_is_cold( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256 @@ -106,7 +106,7 @@ ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 1, i8* [[LOCAL1_CAST]]) ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: codeRepl: -; CHECK-NEXT: call void @only_lifetime_end_is_cold.cold.1(i8* [[LOCAL1_CAST]]) #3 +; CHECK-NEXT: call void @only_lifetime_end_is_cold.cold.1(i8* [[LOCAL1_CAST]]) #4 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void @@ -135,7 +135,7 @@ ; In this CFG, splitting will extract the blocks extract{1,2,3}. Lifting the ; lifetime.end marker would be a miscompile. -define void @do_not_lift_lifetime_end() { +define void @do_not_lift_lifetime_end() "hot-cold-split" { ; CHECK-LABEL: @do_not_lift_lifetime_end( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[LOCAL1:%.*]] = alloca i256 @@ -146,7 +146,7 @@ ; CHECK-NEXT: call void @use(i8* [[LOCAL1_CAST]]) ; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[CODEREPL:%.*]] ; CHECK: codeRepl: -; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @do_not_lift_lifetime_end.cold.1(i8* [[LOCAL1_CAST]]) #3 +; CHECK-NEXT: [[TARGETBLOCK:%.*]] = call i1 @do_not_lift_lifetime_end.cold.1(i8* [[LOCAL1_CAST]]) #4 ; CHECK-NEXT: br i1 [[TARGETBLOCK]], label [[HEADER]], label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void Index: llvm/test/Transforms/HotColdSplit/mark-the-whole-func-cold.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/mark-the-whole-func-cold.ll +++ llvm/test/Transforms/HotColdSplit/mark-the-whole-func-cold.ll @@ -24,7 +24,7 @@ ; CHECK: define {{.*}}@_Z3fooii{{.*}}#[[outlined_func_attr:[0-9]+]] ; CHECK-NOT: _Z3fooii.cold ; CHECK: attributes #[[outlined_func_attr]] = { {{.*}}minsize -define void @_Z3fooii(i32, i32) { +define void @_Z3fooii(i32, i32) "hot-cold-split" { %3 = alloca i32, align 4 %4 = alloca i32, align 4 store i32 %0, i32* %3, align 4 Index: llvm/test/Transforms/HotColdSplit/minsize.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/minsize.ll +++ llvm/test/Transforms/HotColdSplit/minsize.ll @@ -5,7 +5,7 @@ ; CHECK-LABEL: @fun ; CHECK: call void @fun.cold.1 -define void @fun() { +define void @fun() "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.else @@ -18,7 +18,7 @@ } ; CHECK: define {{.*}} @foo{{.*}}#[[outlined_func_attr:[0-9]+]] -define void @foo() cold { +define void @foo() cold "hot-cold-split" { ret void } Index: llvm/test/Transforms/HotColdSplit/multiple-exits.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/multiple-exits.ll +++ llvm/test/Transforms/HotColdSplit/multiple-exits.ll @@ -32,7 +32,7 @@ ; CHECK: call {{.*}}@sideeffect(i32 1) ; CHECK: [[return]]: ; CHECK-NEXT: ret void -define void @foo(i32 %cond) { +define void @foo(i32 %cond) "hot-cold-split" { entry: %tobool = icmp eq i32 %cond, 0 br i1 %tobool, label %exit1, label %if.then Index: llvm/test/Transforms/HotColdSplit/noreturn.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/noreturn.ll +++ llvm/test/Transforms/HotColdSplit/noreturn.ll @@ -10,7 +10,7 @@ ; CHECK-LABEL: define {{.*}}@foo( ; CHECK-NOT: foo.cold.1 -define void @foo(i32, %struct.__jmp_buf_tag*) { +define void @foo(i32, %struct.__jmp_buf_tag*) "hot-cold-split" { %3 = icmp eq i32 %0, 0 tail call void @_Z10sideeffectv() br i1 %3, label %5, label %4 @@ -27,7 +27,7 @@ ; CHECK-LABEL: define {{.*}}@bar( ; CHECK: call {{.*}}@bar.cold.1( -define void @bar(i32) { +define void @bar(i32) "hot-cold-split" { %2 = icmp eq i32 %0, 0 tail call void @_Z10sideeffectv() br i1 %2, label %sink, label %exit @@ -45,7 +45,7 @@ ; CHECK-LABEL: define {{.*}}@baz( ; CHECK: call {{.*}}@baz.cold.1( -define void @baz(i32, %struct.__jmp_buf_tag*) { +define void @baz(i32, %struct.__jmp_buf_tag*) "hot-cold-split" { %3 = icmp eq i32 %0, 0 tail call void @_Z10sideeffectv() br i1 %3, label %5, label %4 Index: llvm/test/Transforms/HotColdSplit/outline-cold-asm.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/outline-cold-asm.ll +++ llvm/test/Transforms/HotColdSplit/outline-cold-asm.ll @@ -9,7 +9,7 @@ ; CHECK-LABEL: define {{.*}}@fun.cold.1( ; CHECK: asm "" -define void @fun() { +define void @fun() "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.else Index: llvm/test/Transforms/HotColdSplit/outline-disjoint-diamonds.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/outline-disjoint-diamonds.ll +++ llvm/test/Transforms/HotColdSplit/outline-disjoint-diamonds.ll @@ -5,7 +5,7 @@ ; CHECK-NEXT: ret void ; CHECK: call {{.*}}@fun.cold.1( ; CHECK-NEXT: ret void -define void @fun() { +define void @fun() "hot-cold-split" { entry: br i1 undef, label %A.then, label %A.else Index: llvm/test/Transforms/HotColdSplit/outline-if-then-else.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/outline-if-then-else.ll +++ llvm/test/Transforms/HotColdSplit/outline-if-then-else.ll @@ -24,7 +24,7 @@ ; CHECK-NEXT: call void @foo.cold.1 ; CHECK-LABEL: if.end2: ; CHECK: call void @sideeffect(i32 2) -define void @foo(i32 %cond) { +define void @foo(i32 %cond) "hot-cold-split" { entry: %cond.addr = alloca i32 store i32 %cond, i32* %cond.addr Index: llvm/test/Transforms/HotColdSplit/outline-multiple-entry-region.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/outline-multiple-entry-region.ll +++ llvm/test/Transforms/HotColdSplit/outline-multiple-entry-region.ll @@ -34,7 +34,7 @@ ; CHECK: call void @_Z4sinkv ; CHECK: call void @_Z10sideeffecti(i32 3) -define void @_Z3fooii(i32, i32) { +define void @_Z3fooii(i32, i32) "hot-cold-split" { %3 = alloca i32, align 4 %4 = alloca i32, align 4 store i32 %0, i32* %3, align 4 Index: llvm/test/Transforms/HotColdSplit/outline-while-loop.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/outline-while-loop.ll +++ llvm/test/Transforms/HotColdSplit/outline-while-loop.ll @@ -24,7 +24,7 @@ ; CHECK-NEXT: call void @foo.cold.1 ; CHECK-LABEL: if.end: ; CHECK: call void @sideeffect(i32 1) -define void @foo(i32 %cond) { +define void @foo(i32 %cond) "hot-cold-split" { entry: %tobool = icmp eq i32 %cond, 0 br i1 %tobool, label %if.end, label %while.cond.preheader @@ -62,7 +62,7 @@ ; CHECK-NEXT: call void @while_loop_after_sink.cold.1 ; CHECK-LABEL: if.end: ; CHECK: call void @sideeffect(i32 1) -define void @while_loop_after_sink(i32 %cond) { +define void @while_loop_after_sink(i32 %cond) "hot-cold-split" { entry: %tobool = icmp eq i32 %cond, 0 br i1 %tobool, label %if.end, label %sink Index: llvm/test/Transforms/HotColdSplit/phi-with-distinct-outlined-values.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/phi-with-distinct-outlined-values.ll +++ llvm/test/Transforms/HotColdSplit/phi-with-distinct-outlined-values.ll @@ -11,7 +11,7 @@ ; CHECK: %p.ce = phi i32 [ 1, %coldbb ], [ 3, %coldbb2 ] ; CHECK-NEXT: store i32 %p.ce, i32* %p.ce.out -define void @foo(i32 %cond) { +define void @foo(i32 %cond) "hot-cold-split" { entry: %tobool = icmp eq i32 %cond, 0 br i1 %tobool, label %if.end, label %coldbb Index: llvm/test/Transforms/HotColdSplit/region-overlap.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/region-overlap.ll +++ llvm/test/Transforms/HotColdSplit/region-overlap.ll @@ -24,7 +24,7 @@ ; CHECK-LABEL: define {{.*}}@_Z3fooii ; CHECK: call {{.*}}@_Z3fooii.cold.1 ; CHECK-NOT: _Z3fooii.cold -define void @_Z3fooii(i32, i32) { +define void @_Z3fooii(i32, i32) "hot-cold-split" { %3 = alloca i32, align 4 %4 = alloca i32, align 4 store i32 %0, i32* %3, align 4 Index: llvm/test/Transforms/HotColdSplit/resume.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/resume.ll +++ llvm/test/Transforms/HotColdSplit/resume.ll @@ -10,7 +10,7 @@ declare void @sink() cold -define i32 @foo() personality i8 0 { +define i32 @foo() "hot-cold-split" personality i8 0 { entry: br i1 undef, label %pre-resume-eh, label %normal Index: llvm/test/Transforms/HotColdSplit/split-cold-2.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/split-cold-2.ll +++ llvm/test/Transforms/HotColdSplit/split-cold-2.ll @@ -12,7 +12,7 @@ ; CHECK: define {{.*}}@fun.cold.1{{.*}} [[cold_attr:#[0-9]+]] ; CHECK: attributes [[cold_attr]] = { {{.*}}noreturn -define void @fun() { +define void @fun() "hot-cold-split" { entry: br i1 undef, label %if.then, label %if.else Index: llvm/test/Transforms/HotColdSplit/split-out-dbg-val-of-arg.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/split-out-dbg-val-of-arg.ll +++ llvm/test/Transforms/HotColdSplit/split-out-dbg-val-of-arg.ll @@ -6,7 +6,7 @@ ; CHECK-LABEL: define {{.*}}@foo.cold ; CHECK-NOT: llvm.dbg.value -define void @foo(i32 %arg1) !dbg !6 { +define void @foo(i32 %arg1) "hot-cold-split" !dbg !6 { entry: %var = add i32 0, 0, !dbg !11 br i1 undef, label %if.then, label %if.end Index: llvm/test/Transforms/HotColdSplit/split-phis-in-exit-blocks.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/split-phis-in-exit-blocks.ll +++ llvm/test/Transforms/HotColdSplit/split-phis-in-exit-blocks.ll @@ -29,7 +29,7 @@ ; CHECK: call {{.*}}@sideeffect(i32 3) ; CHECK: call {{.*}}@sideeffect(i32 4) ; CHECK: call {{.*}}@sideeffect(i32 5) -define void @pluto() { +define void @pluto() "hot-cold-split" { bb: switch i8 undef, label %bb1 [ i8 0, label %bb7 Index: llvm/test/Transforms/HotColdSplit/succ-block-with-self-edge.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/succ-block-with-self-edge.ll +++ llvm/test/Transforms/HotColdSplit/succ-block-with-self-edge.ll @@ -7,7 +7,7 @@ ; CHECK: call {{.*}}@exit_block_with_same_incoming_vals.cold.1( ; CHECK-NOT: br i1 undef ; CHECK: phi i32 [ 0, %entry ], [ %p.ce.reload, %codeRepl ] -define void @exit_block_with_same_incoming_vals(i32 %cond) { +define void @exit_block_with_same_incoming_vals(i32 %cond) "hot-cold-split" { entry: %tobool = icmp eq i32 %cond, 0 br i1 %tobool, label %if.end, label %coldbb @@ -30,7 +30,7 @@ ; CHECK: call {{.*}}@exit_block_with_distinct_incoming_vals.cold.1( ; CHECK-NOT: br i1 undef ; CHECK: phi i32 [ 0, %entry ], [ %p.ce.reload, %codeRepl ] -define void @exit_block_with_distinct_incoming_vals(i32 %cond) { +define void @exit_block_with_distinct_incoming_vals(i32 %cond) "hot-cold-split" { entry: %tobool = icmp eq i32 %cond, 0 br i1 %tobool, label %if.end, label %coldbb Index: llvm/test/Transforms/HotColdSplit/swifterror.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/swifterror.ll +++ llvm/test/Transforms/HotColdSplit/swifterror.ll @@ -9,7 +9,7 @@ ; CHECK-LABEL: define {{.*}}@in_arg( ; CHECK: call void @in_arg.cold.1(%swift_error** swifterror -define void @in_arg(%swift_error** swifterror %error_ptr_ref) { +define void @in_arg(%swift_error** swifterror %error_ptr_ref) "hot-cold-split" { br i1 undef, label %cold, label %exit cold: @@ -23,7 +23,7 @@ ; CHECK-LABEL: define {{.*}}@in_alloca( ; CHECK: call void @in_alloca.cold.1(%swift_error** swifterror -define void @in_alloca() { +define void @in_alloca() "hot-cold-split" { %err = alloca swifterror %swift_error* br i1 undef, label %cold, label %exit Index: llvm/test/Transforms/HotColdSplit/unwind.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/unwind.ll +++ llvm/test/Transforms/HotColdSplit/unwind.ll @@ -11,7 +11,7 @@ ; CHECK-NOT: noreturn -define i32 @foo() personality i8 0 { +define i32 @foo() "hot-cold-split" personality i8 0 { entry: invoke void @llvm.donothing() to label %normal unwind label %exception