Skip to content

Commit d60c2ad

Browse files
committed
Embed the command line arguments during LTO
1 parent 2e81ac2 commit d60c2ad

File tree

18 files changed

+60
-38
lines changed

18 files changed

+60
-38
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,7 @@ static void runThinLTOBackend(
12081208
Conf.CPU = TOpts.CPU;
12091209
Conf.CodeModel = getCodeModel(CGOpts);
12101210
Conf.MAttrs = TOpts.Features;
1211+
Conf.EmbedCmdArgs = CGOpts.CmdArgs;
12111212
Conf.RelocModel = CGOpts.RelocationModel;
12121213
std::optional<CodeGenOptLevel> OptLevelOrNone =
12131214
CodeGenOpt::getLevel(CGOpts.OptimizationLevel);
@@ -1269,7 +1270,7 @@ static void runThinLTOBackend(
12691270
if (Error E =
12701271
thinBackend(Conf, -1, AddStream, *M, *CombinedIndex, ImportList,
12711272
ModuleToDefinedGVSummaries[M->getModuleIdentifier()],
1272-
/* ModuleMap */ nullptr, CGOpts.CmdArgs)) {
1273+
/* ModuleMap */ nullptr)) {
12731274
handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
12741275
errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
12751276
});

lld/COFF/Driver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,6 +1447,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
14471447
// Parse command line options.
14481448
ArgParser parser(ctx);
14491449
opt::InputArgList args = parser.parse(argsArr);
1450+
commonContext().storeCmdArgs(args);
14501451

14511452
// Initialize time trace profiler.
14521453
config->timeTraceEnabled = args.hasArg(OPT_time_trace_eq);

lld/COFF/LTO.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ lto::Config BitcodeCompiler::createConfig() {
5252
lto::Config c;
5353
c.Options = initTargetOptionsFromCodeGenFlags();
5454
c.Options.EmitAddrsig = true;
55-
for (StringRef C : ctx.config.mllvmOpts)
56-
c.MllvmArgs.emplace_back(C.str());
55+
c.EmbedCmdArgs = commonContext().cmdArgs;
5756

5857
// Always emit a section per function/datum with LTO. LLVM LTO should get most
5958
// of the benefit of linker GC, but there are still opportunities for ICF.

lld/Common/CommonLinkerContext.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ CommonLinkerContext::~CommonLinkerContext() {
3737
lctx = nullptr;
3838
}
3939

40+
void CommonLinkerContext::storeCmdArgs(const llvm::opt::ArgList &args) {
41+
cmdArgs.clear();
42+
for (const llvm::opt::Arg *arg : args) {
43+
StringRef str(args.getArgString(arg->getIndex()));
44+
cmdArgs.insert(cmdArgs.end(), str.begin(), str.end());
45+
cmdArgs.push_back('\0');
46+
}
47+
}
48+
4049
CommonLinkerContext &lld::commonContext() {
4150
assert(lctx);
4251
return *lctx;

lld/ELF/Driver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ constexpr const char *saveTempsValues[] = {
573573
void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
574574
ELFOptTable parser;
575575
opt::InputArgList args = parser.parse(argsArr.slice(1));
576+
commonContext().storeCmdArgs(args);
576577

577578
// Interpret these flags early because error()/warn() depend on them.
578579
errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20);

lld/ELF/LTO.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ static lto::Config createConfig() {
5454
// LLD supports the new relocations and address-significance tables.
5555
c.Options = initTargetOptionsFromCodeGenFlags();
5656
c.Options.EmitAddrsig = true;
57-
for (StringRef C : config->mllvmOpts)
58-
c.MllvmArgs.emplace_back(C.str());
57+
c.EmbedCmdArgs = commonContext().cmdArgs;
5958

6059
// Always emit a section per function/datum with LTO.
6160
c.Options.FunctionSections = true;

lld/MachO/Driver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,7 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
14371437

14381438
MachOOptTable parser;
14391439
InputArgList args = parser.parse(argsArr.slice(1));
1440+
commonContext().storeCmdArgs(args);
14401441

14411442
ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now "
14421443
"(use --error-limit=0 to see all errors)";

lld/MachO/LTO.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ static lto::Config createConfig() {
4242
lto::Config c;
4343
c.Options = initTargetOptionsFromCodeGenFlags();
4444
c.Options.EmitAddrsig = config->icfLevel == ICFLevel::safe;
45-
for (StringRef C : config->mllvmOpts)
46-
c.MllvmArgs.emplace_back(C.str());
45+
c.EmbedCmdArgs = commonContext().cmdArgs;
4746
c.CodeModel = getCodeModelFromCMModel();
4847
c.CPU = getCPUStr();
4948
c.MAttrs = getMAttrs();

lld/MinGW/Driver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
174174

175175
MinGWOptTable parser;
176176
opt::InputArgList args = parser.parse(argsArr.slice(1));
177+
commonContext().storeCmdArgs(args);
177178

178179
if (errorCount())
179180
return false;

lld/include/lld/Common/CommonLinkerContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "lld/Common/ErrorHandler.h"
2323
#include "lld/Common/Memory.h"
24+
#include "llvm/Option/ArgList.h"
2425
#include "llvm/Support/StringSaver.h"
2526

2627
namespace llvm {
@@ -33,12 +34,14 @@ class CommonLinkerContext {
3334
public:
3435
CommonLinkerContext();
3536
virtual ~CommonLinkerContext();
37+
void storeCmdArgs(const llvm::opt::ArgList &args);
3638

3739
static void destroy();
3840

3941
llvm::BumpPtrAllocator bAlloc;
4042
llvm::StringSaver saver{bAlloc};
4143
llvm::DenseMap<void *, SpecificAllocBase *> instances;
44+
std::vector<uint8_t> cmdArgs;
4245

4346
ErrorHandler e;
4447
};

lld/wasm/Driver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,7 @@ static void checkZOptions(opt::InputArgList &args) {
11461146
void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
11471147
WasmOptTable parser;
11481148
opt::InputArgList args = parser.parse(argsArr.slice(1));
1149+
commonContext().storeCmdArgs(args);
11491150

11501151
// Interpret these flags early because error()/warn() depend on them.
11511152
errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20);

lld/wasm/LTO.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "InputFiles.h"
1212
#include "Symbols.h"
1313
#include "lld/Common/Args.h"
14+
#include "lld/Common/CommonLinkerContext.h"
1415
#include "lld/Common/ErrorHandler.h"
1516
#include "lld/Common/Strings.h"
1617
#include "lld/Common/TargetOptionsCommandFlags.h"
@@ -40,6 +41,7 @@ using namespace llvm;
4041
namespace lld::wasm {
4142
static std::unique_ptr<lto::LTO> createLTO() {
4243
lto::Config c;
44+
c.EmbedCmdArgs = commonContext().cmdArgs;
4345
c.Options = initTargetOptionsFromCodeGenFlags();
4446

4547
// Always emit a section per function/data with LTO.

llvm/include/llvm/LTO/Config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ struct Config {
4848
std::string CPU;
4949
TargetOptions Options;
5050
std::vector<std::string> MAttrs;
51-
std::vector<std::string> MllvmArgs;
51+
std::vector<uint8_t> EmbedCmdArgs;
5252
std::vector<std::string> PassPlugins;
5353
/// For adding passes that run right before codegen.
5454
std::function<void(legacy::PassManager &)> PreCodeGenPassesHook;

llvm/include/llvm/LTO/LTOBackend.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ namespace lto {
3636
/// Runs middle-end LTO optimizations on \p Mod.
3737
bool opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
3838
bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
39-
const ModuleSummaryIndex *ImportSummary,
40-
const std::vector<uint8_t> &CmdArgs);
39+
const ModuleSummaryIndex *ImportSummary);
4140

4241
/// Runs a regular LTO backend. The regular LTO backend can also act as the
4342
/// regular LTO phase of ThinLTO, which may need to access the combined index.
@@ -55,8 +54,7 @@ Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream,
5554
Module &M, const ModuleSummaryIndex &CombinedIndex,
5655
const FunctionImporter::ImportMapTy &ImportList,
5756
const GVSummaryMapTy &DefinedGlobals,
58-
MapVector<StringRef, BitcodeModule> *ModuleMap,
59-
const std::vector<uint8_t> &CmdArgs = std::vector<uint8_t>());
57+
MapVector<StringRef, BitcodeModule> *ModuleMap);
6058

6159
Error finalizeOptimizationRemarks(
6260
std::unique_ptr<ToolOutputFile> DiagOutputFile);

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#include "llvm/Support/Endian.h"
6666
#include "llvm/Support/Error.h"
6767
#include "llvm/Support/ErrorHandling.h"
68+
#include "llvm/Support/FileSystem.h"
6869
#include "llvm/Support/MathExtras.h"
6970
#include "llvm/Support/SHA1.h"
7071
#include "llvm/Support/raw_ostream.h"
@@ -5201,6 +5202,19 @@ void llvm::embedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf,
52015202
if (Used)
52025203
Used->eraseFromParent();
52035204

5205+
// Add the command line and working directory to the module flags
5206+
if (!CmdArgs.empty()) {
5207+
M.setModuleFlag(llvm::Module::Warning, "embed.cmd",
5208+
llvm::MDString::get(M.getContext(),
5209+
StringRef((const char *)CmdArgs.data(),
5210+
CmdArgs.size())));
5211+
SmallString<256> cwd;
5212+
if (!llvm::sys::fs::current_path(cwd)) {
5213+
M.setModuleFlag(llvm::Module::Warning, "embed.cwd",
5214+
llvm::MDString::get(M.getContext(), cwd));
5215+
}
5216+
}
5217+
52045218
// Embed the bitcode for the llvm module.
52055219
std::string Data;
52065220
ArrayRef<uint8_t> ModuleData;

llvm/lib/LTO/LTO.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,7 @@ void llvm::computeLTOCacheKey(
140140
AddUnsigned(*Conf.CodeModel);
141141
else
142142
AddUnsigned(-1);
143-
for (const auto &S : Conf.MllvmArgs)
144-
AddString(S);
143+
Hasher.update(Conf.EmbedCmdArgs);
145144
AddUnsigned(static_cast<int>(Conf.CGOptLevel));
146145
AddUnsigned(static_cast<int>(Conf.CGFileType));
147146
AddUnsigned(Conf.OptLevel);

llvm/lib/LTO/LTOBackend.cpp

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -342,24 +342,16 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
342342

343343
bool lto::opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
344344
bool IsThinLTO, ModuleSummaryIndex *ExportSummary,
345-
const ModuleSummaryIndex *ImportSummary,
346-
const std::vector<uint8_t> &CmdArgs) {
345+
const ModuleSummaryIndex *ImportSummary) {
347346
if (EmbedBitcode == LTOBitcodeEmbedding::EmbedPostMergePreOptimized) {
348-
// FIXME: the motivation for capturing post-merge bitcode and command line
349-
// is replicating the compilation environment from bitcode, without needing
350-
// to understand the dependencies (the functions to be imported). This
351-
// assumes a clang - based invocation, case in which we have the command
352-
// line.
353-
// It's not very clear how the above motivation would map in the
354-
// linker-based case, so we currently don't plumb the command line args in
355-
// that case.
356-
if (CmdArgs.empty())
347+
if (Conf.EmbedCmdArgs.empty())
357348
LLVM_DEBUG(
358349
dbgs() << "Post-(Thin)LTO merge bitcode embedding was requested, but "
359350
"command line arguments are not available");
360351
llvm::embedBitcodeInModule(Mod, llvm::MemoryBufferRef(),
361-
/*EmbedBitcode*/ true, /*EmbedCmdline*/ true,
362-
/*Cmdline*/ CmdArgs);
352+
/*EmbedBitcode*/ true,
353+
/*EmbedCmdline*/ true,
354+
/*CmdArgs*/ Conf.EmbedCmdArgs);
363355
}
364356
// FIXME: Plumb the combined index into the new pass manager.
365357
runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO, ExportSummary,
@@ -373,11 +365,17 @@ static void codegen(const Config &Conf, TargetMachine *TM,
373365
if (Conf.PreCodeGenModuleHook && !Conf.PreCodeGenModuleHook(Task, Mod))
374366
return;
375367

376-
if (EmbedBitcode == LTOBitcodeEmbedding::EmbedOptimized)
368+
if (EmbedBitcode == LTOBitcodeEmbedding::EmbedOptimized) {
369+
if (Conf.EmbedCmdArgs.empty())
370+
LLVM_DEBUG(
371+
dbgs()
372+
<< "Post-(Thin)LTO optimize bitcode embedding was requested, but "
373+
"command line arguments are not available");
377374
llvm::embedBitcodeInModule(Mod, llvm::MemoryBufferRef(),
378375
/*EmbedBitcode*/ true,
379-
/*EmbedCmdline*/ false,
380-
/*CmdArgs*/ std::vector<uint8_t>());
376+
/*EmbedCmdline*/ true,
377+
/*CmdArgs*/ Conf.EmbedCmdArgs);
378+
}
381379

382380
std::unique_ptr<ToolOutputFile> DwoOut;
383381
SmallString<1024> DwoFile(Conf.SplitDwarfOutput);
@@ -513,8 +511,7 @@ Error lto::backend(const Config &C, AddStreamFn AddStream,
513511
LLVM_DEBUG(dbgs() << "Running regular LTO\n");
514512
if (!C.CodeGenOnly) {
515513
if (!opt(C, TM.get(), 0, Mod, /*IsThinLTO=*/false,
516-
/*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
517-
/*CmdArgs*/ std::vector<uint8_t>()))
514+
/*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr))
518515
return Error::success();
519516
}
520517

@@ -552,8 +549,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
552549
Module &Mod, const ModuleSummaryIndex &CombinedIndex,
553550
const FunctionImporter::ImportMapTy &ImportList,
554551
const GVSummaryMapTy &DefinedGlobals,
555-
MapVector<StringRef, BitcodeModule> *ModuleMap,
556-
const std::vector<uint8_t> &CmdArgs) {
552+
MapVector<StringRef, BitcodeModule> *ModuleMap) {
557553
Expected<const Target *> TOrErr = initAndLookupTarget(Conf, Mod);
558554
if (!TOrErr)
559555
return TOrErr.takeError();
@@ -586,8 +582,7 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
586582
[&](Module &Mod, TargetMachine *TM,
587583
std::unique_ptr<ToolOutputFile> DiagnosticOutputFile) {
588584
if (!opt(Conf, TM, Task, Mod, /*IsThinLTO=*/true,
589-
/*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex,
590-
CmdArgs))
585+
/*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex))
591586
return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
592587

593588
codegen(Conf, TM, AddStream, Task, Mod, CombinedIndex);

llvm/lib/LTO/LTOCodeGenerator.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,8 +637,7 @@ bool LTOCodeGenerator::optimize() {
637637
ModuleSummaryIndex CombinedIndex(false);
638638
TargetMach = createTargetMachine();
639639
if (!opt(Config, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false,
640-
/*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr,
641-
/*CmdArgs*/ std::vector<uint8_t>())) {
640+
/*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr)) {
642641
emitError("LTO middle-end optimizations failed");
643642
return false;
644643
}

0 commit comments

Comments
 (0)