diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index f95c32d859d14..dcb6484108c60 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -1511,6 +1511,41 @@ Expected parseVirtRegRewriterPassOptions(StringRef Params) { return ClearVirtRegs; } +struct FatLTOOptions { + OptimizationLevel OptLevel; + bool ThinLTO = false; + bool EmitSummary = false; +}; + +Expected parseFatLTOOptions(StringRef Params) { + FatLTOOptions Result; + bool HaveOptLevel = false; + while (!Params.empty()) { + StringRef ParamName; + std::tie(ParamName, Params) = Params.split(';'); + + if (ParamName == "thinlto") { + Result.ThinLTO = true; + } else if (ParamName == "emit-summary") { + Result.EmitSummary = true; + } else if (std::optional OptLevel = + parseOptLevel(ParamName)) { + Result.OptLevel = *OptLevel; + HaveOptLevel = true; + } else { + return make_error( + formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName) + .str(), + inconvertibleErrorCode()); + } + } + if (!HaveOptLevel) + return make_error( + "missing optimization level for fatlto-pre-link pipeline", + inconvertibleErrorCode()); + return Result; +} + } // namespace /// Tests whether registered callbacks will accept a given pass name. diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 1d924f38a47fb..65276489e6f02 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -276,6 +276,13 @@ MODULE_PASS_WITH_PARAMS( return buildLTODefaultPipeline(L, nullptr); }, parseOptLevelParam, "O0;O1;O2;O3;Os;Oz") +MODULE_PASS_WITH_PARAMS( + "fatlto-pre-link", "", [&](FatLTOOptions Opts) { + setupOptionsForPipelineAlias(PTO, Opts.OptLevel); + return buildFatLTODefaultPipeline(Opts.OptLevel, Opts.ThinLTO, + Opts.EmitSummary); + }, + parseFatLTOOptions, "O0;O1;O2;O3;Os;Oz;thinlto;emit-summary") #undef MODULE_PASS_WITH_PARAMS diff --git a/llvm/test/Other/fatlto.ll b/llvm/test/Other/fatlto.ll new file mode 100644 index 0000000000000..90e2701dc847b --- /dev/null +++ b/llvm/test/Other/fatlto.ll @@ -0,0 +1,7 @@ +; RUN: opt -debug-pass-manager -passes='fatlto-pre-link' -disable-output %s 2>&1 | FileCheck %s +; RUN: opt -debug-pass-manager -passes='fatlto-pre-link' -disable-output %s 2>&1 | FileCheck %s --check-prefixes=CHECK,THINLTO + +; CHECK: Running pass: EmbedBitcodePass on [module] +; THINLTO: Running analysis: ModuleSummaryIndexAnalysis on [module] +; CHECK-NEXT: Running pass: FatLtoCleanup on [module] +; CHECK-NEXT: Running pass: LowerTypeTestsPass on [module] diff --git a/llvm/test/Other/pipeline-alias-errors.ll b/llvm/test/Other/pipeline-alias-errors.ll index 4d744144ed2ec..f27dd76568a56 100644 --- a/llvm/test/Other/pipeline-alias-errors.ll +++ b/llvm/test/Other/pipeline-alias-errors.ll @@ -8,6 +8,11 @@ ; RUN: not opt -passes="lto-pre-link" < %s 2>&1 | FileCheck %s --check-prefix=INVALID-OPT-LEVEL ; RUN: not opt -passes="lto" < %s 2>&1 | FileCheck %s --check-prefix=MISSING-OPT-LEVEL ; RUN: not opt -passes="lto" < %s 2>&1 | FileCheck %s --check-prefix=INVALID-OPT-LEVEL +; RUN: not opt -passes="fatlto-pre-link" < %s 2>&1 | FileCheck %s --check-prefix=FATLTO-MISSING-OPT-LEVEL +; RUN: not opt -passes="fatlto-pre-link" < %s 2>&1 | FileCheck %s --check-prefix=FATLTO-INVALID-PARAMS ; MISSING-OPT-LEVEL: invalid optimization level '' ; INVALID-OPT-LEVEL: invalid optimization level 'foo' + +; FATLTO-MISSING-OPT-LEVEL: missing optimization level for fatlto-pre-link pipeline +; FATLTO-INVALID-PARAMS: invalid fatlto-pre-link pass parameter 'foo'