diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index bde4c25c7bc276..554688ac987b70 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1139,6 +1139,7 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( PTO.LoopInterleaving = CodeGenOpts.UnrollLoops; PTO.LoopVectorization = CodeGenOpts.VectorizeLoop; PTO.SLPVectorization = CodeGenOpts.VectorizeSLP; + PTO.MergeFunctions = CodeGenOpts.MergeFunctions; // Only enable CGProfilePass when using integrated assembler, since // non-integrated assemblers don't recognize .cgprofile section. PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS; diff --git a/clang/test/CodeGenCXX/merge-functions.cpp b/clang/test/CodeGenCXX/merge-functions.cpp index db742f41d3c894..42d57d7db811c6 100644 --- a/clang/test/CodeGenCXX/merge-functions.cpp +++ b/clang/test/CodeGenCXX/merge-functions.cpp @@ -1,5 +1,8 @@ // REQUIRES: x86-registered-target +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O0 -fno-experimental-new-pass-manager -fmerge-functions -emit-llvm -o - -x c++ < %s | FileCheck %s -implicit-check-not=_ZN1A1gEiPi // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O1 -fno-experimental-new-pass-manager -fmerge-functions -emit-llvm -o - -x c++ < %s | FileCheck %s -implicit-check-not=_ZN1A1gEiPi +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O0 -fexperimental-new-pass-manager -fmerge-functions -emit-llvm -o - -x c++ < %s | FileCheck %s -implicit-check-not=_ZN1A1gEiPi +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -O1 -fexperimental-new-pass-manager -fmerge-functions -emit-llvm -o - -x c++ < %s | FileCheck %s -implicit-check-not=_ZN1A1gEiPi // Basic functionality test. Function merging doesn't kick in on functions that // are too simple. diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h index a04e98df8f85aa..e2d22031dd5ec5 100644 --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -123,6 +123,10 @@ class PipelineTuningOptions { /// Tuning option to enable/disable call graph profile. Its default value is /// that of the flag: `-enable-npm-call-graph-profile`. bool CallGraphProfile; + + /// Tuning option to enable/disable function merging. Its default value is + /// false. + bool MergeFunctions; }; /// This class provides access to building LLVM's passes. diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 0e29b14dac9a36..bb77124e48d65b 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -282,6 +282,7 @@ PipelineTuningOptions::PipelineTuningOptions() { LicmMssaOptCap = SetLicmMssaOptCap; LicmMssaNoAccForPromotionCap = SetLicmMssaNoAccForPromotionCap; CallGraphProfile = true; + MergeFunctions = false; } extern cl::opt EnableConstraintElimination; @@ -1316,6 +1317,10 @@ PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level, if (EnableHotColdSplit && !LTOPreLink) MPM.addPass(HotColdSplittingPass()); + // Merge functions if requested. + if (PTO.MergeFunctions) + MPM.addPass(MergeFunctionsPass()); + // LoopSink pass sinks instructions hoisted by LICM, which serves as a // canonicalization pass that enables other optimizations. As a result, // LoopSink pass needs to be a very late IR pass to avoid undoing LICM @@ -1746,10 +1751,12 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level, // Now that we have optimized the program, discard unreachable functions. MPM.addPass(GlobalDCEPass()); + if (PTO.MergeFunctions) + MPM.addPass(MergeFunctionsPass()); + // Emit annotation remarks. addAnnotationRemarksPass(MPM); - // FIXME: Maybe enable MergeFuncs conditionally after it's ported. return MPM; } @@ -1781,6 +1788,9 @@ ModulePassManager PassBuilder::buildO0DefaultPipeline(OptimizationLevel Level, MPM.addPass(AlwaysInlinerPass( /*InsertLifetimeIntrinsics=*/PTO.Coroutines)); + if (PTO.MergeFunctions) + MPM.addPass(MergeFunctionsPass()); + if (EnableMatrix) MPM.addPass( createModuleToFunctionPassAdaptor(LowerMatrixIntrinsicsPass(true)));