@@ -43,42 +43,42 @@ using namespace llvm::ELF;
43
43
using namespace lld ;
44
44
using namespace lld ::elf;
45
45
46
- static std::string getThinLTOOutputFile (StringRef modulePath) {
47
- return lto::getThinLTOOutputFile (modulePath, config-> thinLTOPrefixReplaceOld ,
48
- config-> thinLTOPrefixReplaceNew );
46
+ static std::string getThinLTOOutputFile (Ctx &ctx, StringRef modulePath) {
47
+ return lto::getThinLTOOutputFile (modulePath, ctx. arg . thinLTOPrefixReplaceOld ,
48
+ ctx. arg . thinLTOPrefixReplaceNew );
49
49
}
50
50
51
- static lto::Config createConfig () {
51
+ static lto::Config createConfig (Ctx &ctx ) {
52
52
lto::Config c;
53
53
54
54
// LLD supports the new relocations and address-significance tables.
55
55
c.Options = initTargetOptionsFromCodeGenFlags ();
56
56
c.Options .EmitAddrsig = true ;
57
- for (StringRef C : config-> mllvmOpts )
57
+ for (StringRef C : ctx. arg . mllvmOpts )
58
58
c.MllvmArgs .emplace_back (C.str ());
59
59
60
60
// Always emit a section per function/datum with LTO.
61
61
c.Options .FunctionSections = true ;
62
62
c.Options .DataSections = true ;
63
63
64
- c.Options .BBAddrMap = config-> ltoBBAddrMap ;
64
+ c.Options .BBAddrMap = ctx. arg . ltoBBAddrMap ;
65
65
66
66
// Check if basic block sections must be used.
67
67
// Allowed values for --lto-basic-block-sections are "all", "labels",
68
68
// "<file name specifying basic block ids>", or none. This is the equivalent
69
69
// of -fbasic-block-sections= flag in clang.
70
- if (!config-> ltoBasicBlockSections .empty ()) {
71
- if (config-> ltoBasicBlockSections == " all" ) {
70
+ if (!ctx. arg . ltoBasicBlockSections .empty ()) {
71
+ if (ctx. arg . ltoBasicBlockSections == " all" ) {
72
72
c.Options .BBSections = BasicBlockSection::All;
73
- } else if (config-> ltoBasicBlockSections == " labels" ) {
73
+ } else if (ctx. arg . ltoBasicBlockSections == " labels" ) {
74
74
c.Options .BBSections = BasicBlockSection::Labels;
75
- } else if (config-> ltoBasicBlockSections == " none" ) {
75
+ } else if (ctx. arg . ltoBasicBlockSections == " none" ) {
76
76
c.Options .BBSections = BasicBlockSection::None;
77
77
} else {
78
78
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
79
- MemoryBuffer::getFile (config-> ltoBasicBlockSections .str ());
79
+ MemoryBuffer::getFile (ctx. arg . ltoBasicBlockSections .str ());
80
80
if (!MBOrErr) {
81
- error (" cannot open " + config-> ltoBasicBlockSections + " :" +
81
+ error (" cannot open " + ctx. arg . ltoBasicBlockSections + " :" +
82
82
MBOrErr.getError ().message ());
83
83
} else {
84
84
c.Options .BBSectionsFuncListBuf = std::move (*MBOrErr);
@@ -88,114 +88,114 @@ static lto::Config createConfig() {
88
88
}
89
89
90
90
c.Options .UniqueBasicBlockSectionNames =
91
- config-> ltoUniqueBasicBlockSectionNames ;
91
+ ctx. arg . ltoUniqueBasicBlockSectionNames ;
92
92
93
93
if (auto relocModel = getRelocModelFromCMModel ())
94
94
c.RelocModel = *relocModel;
95
- else if (config-> relocatable )
95
+ else if (ctx. arg . relocatable )
96
96
c.RelocModel = std::nullopt;
97
- else if (config-> isPic )
97
+ else if (ctx. arg . isPic )
98
98
c.RelocModel = Reloc::PIC_;
99
99
else
100
100
c.RelocModel = Reloc::Static;
101
101
102
102
c.CodeModel = getCodeModelFromCMModel ();
103
- c.DisableVerify = config-> disableVerify ;
103
+ c.DisableVerify = ctx. arg . disableVerify ;
104
104
c.DiagHandler = diagnosticHandler;
105
- c.OptLevel = config-> ltoo ;
105
+ c.OptLevel = ctx. arg . ltoo ;
106
106
c.CPU = getCPUStr ();
107
107
c.MAttrs = getMAttrs ();
108
- c.CGOptLevel = config-> ltoCgo ;
108
+ c.CGOptLevel = ctx. arg . ltoCgo ;
109
109
110
110
c.PTO .LoopVectorization = c.OptLevel > 1 ;
111
111
c.PTO .SLPVectorization = c.OptLevel > 1 ;
112
112
113
113
// Set up a custom pipeline if we've been asked to.
114
- c.OptPipeline = std::string (config-> ltoNewPmPasses );
115
- c.AAPipeline = std::string (config-> ltoAAPipeline );
114
+ c.OptPipeline = std::string (ctx. arg . ltoNewPmPasses );
115
+ c.AAPipeline = std::string (ctx. arg . ltoAAPipeline );
116
116
117
117
// Set up optimization remarks if we've been asked to.
118
- c.RemarksFilename = std::string (config-> optRemarksFilename );
119
- c.RemarksPasses = std::string (config-> optRemarksPasses );
120
- c.RemarksWithHotness = config-> optRemarksWithHotness ;
121
- c.RemarksHotnessThreshold = config-> optRemarksHotnessThreshold ;
122
- c.RemarksFormat = std::string (config-> optRemarksFormat );
118
+ c.RemarksFilename = std::string (ctx. arg . optRemarksFilename );
119
+ c.RemarksPasses = std::string (ctx. arg . optRemarksPasses );
120
+ c.RemarksWithHotness = ctx. arg . optRemarksWithHotness ;
121
+ c.RemarksHotnessThreshold = ctx. arg . optRemarksHotnessThreshold ;
122
+ c.RemarksFormat = std::string (ctx. arg . optRemarksFormat );
123
123
124
124
// Set up output file to emit statistics.
125
- c.StatsFile = std::string (config-> optStatsFilename );
125
+ c.StatsFile = std::string (ctx. arg . optStatsFilename );
126
126
127
- c.SampleProfile = std::string (config-> ltoSampleProfile );
128
- for (StringRef pluginFn : config-> passPlugins )
127
+ c.SampleProfile = std::string (ctx. arg . ltoSampleProfile );
128
+ for (StringRef pluginFn : ctx. arg . passPlugins )
129
129
c.PassPlugins .push_back (std::string (pluginFn));
130
- c.DebugPassManager = config-> ltoDebugPassManager ;
131
- c.DwoDir = std::string (config-> dwoDir );
130
+ c.DebugPassManager = ctx. arg . ltoDebugPassManager ;
131
+ c.DwoDir = std::string (ctx. arg . dwoDir );
132
132
133
- c.HasWholeProgramVisibility = config-> ltoWholeProgramVisibility ;
133
+ c.HasWholeProgramVisibility = ctx. arg . ltoWholeProgramVisibility ;
134
134
c.ValidateAllVtablesHaveTypeInfos =
135
- config-> ltoValidateAllVtablesHaveTypeInfos ;
135
+ ctx. arg . ltoValidateAllVtablesHaveTypeInfos ;
136
136
c.AllVtablesHaveTypeInfos = ctx.ltoAllVtablesHaveTypeInfos ;
137
- c.AlwaysEmitRegularLTOObj = !config-> ltoObjPath .empty ();
137
+ c.AlwaysEmitRegularLTOObj = !ctx. arg . ltoObjPath .empty ();
138
138
c.KeepSymbolNameCopies = false ;
139
139
140
- for (const llvm::StringRef &name : config-> thinLTOModulesToCompile )
140
+ for (const llvm::StringRef &name : ctx. arg . thinLTOModulesToCompile )
141
141
c.ThinLTOModulesToCompile .emplace_back (name);
142
142
143
- c.TimeTraceEnabled = config-> timeTraceEnabled ;
144
- c.TimeTraceGranularity = config-> timeTraceGranularity ;
143
+ c.TimeTraceEnabled = ctx. arg . timeTraceEnabled ;
144
+ c.TimeTraceGranularity = ctx. arg . timeTraceGranularity ;
145
145
146
- c.CSIRProfile = std::string (config-> ltoCSProfileFile );
147
- c.RunCSIRInstr = config-> ltoCSProfileGenerate ;
148
- c.PGOWarnMismatch = config-> ltoPGOWarnMismatch ;
146
+ c.CSIRProfile = std::string (ctx. arg . ltoCSProfileFile );
147
+ c.RunCSIRInstr = ctx. arg . ltoCSProfileGenerate ;
148
+ c.PGOWarnMismatch = ctx. arg . ltoPGOWarnMismatch ;
149
149
150
- if (config-> emitLLVM ) {
151
- c.PreCodeGenModuleHook = [](size_t task, const Module &m) {
150
+ if (ctx. arg . emitLLVM ) {
151
+ c.PreCodeGenModuleHook = [&ctx ](size_t task, const Module &m) {
152
152
if (std::unique_ptr<raw_fd_ostream> os =
153
- openLTOOutputFile (config-> outputFile ))
153
+ openLTOOutputFile (ctx. arg . outputFile ))
154
154
WriteBitcodeToFile (m, *os, false );
155
155
return false ;
156
156
};
157
157
}
158
158
159
- if (config-> ltoEmitAsm ) {
159
+ if (ctx. arg . ltoEmitAsm ) {
160
160
c.CGFileType = CodeGenFileType::AssemblyFile;
161
161
c.Options .MCOptions .AsmVerbose = true ;
162
162
}
163
163
164
- if (!config-> saveTempsArgs .empty ())
165
- checkError (c.addSaveTemps (config-> outputFile .str () + " ." ,
164
+ if (!ctx. arg . saveTempsArgs .empty ())
165
+ checkError (c.addSaveTemps (ctx. arg . outputFile .str () + " ." ,
166
166
/* UseInputModulePath*/ true ,
167
- config-> saveTempsArgs ));
167
+ ctx. arg . saveTempsArgs ));
168
168
return c;
169
169
}
170
170
171
- BitcodeCompiler::BitcodeCompiler () {
171
+ BitcodeCompiler::BitcodeCompiler (Ctx &ctx) : ctx(ctx ) {
172
172
// Initialize indexFile.
173
- if (!config-> thinLTOIndexOnlyArg .empty ())
174
- indexFile = openFile (config-> thinLTOIndexOnlyArg );
173
+ if (!ctx. arg . thinLTOIndexOnlyArg .empty ())
174
+ indexFile = openFile (ctx. arg . thinLTOIndexOnlyArg );
175
175
176
176
// Initialize ltoObj.
177
177
lto::ThinBackend backend;
178
178
auto onIndexWrite = [&](StringRef s) { thinIndices.erase (s); };
179
- if (config-> thinLTOIndexOnly ) {
179
+ if (ctx. arg . thinLTOIndexOnly ) {
180
180
backend = lto::createWriteIndexesThinBackend (
181
- std::string (config-> thinLTOPrefixReplaceOld ),
182
- std::string (config-> thinLTOPrefixReplaceNew ),
183
- std::string (config-> thinLTOPrefixReplaceNativeObject ),
184
- config-> thinLTOEmitImportsFiles , indexFile.get (), onIndexWrite);
181
+ std::string (ctx. arg . thinLTOPrefixReplaceOld ),
182
+ std::string (ctx. arg . thinLTOPrefixReplaceNew ),
183
+ std::string (ctx. arg . thinLTOPrefixReplaceNativeObject ),
184
+ ctx. arg . thinLTOEmitImportsFiles , indexFile.get (), onIndexWrite);
185
185
} else {
186
186
backend = lto::createInProcessThinBackend (
187
- llvm::heavyweight_hardware_concurrency (config-> thinLTOJobs ),
188
- onIndexWrite, config-> thinLTOEmitIndexFiles ,
189
- config-> thinLTOEmitImportsFiles );
187
+ llvm::heavyweight_hardware_concurrency (ctx. arg . thinLTOJobs ),
188
+ onIndexWrite, ctx. arg . thinLTOEmitIndexFiles ,
189
+ ctx. arg . thinLTOEmitImportsFiles );
190
190
}
191
191
192
192
constexpr llvm::lto::LTO::LTOKind ltoModes[3 ] =
193
193
{llvm::lto::LTO::LTOKind::LTOK_UnifiedThin,
194
194
llvm::lto::LTO::LTOKind::LTOK_UnifiedRegular,
195
195
llvm::lto::LTO::LTOKind::LTOK_Default};
196
- ltoObj = std::make_unique<lto::LTO>(
197
- createConfig (), backend, config-> ltoPartitions ,
198
- ltoModes[config-> ltoKind ]);
196
+ ltoObj = std::make_unique<lto::LTO>(createConfig (ctx), backend,
197
+ ctx. arg . ltoPartitions ,
198
+ ltoModes[ctx. arg . ltoKind ]);
199
199
200
200
// Initialize usedStartStop.
201
201
if (ctx.bitcodeFiles .empty ())
@@ -291,7 +291,7 @@ static void thinLTOCreateEmptyIndexFiles() {
291
291
if (linkedBitCodeFiles.contains (f->getName ()))
292
292
continue ;
293
293
std::string path =
294
- replaceThinLTOSuffix (getThinLTOOutputFile (f->obj ->getName ()));
294
+ replaceThinLTOSuffix (getThinLTOOutputFile (ctx, f->obj ->getName ()));
295
295
std::unique_ptr<raw_fd_ostream> os = openFile (path + " .thinlto.bc" );
296
296
if (!os)
297
297
continue ;
@@ -316,8 +316,8 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
316
316
// to cache native object files for ThinLTO incremental builds. If a path was
317
317
// specified, configure LTO to use it as the cache directory.
318
318
FileCache cache;
319
- if (!config-> thinLTOCacheDir .empty ())
320
- cache = check (localCache (" ThinLTO" , " Thin" , config-> thinLTOCacheDir ,
319
+ if (!ctx. arg . thinLTOCacheDir .empty ())
320
+ cache = check (localCache (" ThinLTO" , " Thin" , ctx. arg . thinLTOCacheDir ,
321
321
[&](size_t task, const Twine &moduleName,
322
322
std::unique_ptr<MemoryBuffer> mb) {
323
323
files[task] = std::move (mb);
@@ -334,21 +334,21 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
334
334
cache));
335
335
336
336
// Emit empty index files for non-indexed files but not in single-module mode.
337
- if (config-> thinLTOModulesToCompile .empty ()) {
337
+ if (ctx. arg . thinLTOModulesToCompile .empty ()) {
338
338
for (StringRef s : thinIndices) {
339
- std::string path = getThinLTOOutputFile (s);
339
+ std::string path = getThinLTOOutputFile (ctx, s);
340
340
openFile (path + " .thinlto.bc" );
341
- if (config-> thinLTOEmitImportsFiles )
341
+ if (ctx. arg . thinLTOEmitImportsFiles )
342
342
openFile (path + " .imports" );
343
343
}
344
344
}
345
345
346
- if (config-> thinLTOEmitIndexFiles )
346
+ if (ctx. arg . thinLTOEmitIndexFiles )
347
347
thinLTOCreateEmptyIndexFiles ();
348
348
349
- if (config-> thinLTOIndexOnly ) {
350
- if (!config-> ltoObjPath .empty ())
351
- saveBuffer (buf[0 ].second , config-> ltoObjPath );
349
+ if (ctx. arg . thinLTOIndexOnly ) {
350
+ if (!ctx. arg . ltoObjPath .empty ())
351
+ saveBuffer (buf[0 ].second , ctx. arg . ltoObjPath );
352
352
353
353
// ThinLTO with index only option is required to generate only the index
354
354
// files. After that, we exit from linker and ThinLTO backend runs in a
@@ -358,18 +358,18 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
358
358
return {};
359
359
}
360
360
361
- if (!config-> thinLTOCacheDir .empty ())
362
- pruneCache (config-> thinLTOCacheDir , config-> thinLTOCachePolicy , files);
361
+ if (!ctx. arg . thinLTOCacheDir .empty ())
362
+ pruneCache (ctx. arg . thinLTOCacheDir , ctx. arg . thinLTOCachePolicy , files);
363
363
364
- if (!config-> ltoObjPath .empty ()) {
365
- saveBuffer (buf[0 ].second , config-> ltoObjPath );
364
+ if (!ctx. arg . ltoObjPath .empty ()) {
365
+ saveBuffer (buf[0 ].second , ctx. arg . ltoObjPath );
366
366
for (unsigned i = 1 ; i != maxTasks; ++i)
367
- saveBuffer (buf[i].second , config-> ltoObjPath + Twine (i));
367
+ saveBuffer (buf[i].second , ctx. arg . ltoObjPath + Twine (i));
368
368
}
369
369
370
- bool savePrelink = config-> saveTempsArgs .contains (" prelink" );
370
+ bool savePrelink = ctx. arg . saveTempsArgs .contains (" prelink" );
371
371
std::vector<InputFile *> ret;
372
- const char *ext = config-> ltoEmitAsm ? " .s" : " .o" ;
372
+ const char *ext = ctx. arg . ltoEmitAsm ? " .s" : " .o" ;
373
373
for (unsigned i = 0 ; i != maxTasks; ++i) {
374
374
StringRef bitcodeFilePath;
375
375
StringRef objBuf;
@@ -392,7 +392,7 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
392
392
StringRef ltoObjName;
393
393
if (bitcodeFilePath == " ld-temp.o" ) {
394
394
ltoObjName =
395
- saver ().save (Twine (config-> outputFile ) + " .lto" +
395
+ saver ().save (Twine (ctx. arg . outputFile ) + " .lto" +
396
396
(i == 0 ? Twine (" " ) : Twine (' .' ) + Twine (i)) + ext);
397
397
} else {
398
398
StringRef directory = sys::path::parent_path (bitcodeFilePath);
@@ -402,16 +402,16 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
402
402
StringRef baseName = bitcodeFilePath.ends_with (" )" )
403
403
? sys::path::filename (bitcodeFilePath)
404
404
: sys::path::stem (bitcodeFilePath);
405
- StringRef outputFileBaseName = sys::path::filename (config-> outputFile );
405
+ StringRef outputFileBaseName = sys::path::filename (ctx. arg . outputFile );
406
406
SmallString<256 > path;
407
407
sys::path::append (path, directory,
408
408
outputFileBaseName + " .lto." + baseName + ext);
409
409
sys::path::remove_dots (path, true );
410
410
ltoObjName = saver ().save (path.str ());
411
411
}
412
- if (savePrelink || config-> ltoEmitAsm )
412
+ if (savePrelink || ctx. arg . ltoEmitAsm )
413
413
saveBuffer (buf[i].second , ltoObjName);
414
- if (!config-> ltoEmitAsm )
414
+ if (!ctx. arg . ltoEmitAsm )
415
415
ret.push_back (createObjFile (MemoryBufferRef (objBuf, ltoObjName)));
416
416
}
417
417
return ret;
0 commit comments