Skip to content

Commit 45ee0a9

Browse files
committed
[LLD] Add --lto-CGO[0-3] option
Allow controlling the CodeGenOpt::Level independent of the LTO optimization level in LLD via new options for the COFF, ELF, MachO, and wasm frontends to lld. Most are spelled as --lto-CGO[0-3], but COFF is spelled as -opt:lldltocgo=[0-3]. See D57422 for discussion surrounding the issue of how to set the CG opt level. The ultimate goal is to let each function control its CG opt level, but until then the current default means it is impossible to specify a CG opt level lower than 2 while using LTO. This option gives the user a means to control it for as long as it is not handled on a per-function basis. Reviewed By: MaskRay, #lld-macho, int3 Differential Revision: https://reviews.llvm.org/D141970
1 parent 3cf7f22 commit 45ee0a9

File tree

21 files changed

+174
-17
lines changed

21 files changed

+174
-17
lines changed

lld/COFF/Config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ struct Configuration {
162162

163163
// Used for /opt:lldlto=N
164164
unsigned ltoo = 2;
165+
// Used for /opt:lldltocgo=N
166+
std::optional<unsigned> ltoCgo;
165167

166168
// Used for /opt:lldltojobs=N
167169
std::string thinLTOJobs;

lld/COFF/Driver.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1768,6 +1768,10 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
17681768
} else if (s.consume_front("lldlto=")) {
17691769
if (s.getAsInteger(10, config->ltoo) || config->ltoo > 3)
17701770
error("/opt:lldlto: invalid optimization level: " + s);
1771+
} else if (s.consume_front("lldltocgo=")) {
1772+
config->ltoCgo.emplace();
1773+
if (s.getAsInteger(10, *config->ltoCgo) || *config->ltoCgo > 3)
1774+
error("/opt:lldltocgo: invalid codegen optimization level: " + s);
17711775
} else if (s.consume_front("lldltojobs=")) {
17721776
if (!get_threadpool_strategy(s))
17731777
error("/opt:lldltojobs: invalid job count: " + s);

lld/COFF/LTO.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ lto::Config BitcodeCompiler::createConfig() {
8888
c.OptLevel = ctx.config.ltoo;
8989
c.CPU = getCPUStr();
9090
c.MAttrs = getMAttrs();
91-
c.CGOptLevel = args::getCGOptLevel(ctx.config.ltoo);
91+
std::optional<CodeGenOpt::Level> optLevelOrNone = CodeGenOpt::getLevel(
92+
ctx.config.ltoCgo.value_or(args::getCGOptLevel(ctx.config.ltoo)));
93+
assert(optLevelOrNone && "Invalid optimization level!");
94+
c.CGOptLevel = *optLevelOrNone;
9295
c.AlwaysEmitRegularLTOObj = !ctx.config.ltoObjPath.empty();
9396
c.DebugPassManager = ctx.config.ltoDebugPassManager;
9497
c.CSIRProfile = std::string(ctx.config.ltoCSProfileFile);

lld/Common/Args.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,8 @@ using namespace lld;
1919

2020
// TODO(sbc): Remove this once CGOptLevel can be set completely based on bitcode
2121
// function metadata.
22-
CodeGenOpt::Level lld::args::getCGOptLevel(int optLevelLTO) {
23-
if (optLevelLTO == 3)
24-
return CodeGenOpt::Aggressive;
25-
assert(optLevelLTO < 3);
26-
return CodeGenOpt::Default;
22+
int lld::args::getCGOptLevel(int optLevelLTO) {
23+
return std::clamp(optLevelLTO, 2, 3);
2724
}
2825

2926
static int64_t getInteger(opt::InputArgList &args, unsigned key,

lld/ELF/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ struct Config {
317317
uint64_t zStackSize;
318318
unsigned ltoPartitions;
319319
unsigned ltoo;
320+
llvm::CodeGenOpt::Level ltoCgo;
320321
unsigned optimize;
321322
StringRef thinLTOJobs;
322323
unsigned timeTraceGranularity;

lld/ELF/Driver.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,14 @@ static void readConfigs(opt::InputArgList &args) {
11391139
args.hasFlag(OPT_lto_whole_program_visibility,
11401140
OPT_no_lto_whole_program_visibility, false);
11411141
config->ltoo = args::getInteger(args, OPT_lto_O, 2);
1142+
if (config->ltoo > 3)
1143+
error("invalid optimization level for LTO: " + Twine(config->ltoo));
1144+
unsigned ltoCgo =
1145+
args::getInteger(args, OPT_lto_CGO, args::getCGOptLevel(config->ltoo));
1146+
if (auto level = CodeGenOpt::getLevel(ltoCgo))
1147+
config->ltoCgo = *level;
1148+
else
1149+
error("invalid codegen optimization level for LTO: " + Twine(ltoCgo));
11421150
config->ltoObjPath = args.getLastArgValue(OPT_lto_obj_path_eq);
11431151
config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
11441152
config->ltoSampleProfile = args.getLastArgValue(OPT_lto_sample_profile);
@@ -1395,8 +1403,6 @@ static void readConfigs(opt::InputArgList &args) {
13951403
config->thinLTOJobs = arg->getValue();
13961404
config->threadCount = parallel::strategy.compute_thread_count();
13971405

1398-
if (config->ltoo > 3)
1399-
error("invalid optimization level for LTO: " + Twine(config->ltoo));
14001406
if (config->ltoPartitions == 0)
14011407
error("--lto-partitions: number of threads must be > 0");
14021408
if (!get_threadpool_strategy(config->thinLTOJobs))

lld/ELF/LTO.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ static lto::Config createConfig() {
127127
c.OptLevel = config->ltoo;
128128
c.CPU = getCPUStr();
129129
c.MAttrs = getMAttrs();
130-
c.CGOptLevel = args::getCGOptLevel(config->ltoo);
130+
c.CGOptLevel = config->ltoCgo;
131131

132132
c.PTO.LoopVectorization = c.OptLevel > 1;
133133
c.PTO.SLPVectorization = c.OptLevel > 1;

lld/ELF/Options.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,8 @@ def lto_newpm_passes: JJ<"lto-newpm-passes=">,
558558
HelpText<"Passes to run during LTO">;
559559
def lto_O: JJ<"lto-O">, MetaVarName<"<opt-level>">,
560560
HelpText<"Optimization level for LTO">;
561+
def lto_CGO: JJ<"lto-CGO">, MetaVarName<"<cgopt-level>">,
562+
HelpText<"Codegen optimization level for LTO">;
561563
def lto_partitions: JJ<"lto-partitions=">,
562564
HelpText<"Number of LTO codegen partitions">;
563565
def lto_cs_profile_generate: FF<"lto-cs-profile-generate">,

lld/MachO/Config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626

2727
#include <vector>
2828

29+
namespace llvm::CodeGenOpt {
30+
enum Level : int;
31+
} // namespace llvm::CodeGenOpt
32+
2933
namespace lld {
3034
namespace macho {
3135

@@ -165,6 +169,7 @@ struct Configuration {
165169
llvm::StringRef thinLTOJobs;
166170
llvm::StringRef umbrella;
167171
uint32_t ltoo = 2;
172+
llvm::CodeGenOpt::Level ltoCgo;
168173
llvm::CachePruningPolicy thinLTOCachePolicy;
169174
llvm::StringRef thinLTOCacheDir;
170175
llvm::StringRef thinLTOIndexOnlyArg;

lld/MachO/Driver.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,17 @@ bool macho::link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
14211421
target = createTargetInfo(args);
14221422
depTracker = std::make_unique<DependencyTracker>(
14231423
args.getLastArgValue(OPT_dependency_info));
1424+
1425+
config->ltoo = args::getInteger(args, OPT_lto_O, 2);
1426+
if (config->ltoo > 3)
1427+
error("--lto-O: invalid optimization level: " + Twine(config->ltoo));
1428+
unsigned ltoCgo =
1429+
args::getInteger(args, OPT_lto_CGO, args::getCGOptLevel(config->ltoo));
1430+
if (auto level = CodeGenOpt::getLevel(ltoCgo))
1431+
config->ltoCgo = *level;
1432+
else
1433+
error("--lto-CGO: invalid codegen optimization level: " + Twine(ltoCgo));
1434+
14241435
if (errorCount())
14251436
return false;
14261437

@@ -1558,9 +1569,6 @@ bool macho::link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
15581569
config->umbrella = arg->getValue();
15591570
}
15601571
config->ltoObjPath = args.getLastArgValue(OPT_object_path_lto);
1561-
config->ltoo = args::getInteger(args, OPT_lto_O, 2);
1562-
if (config->ltoo > 3)
1563-
error("--lto-O: invalid optimization level: " + Twine(config->ltoo));
15641572
config->thinLTOCacheDir = args.getLastArgValue(OPT_cache_path_lto);
15651573
config->thinLTOCachePolicy = getLTOCachePolicy(args);
15661574
config->thinLTOEmitImportsFiles = args.hasArg(OPT_thinlto_emit_imports_files);

0 commit comments

Comments
 (0)