diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -162,6 +162,8 @@ // Used for /opt:lldlto=N unsigned ltoo = 2; + // Used for /opt:lldltocgo=N + std::optional ltoCgo; // Used for /opt:lldltojobs=N std::string thinLTOJobs; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1768,6 +1768,10 @@ } else if (s.consume_front("lldlto=")) { if (s.getAsInteger(10, config->ltoo) || config->ltoo > 3) error("/opt:lldlto: invalid optimization level: " + s); + } else if (s.consume_front("lldltocgo=")) { + config->ltoCgo.emplace(); + if (s.getAsInteger(10, *config->ltoCgo) || *config->ltoCgo > 3) + error("/opt:lldltocgo: invalid codegen optimization level: " + s); } else if (s.consume_front("lldltojobs=")) { if (!get_threadpool_strategy(s)) error("/opt:lldltojobs: invalid job count: " + s); diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -88,7 +88,10 @@ c.OptLevel = ctx.config.ltoo; c.CPU = getCPUStr(); c.MAttrs = getMAttrs(); - c.CGOptLevel = args::getCGOptLevel(ctx.config.ltoo); + std::optional optLevelOrNone = CodeGenOpt::getLevel( + ctx.config.ltoCgo.value_or(args::getCGOptLevel(ctx.config.ltoo))); + assert(optLevelOrNone && "Invalid optimization level!"); + c.CGOptLevel = *optLevelOrNone; c.AlwaysEmitRegularLTOObj = !ctx.config.ltoObjPath.empty(); c.DebugPassManager = ctx.config.ltoDebugPassManager; c.CSIRProfile = std::string(ctx.config.ltoCSProfileFile); diff --git a/lld/Common/Args.cpp b/lld/Common/Args.cpp --- a/lld/Common/Args.cpp +++ b/lld/Common/Args.cpp @@ -19,11 +19,8 @@ // TODO(sbc): Remove this once CGOptLevel can be set completely based on bitcode // function metadata. -CodeGenOpt::Level lld::args::getCGOptLevel(int optLevelLTO) { - if (optLevelLTO == 3) - return CodeGenOpt::Aggressive; - assert(optLevelLTO < 3); - return CodeGenOpt::Default; +int lld::args::getCGOptLevel(int optLevelLTO) { + return std::clamp(optLevelLTO, 2, 3); } static int64_t getInteger(opt::InputArgList &args, unsigned key, diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -317,6 +317,7 @@ uint64_t zStackSize; unsigned ltoPartitions; unsigned ltoo; + llvm::CodeGenOpt::Level ltoCgo; unsigned optimize; StringRef thinLTOJobs; unsigned timeTraceGranularity; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1139,6 +1139,14 @@ args.hasFlag(OPT_lto_whole_program_visibility, OPT_no_lto_whole_program_visibility, false); config->ltoo = args::getInteger(args, OPT_lto_O, 2); + if (config->ltoo > 3) + error("invalid optimization level for LTO: " + Twine(config->ltoo)); + unsigned ltoCgo = + args::getInteger(args, OPT_lto_CGO, args::getCGOptLevel(config->ltoo)); + if (auto level = CodeGenOpt::getLevel(ltoCgo)) + config->ltoCgo = *level; + else + error("invalid codegen optimization level for LTO: " + Twine(ltoCgo)); config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq); config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile); @@ -1395,8 +1403,6 @@ config->thinLTOJobs = arg->getValue(); config->threadCount = parallel::strategy.compute_thread_count(); - if (config->ltoo > 3) - error("invalid optimization level for LTO: " + Twine(config->ltoo)); if (config->ltoPartitions == 0) error("--lto-partitions: number of threads must be > 0"); if (!get_threadpool_strategy(config->thinLTOJobs)) diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -127,7 +127,7 @@ c.OptLevel = config->ltoo; c.CPU = getCPUStr(); c.MAttrs = getMAttrs(); - c.CGOptLevel = args::getCGOptLevel(config->ltoo); + c.CGOptLevel = config->ltoCgo; c.PTO.LoopVectorization = c.OptLevel > 1; c.PTO.SLPVectorization = c.OptLevel > 1; diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -558,6 +558,8 @@ HelpText<"Passes to run during LTO">; def lto_O: JJ<"lto-O">, MetaVarName<"">, HelpText<"Optimization level for LTO">; +def lto_CGO: JJ<"lto-CGO">, MetaVarName<"">, + HelpText<"Codegen optimization level for LTO">; def lto_partitions: JJ<"lto-partitions=">, HelpText<"Number of LTO codegen partitions">; def lto_cs_profile_generate: FF<"lto-cs-profile-generate">, diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -26,6 +26,10 @@ #include +namespace llvm::CodeGenOpt { +enum Level : int; +} // namespace llvm::CodeGenOpt + namespace lld { namespace macho { @@ -165,6 +169,7 @@ llvm::StringRef thinLTOJobs; llvm::StringRef umbrella; uint32_t ltoo = 2; + llvm::CodeGenOpt::Level ltoCgo; llvm::CachePruningPolicy thinLTOCachePolicy; llvm::StringRef thinLTOCacheDir; llvm::StringRef thinLTOIndexOnlyArg; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1421,6 +1421,17 @@ target = createTargetInfo(args); depTracker = std::make_unique( args.getLastArgValue(OPT_dependency_info)); + + config->ltoo = args::getInteger(args, OPT_lto_O, 2); + if (config->ltoo > 3) + error("--lto-O: invalid optimization level: " + Twine(config->ltoo)); + unsigned ltoCgo = + args::getInteger(args, OPT_lto_CGO, args::getCGOptLevel(config->ltoo)); + if (auto level = CodeGenOpt::getLevel(ltoCgo)) + config->ltoCgo = *level; + else + error("--lto-CGO: invalid codegen optimization level: " + Twine(ltoCgo)); + if (errorCount()) return false; @@ -1558,9 +1569,6 @@ config->umbrella = arg->getValue(); } config->ltoObjPath = args.getLastArgValue(OPT_object_path_lto); - config->ltoo = args::getInteger(args, OPT_lto_O, 2); - if (config->ltoo > 3) - error("--lto-O: invalid optimization level: " + Twine(config->ltoo)); config->thinLTOCacheDir = args.getLastArgValue(OPT_cache_path_lto); config->thinLTOCachePolicy = getLTOCachePolicy(args); config->thinLTOEmitImportsFiles = args.hasArg(OPT_thinlto_emit_imports_files); diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp --- a/lld/MachO/LTO.cpp +++ b/lld/MachO/LTO.cpp @@ -70,7 +70,7 @@ c.TimeTraceEnabled = config->timeTraceEnabled; c.TimeTraceGranularity = config->timeTraceGranularity; c.OptLevel = config->ltoo; - c.CGOptLevel = args::getCGOptLevel(config->ltoo); + c.CGOptLevel = config->ltoCgo; if (config->saveTemps) checkError(c.addSaveTemps(config->outputFile.str() + ".", /*UseInputModulePath=*/true)); diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -84,6 +84,10 @@ HelpText<"Set optimization level for LTO (default: 2)">, MetaVarName<"">, Group; +def lto_CGO: Joined<["--"], "lto-CGO">, + HelpText<"Set codegen optimization level for LTO (default: 2)">, + MetaVarName<"">, + Group; def thinlto_cache_policy_eq: Joined<["--"], "thinlto-cache-policy=">, HelpText<"Pruning policy for the ThinLTO cache">, Group; diff --git a/lld/include/lld/Common/Args.h b/lld/include/lld/Common/Args.h --- a/lld/include/lld/Common/Args.h +++ b/lld/include/lld/Common/Args.h @@ -23,7 +23,7 @@ namespace lld { namespace args { -llvm::CodeGenOpt::Level getCGOptLevel(int optLevelLTO); +int getCGOptLevel(int optLevelLTO); int64_t getInteger(llvm::opt::InputArgList &args, unsigned key, int64_t Default); diff --git a/lld/test/COFF/lto-cgo.ll b/lld/test/COFF/lto-cgo.ll new file mode 100644 --- /dev/null +++ b/lld/test/COFF/lto-cgo.ll @@ -0,0 +1,28 @@ +; REQUIRES: x86 + +; RUN: llvm-as %s -o %t.obj +; RUN: lld-link -opt:lldlto=0 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: lld-link -opt:lldltocgo=0 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: lld-link -opt:lldlto=3 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: lld-link -opt:lldltocgo=3 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: lld-link -opt:lldlto=0 -opt:lldltocgo=0 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: lld-link -opt:lldlto=3 -opt:lldltocgo=0 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: lld-link -opt:lldlto=0 -opt:lldltocgo=3 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: lld-link -opt:lldlto=3 -opt:lldltocgo=3 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: lld-link -opt:lldlto=0 -opt:lldltocgo=0 -opt:lldltocgo=2 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: not lld-link -opt:lldlto=4 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefix=ERROR-O4 %s +; RUN: not lld-link -opt:lldltocgo=4 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefix=ERROR-CGO4 %s +; RUN: not lld-link -opt:lldlto=4 -opt:lldltocgo=4 %t.obj -dll -noentry -out:%t.dll -mllvm:-debug-pass=Structure 2>&1 | FileCheck --check-prefixes=ERROR-O4,ERROR-CGO4 %s + +; NOOPT: Fast Register Allocator +; OPT: Greedy Register Allocator +; ERROR-O4: lld-link: error: /opt:lldlto: invalid optimization level: 4 +; ERROR-CGO4: lld-link: error: /opt:lldltocgo: invalid codegen optimization level: 4 + +target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc" + +define void @_start() { +entry: + ret void +} diff --git a/lld/test/ELF/lto/cgo.ll b/lld/test/ELF/lto/cgo.ll new file mode 100644 --- /dev/null +++ b/lld/test/ELF/lto/cgo.ll @@ -0,0 +1,28 @@ +; REQUIRES: x86 + +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld --lto-O0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: ld.lld --lto-CGO0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: ld.lld --lto-O3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: ld.lld --lto-CGO3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: ld.lld --lto-O0 --lto-CGO0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: ld.lld --lto-O3 --lto-CGO0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: ld.lld --lto-O0 --lto-CGO3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: ld.lld --lto-O3 --lto-CGO3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: ld.lld --lto-O0 --lto-CGO0 --lto-CGO2 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: not ld.lld --lto-O4 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=ERROR-O4 %s +; RUN: not ld.lld --lto-CGO4 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=ERROR-CGO4 %s +; RUN: not ld.lld --lto-O4 --lto-CGO4 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefixes=ERROR-O4,ERROR-CGO4 %s + +; NOOPT: Fast Register Allocator +; OPT: Greedy Register Allocator +; ERROR-O4: ld.lld: error: invalid optimization level for LTO: 4 +; ERROR-CGO4: ld.lld: error: invalid codegen optimization level for LTO: 4 + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +define void @_start() { +entry: + ret void +} diff --git a/lld/test/MachO/lto-cgo.ll b/lld/test/MachO/lto-cgo.ll new file mode 100644 --- /dev/null +++ b/lld/test/MachO/lto-cgo.ll @@ -0,0 +1,28 @@ +; REQUIRES: x86 + +; RUN: llvm-as %s -o %t.o +; RUN: %lld -dylib --lto-O0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: %lld -dylib --lto-CGO0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: %lld -dylib --lto-O3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: %lld -dylib --lto-CGO3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: %lld -dylib --lto-O0 --lto-CGO0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: %lld -dylib --lto-O3 --lto-CGO0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: %lld -dylib --lto-O0 --lto-CGO3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: %lld -dylib --lto-O3 --lto-CGO3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: %lld -dylib --lto-O0 --lto-CGO0 --lto-CGO2 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: not %lld -dylib --lto-O4 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=ERROR-O4 %s +; RUN: not %lld -dylib --lto-CGO4 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=ERROR-CGO4 %s +; RUN: not %lld -dylib --lto-O4 --lto-CGO4 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefixes=ERROR-O4,ERROR-CGO4 %s + +; NOOPT: Fast Register Allocator +; OPT: Greedy Register Allocator +; ERROR-O4: ld64.lld: error: --lto-O: invalid optimization level: 4 +; ERROR-CGO4: ld64.lld: error: --lto-CGO: invalid codegen optimization level: 4 + +target triple = "x86_64-apple-darwin" +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + +define void @_start() { +entry: + ret void +} diff --git a/lld/test/wasm/lto/cgo.ll b/lld/test/wasm/lto/cgo.ll new file mode 100644 --- /dev/null +++ b/lld/test/wasm/lto/cgo.ll @@ -0,0 +1,28 @@ +; REQUIRES: x86 + +; RUN: llvm-as %s -o %t.o +; RUN: wasm-ld --lto-O0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: wasm-ld --lto-CGO0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: wasm-ld --lto-O3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: wasm-ld --lto-CGO3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: wasm-ld --lto-O0 --lto-CGO0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: wasm-ld --lto-O3 --lto-CGO0 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=NOOPT %s +; RUN: wasm-ld --lto-O0 --lto-CGO3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: wasm-ld --lto-O3 --lto-CGO3 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: wasm-ld --lto-O0 --lto-CGO0 --lto-CGO2 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=OPT %s +; RUN: not wasm-ld --lto-O4 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=ERROR-O4 %s +; RUN: not wasm-ld --lto-CGO4 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefix=ERROR-CGO4 %s +; RUN: not wasm-ld --lto-O4 --lto-CGO4 %t.o -o %t -mllvm -debug-pass=Structure 2>&1 | FileCheck --check-prefixes=ERROR-O4,ERROR-CGO4 %s + +; NOOPT-NOT: WebAssembly Optimize Returned +; OPT: WebAssembly Optimize Returned +; ERROR-O4: wasm-ld: error: invalid optimization level for LTO: 4 +; ERROR-CGO4: wasm-ld: error: invalid codegen optimization level for LTO: 4 + +target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown-wasm" + +define void @_start() { +entry: + ret void +} diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -16,6 +16,10 @@ #include "llvm/Support/CachePruning.h" #include +namespace llvm::CodeGenOpt { +enum Level : int; +} // namespace llvm::CodeGenOpt + namespace lld { namespace wasm { @@ -63,6 +67,7 @@ uint64_t zStackSize; unsigned ltoPartitions; unsigned ltoo; + llvm::CodeGenOpt::Level ltoCgo; unsigned optimize; llvm::StringRef thinLTOJobs; bool ltoDebugPassManager; diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -424,6 +424,14 @@ config->importTable = args.hasArg(OPT_import_table); config->importUndefined = args.hasArg(OPT_import_undefined); config->ltoo = args::getInteger(args, OPT_lto_O, 2); + if (config->ltoo > 3) + error("invalid optimization level for LTO: " + Twine(config->ltoo)); + unsigned ltoCgo = + args::getInteger(args, OPT_lto_CGO, args::getCGOptLevel(config->ltoo)); + if (auto level = CodeGenOpt::getLevel(ltoCgo)) + config->ltoCgo = *level; + else + error("invalid codegen optimization level for LTO: " + Twine(ltoCgo)); config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1); config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager); config->mapFile = args.getLastArgValue(OPT_Map); @@ -560,8 +568,6 @@ error("--compress-relocations is incompatible with output debug" " information. Please pass --strip-debug or --strip-all"); - if (config->ltoo > 3) - error("invalid optimization level for LTO: " + Twine(config->ltoo)); if (config->ltoPartitions == 0) error("--lto-partitions: number of threads must be > 0"); if (!get_threadpool_strategy(config->thinLTOJobs)) diff --git a/lld/wasm/LTO.cpp b/lld/wasm/LTO.cpp --- a/lld/wasm/LTO.cpp +++ b/lld/wasm/LTO.cpp @@ -51,7 +51,7 @@ c.DiagHandler = diagnosticHandler; c.OptLevel = config->ltoo; c.MAttrs = getMAttrs(); - c.CGOptLevel = args::getCGOptLevel(config->ltoo); + c.CGOptLevel = config->ltoCgo; c.DebugPassManager = config->ltoDebugPassManager; if (config->relocatable) diff --git a/lld/wasm/Options.td b/lld/wasm/Options.td --- a/lld/wasm/Options.td +++ b/lld/wasm/Options.td @@ -256,6 +256,8 @@ // LTO-related options. def lto_O: JJ<"lto-O">, MetaVarName<"">, HelpText<"Optimization level for LTO">; +def lto_CGO: JJ<"lto-CGO">, MetaVarName<"">, + HelpText<"Codegen optimization level for LTO">; def lto_partitions: JJ<"lto-partitions=">, HelpText<"Number of LTO codegen partitions">; def disable_verify: F<"disable-verify">;