1
- // ===--- LLVMOpt .cpp ------------ ------------------------------------------===//
1
+ // ===--- swift_llvm_opt_main .cpp ------------------------------------------===//
2
2
//
3
3
// This source file is part of the Swift.org open source project
4
4
//
@@ -74,59 +74,65 @@ static llvm::codegen::RegisterCodeGenFlags CGF;
74
74
// Option Declarations
75
75
// ===----------------------------------------------------------------------===//
76
76
77
- // The OptimizationList is automatically populated with registered passes by the
78
- // PassNameParser.
79
- //
80
- static llvm::cl::list<const llvm::PassInfo *, bool , llvm::PassNameParser>
81
- PassList (llvm::cl::desc(" Optimizations available:" ));
82
-
83
- static llvm::cl::opt<bool >
84
- Optimized (" O" , llvm::cl::desc(" Optimization level O. Similar to swift -O" ));
85
-
86
- // TODO: I wanted to call this 'verify', but some other pass is using this
87
- // option.
88
- static llvm::cl::opt<bool > VerifyEach (
89
- " verify-each" ,
90
- llvm::cl::desc (" Should we spend time verifying that the IR is well "
91
- " formed" ));
92
-
93
- static llvm::cl::opt<std::string>
94
- TargetTriple (" mtriple" ,
95
- llvm::cl::desc (" Override target triple for module" ));
96
-
97
- static llvm::cl::opt<bool >
98
- PrintStats (" print-stats" ,
99
- llvm::cl::desc (" Should LLVM Statistics be printed" ));
100
-
101
- static llvm::cl::opt<std::string> InputFilename (llvm::cl::Positional,
102
- llvm::cl::desc (" <input file>" ),
103
- llvm::cl::init(" -" ),
104
- llvm::cl::value_desc(" filename" ));
105
-
106
- static llvm::cl::opt<std::string>
107
- OutputFilename (" o" , llvm::cl::desc(" Override output filename" ),
108
- llvm::cl::value_desc(" filename" ));
109
-
110
- static llvm::cl::opt<std::string> DefaultDataLayout (
111
- " default-data-layout" ,
112
- llvm::cl::desc (" data layout string to use if not specified by module" ),
113
- llvm::cl::value_desc(" layout-string" ), llvm::cl::init(" " ));
77
+ struct SwiftLLVMOptOptions {
78
+ // The OptimizationList is automatically populated with registered passes by the
79
+ // PassNameParser.
80
+ //
81
+ llvm::cl::list<const llvm::PassInfo *, bool , llvm::PassNameParser>
82
+ PassList = llvm::cl::list<const llvm::PassInfo *, bool , llvm::PassNameParser>(llvm::cl::desc(" Optimizations available:" ));
83
+
84
+ llvm::cl::opt<bool >
85
+ Optimized = llvm::cl::opt<bool >(" O" , llvm::cl::desc(" Optimization level O. Similar to swift -O" ));
86
+
87
+ // TODO: I wanted to call this 'verify', but some other pass is using this
88
+ // option.
89
+ llvm::cl::opt<bool >
90
+ VerifyEach = llvm::cl::opt<bool >(
91
+ " verify-each" ,
92
+ llvm::cl::desc (" Should we spend time verifying that the IR is well "
93
+ " formed" ));
94
+
95
+ llvm::cl::opt<std::string>
96
+ TargetTriple = llvm::cl::opt<std::string>(" mtriple" ,
97
+ llvm::cl::desc (" Override target triple for module" ));
98
+
99
+ llvm::cl::opt<bool >
100
+ PrintStats = llvm::cl::opt<bool >(" print-stats" ,
101
+ llvm::cl::desc (" Should LLVM Statistics be printed" ));
102
+
103
+ llvm::cl::opt<std::string>
104
+ InputFilename = llvm::cl::opt<std::string>(llvm::cl::Positional,
105
+ llvm::cl::desc (" <input file>" ),
106
+ llvm::cl::init(" -" ),
107
+ llvm::cl::value_desc(" filename" ));
108
+
109
+ llvm::cl::opt<std::string>
110
+ OutputFilename = llvm::cl::opt<std::string>(" o" , llvm::cl::desc(" Override output filename" ),
111
+ llvm::cl::value_desc (" filename" ));
112
+
113
+ llvm::cl::opt<std::string>
114
+ DefaultDataLayout = llvm::cl::opt<std::string>(
115
+ " default-data-layout" ,
116
+ llvm::cl::desc (" data layout string to use if not specified by module" ),
117
+ llvm::cl::value_desc(" layout-string" ), llvm::cl::init(" " ));
118
+ };
114
119
115
120
// ===----------------------------------------------------------------------===//
116
121
// Helper Methods
117
122
// ===----------------------------------------------------------------------===//
118
123
119
- static llvm::CodeGenOpt::Level GetCodeGenOptLevel () {
124
+ static llvm::CodeGenOpt::Level GetCodeGenOptLevel (const SwiftLLVMOptOptions &options ) {
120
125
// TODO: Is this the right thing to do here?
121
- if (Optimized)
126
+ if (options. Optimized )
122
127
return llvm::CodeGenOpt::Default;
123
128
return llvm::CodeGenOpt::None;
124
129
}
125
130
126
131
// Returns the TargetMachine instance or zero if no triple is provided.
127
132
static llvm::TargetMachine *
128
133
getTargetMachine (llvm::Triple TheTriple, StringRef CPUStr,
129
- StringRef FeaturesStr, const llvm::TargetOptions &Options) {
134
+ StringRef FeaturesStr, const llvm::TargetOptions &targetOptions,
135
+ const SwiftLLVMOptOptions &options) {
130
136
std::string Error;
131
137
const auto *TheTarget = llvm::TargetRegistry::lookupTarget (
132
138
llvm::codegen::getMArch (), TheTriple, Error);
@@ -136,9 +142,9 @@ getTargetMachine(llvm::Triple TheTriple, StringRef CPUStr,
136
142
}
137
143
138
144
return TheTarget->createTargetMachine (
139
- TheTriple.getTriple (), CPUStr, FeaturesStr, Options ,
145
+ TheTriple.getTriple (), CPUStr, FeaturesStr, targetOptions ,
140
146
Optional<llvm::Reloc::Model>(llvm::codegen::getExplicitRelocModel ()),
141
- llvm::codegen::getExplicitCodeModel (), GetCodeGenOptLevel ());
147
+ llvm::codegen::getExplicitCodeModel (), GetCodeGenOptLevel (options ));
142
148
}
143
149
144
150
static void dumpOutput (llvm::Module &M, llvm::raw_ostream &os) {
@@ -148,14 +154,8 @@ static void dumpOutput(llvm::Module &M, llvm::raw_ostream &os) {
148
154
EmitPasses.run (M);
149
155
}
150
156
151
- // This function isn't referenced outside its translation unit, but it
152
- // can't use the "static" keyword because its address is used for
153
- // getMainExecutable (since some platforms don't support taking the
154
- // address of main, and some platforms can't implement getMainExecutable
155
- // without being given the address of a function in the main executable).
156
- void anchorForGetMainExecutable () {}
157
-
158
- static inline void addPass (llvm::legacy::PassManagerBase &PM, llvm::Pass *P) {
157
+ static inline void addPass (llvm::legacy::PassManagerBase &PM, llvm::Pass *P,
158
+ const SwiftLLVMOptOptions &options) {
159
159
// Add the pass to the pass manager...
160
160
PM.add (P);
161
161
if (P->getPassID () == &SwiftAAWrapperPass::ID) {
@@ -167,20 +167,21 @@ static inline void addPass(llvm::legacy::PassManagerBase &PM, llvm::Pass *P) {
167
167
}
168
168
169
169
// If we are verifying all of the intermediate steps, add the verifier...
170
- if (VerifyEach)
170
+ if (options. VerifyEach )
171
171
PM.add (llvm::createVerifierPass ());
172
172
}
173
173
174
174
static void runSpecificPasses (StringRef Binary, llvm::Module *M,
175
175
llvm::TargetMachine *TM,
176
- llvm::Triple &ModuleTriple) {
176
+ llvm::Triple &ModuleTriple,
177
+ const SwiftLLVMOptOptions &options) {
177
178
llvm::legacy::PassManager Passes;
178
179
llvm::TargetLibraryInfoImpl TLII (ModuleTriple);
179
180
Passes.add (new llvm::TargetLibraryInfoWrapperPass (TLII));
180
181
181
182
const llvm::DataLayout &DL = M->getDataLayout ();
182
- if (DL.isDefault () && !DefaultDataLayout.empty ()) {
183
- M->setDataLayout (DefaultDataLayout);
183
+ if (DL.isDefault () && !options. DefaultDataLayout .empty ()) {
184
+ M->setDataLayout (options. DefaultDataLayout );
184
185
}
185
186
186
187
// Add internal analysis passes from the target machine.
@@ -194,7 +195,7 @@ static void runSpecificPasses(StringRef Binary, llvm::Module *M,
194
195
Passes.add (TPC);
195
196
}
196
197
197
- for (const llvm::PassInfo *PassInfo : PassList) {
198
+ for (const llvm::PassInfo *PassInfo : options. PassList ) {
198
199
llvm::Pass *P = nullptr ;
199
200
if (PassInfo->getNormalCtor ())
200
201
P = PassInfo->getNormalCtor ()();
@@ -203,7 +204,7 @@ static void runSpecificPasses(StringRef Binary, llvm::Module *M,
203
204
<< " : cannot create pass: " << PassInfo->getPassName ()
204
205
<< " \n " ;
205
206
if (P) {
206
- addPass (Passes, P);
207
+ addPass (Passes, P, options );
207
208
}
208
209
}
209
210
@@ -215,8 +216,7 @@ static void runSpecificPasses(StringRef Binary, llvm::Module *M,
215
216
// Main Implementation
216
217
// ===----------------------------------------------------------------------===//
217
218
218
- int main (int argc, char **argv) {
219
- PROGRAM_START (argc, argv);
219
+ int swift_llvm_opt_main (ArrayRef<const char *> argv, void *MainAddr) {
220
220
INITIALIZE_LLVM ();
221
221
222
222
// Initialize passes
@@ -247,42 +247,44 @@ int main(int argc, char **argv) {
247
247
initializeInlineTreePrinterPass (Registry);
248
248
initializeLegacySwiftMergeFunctionsPass (Registry);
249
249
250
- llvm::cl::ParseCommandLineOptions (argc, argv, " Swift LLVM optimizer\n " );
250
+ SwiftLLVMOptOptions options;
251
+
252
+ llvm::cl::ParseCommandLineOptions (argv.size (), argv.data (), " Swift LLVM optimizer\n " );
251
253
252
- if (PrintStats)
254
+ if (options. PrintStats )
253
255
llvm::EnableStatistics ();
254
256
255
257
llvm::SMDiagnostic Err;
256
258
257
259
// Load the input module...
258
260
auto LLVMContext = std::make_unique<llvm::LLVMContext>();
259
261
std::unique_ptr<llvm::Module> M =
260
- parseIRFile (InputFilename, Err, *LLVMContext.get ());
262
+ parseIRFile (options. InputFilename , Err, *LLVMContext.get ());
261
263
262
264
if (!M) {
263
265
Err.print (argv[0 ], llvm::errs ());
264
266
return 1 ;
265
267
}
266
268
267
269
if (verifyModule (*M, &llvm::errs ())) {
268
- llvm::errs () << argv[0 ] << " : " << InputFilename
270
+ llvm::errs () << argv[0 ] << " : " << options. InputFilename
269
271
<< " : error: input module is broken!\n " ;
270
272
return 1 ;
271
273
}
272
274
273
275
// If we are supposed to override the target triple, do so now.
274
- if (!TargetTriple.empty ())
275
- M->setTargetTriple (llvm::Triple::normalize (TargetTriple));
276
+ if (!options. TargetTriple .empty ())
277
+ M->setTargetTriple (llvm::Triple::normalize (options. TargetTriple ));
276
278
277
279
// Figure out what stream we are supposed to write to...
278
280
std::unique_ptr<llvm::ToolOutputFile> Out;
279
281
// Default to standard output.
280
- if (OutputFilename.empty ())
281
- OutputFilename = " -" ;
282
+ if (options. OutputFilename .empty ())
283
+ options. OutputFilename = " -" ;
282
284
283
285
std::error_code EC;
284
286
Out.reset (
285
- new llvm::ToolOutputFile (OutputFilename, EC, llvm::sys::fs::OF_None));
287
+ new llvm::ToolOutputFile (options. OutputFilename , EC, llvm::sys::fs::OF_None));
286
288
if (EC) {
287
289
llvm::errs () << EC.message () << ' \n ' ;
288
290
return 1 ;
@@ -291,13 +293,13 @@ int main(int argc, char **argv) {
291
293
llvm::Triple ModuleTriple (M->getTargetTriple ());
292
294
std::string CPUStr, FeaturesStr;
293
295
llvm::TargetMachine *Machine = nullptr ;
294
- const llvm::TargetOptions Options =
296
+ const llvm::TargetOptions targetOptions =
295
297
llvm::codegen::InitTargetOptionsFromCodeGenFlags (ModuleTriple);
296
298
297
299
if (ModuleTriple.getArch ()) {
298
300
CPUStr = llvm::codegen::getCPUStr ();
299
301
FeaturesStr = llvm::codegen::getFeaturesStr ();
300
- Machine = getTargetMachine (ModuleTriple, CPUStr, FeaturesStr, Options );
302
+ Machine = getTargetMachine (ModuleTriple, CPUStr, FeaturesStr, targetOptions, options );
301
303
}
302
304
303
305
std::unique_ptr<llvm::TargetMachine> TM (Machine);
@@ -306,15 +308,15 @@ int main(int argc, char **argv) {
306
308
// flags.
307
309
llvm::codegen::setFunctionAttributes (CPUStr, FeaturesStr, *M);
308
310
309
- if (Optimized) {
311
+ if (options. Optimized ) {
310
312
IRGenOptions Opts;
311
313
Opts.OptMode = OptimizationMode::ForSpeed;
312
314
Opts.OutputKind = IRGenOutputKind::LLVMAssemblyAfterOptimization;
313
315
314
316
// Then perform the optimizations.
315
317
performLLVMOptimizations (Opts, M.get (), TM.get (), &Out->os ());
316
318
} else {
317
- runSpecificPasses (argv[0 ], M.get (), TM.get (), ModuleTriple);
319
+ runSpecificPasses (argv[0 ], M.get (), TM.get (), ModuleTriple, options );
318
320
// Finally dump the output.
319
321
dumpOutput (*M, Out->os ());
320
322
}
0 commit comments