1- // ===--- LLVMOpt .cpp ------------ ------------------------------------------===//
1+ // ===--- swift_llvm_opt_main .cpp ------------------------------------------===//
22//
33// This source file is part of the Swift.org open source project
44//
@@ -74,59 +74,65 @@ static llvm::codegen::RegisterCodeGenFlags CGF;
7474// Option Declarations
7575// ===----------------------------------------------------------------------===//
7676
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+ };
114119
115120// ===----------------------------------------------------------------------===//
116121// Helper Methods
117122// ===----------------------------------------------------------------------===//
118123
119- static llvm::CodeGenOpt::Level GetCodeGenOptLevel () {
124+ static llvm::CodeGenOpt::Level GetCodeGenOptLevel (const SwiftLLVMOptOptions &options ) {
120125 // TODO: Is this the right thing to do here?
121- if (Optimized)
126+ if (options. Optimized )
122127 return llvm::CodeGenOpt::Default;
123128 return llvm::CodeGenOpt::None;
124129}
125130
126131// Returns the TargetMachine instance or zero if no triple is provided.
127132static llvm::TargetMachine *
128133getTargetMachine (llvm::Triple TheTriple, StringRef CPUStr,
129- StringRef FeaturesStr, const llvm::TargetOptions &Options) {
134+ StringRef FeaturesStr, const llvm::TargetOptions &targetOptions,
135+ const SwiftLLVMOptOptions &options) {
130136 std::string Error;
131137 const auto *TheTarget = llvm::TargetRegistry::lookupTarget (
132138 llvm::codegen::getMArch (), TheTriple, Error);
@@ -136,9 +142,9 @@ getTargetMachine(llvm::Triple TheTriple, StringRef CPUStr,
136142 }
137143
138144 return TheTarget->createTargetMachine (
139- TheTriple.getTriple (), CPUStr, FeaturesStr, Options ,
145+ TheTriple.getTriple (), CPUStr, FeaturesStr, targetOptions ,
140146 Optional<llvm::Reloc::Model>(llvm::codegen::getExplicitRelocModel ()),
141- llvm::codegen::getExplicitCodeModel (), GetCodeGenOptLevel ());
147+ llvm::codegen::getExplicitCodeModel (), GetCodeGenOptLevel (options ));
142148}
143149
144150static void dumpOutput (llvm::Module &M, llvm::raw_ostream &os) {
@@ -148,14 +154,8 @@ static void dumpOutput(llvm::Module &M, llvm::raw_ostream &os) {
148154 EmitPasses.run (M);
149155}
150156
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) {
159159 // Add the pass to the pass manager...
160160 PM.add (P);
161161 if (P->getPassID () == &SwiftAAWrapperPass::ID) {
@@ -167,20 +167,21 @@ static inline void addPass(llvm::legacy::PassManagerBase &PM, llvm::Pass *P) {
167167 }
168168
169169 // If we are verifying all of the intermediate steps, add the verifier...
170- if (VerifyEach)
170+ if (options. VerifyEach )
171171 PM.add (llvm::createVerifierPass ());
172172}
173173
174174static void runSpecificPasses (StringRef Binary, llvm::Module *M,
175175 llvm::TargetMachine *TM,
176- llvm::Triple &ModuleTriple) {
176+ llvm::Triple &ModuleTriple,
177+ const SwiftLLVMOptOptions &options) {
177178 llvm::legacy::PassManager Passes;
178179 llvm::TargetLibraryInfoImpl TLII (ModuleTriple);
179180 Passes.add (new llvm::TargetLibraryInfoWrapperPass (TLII));
180181
181182 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 );
184185 }
185186
186187 // Add internal analysis passes from the target machine.
@@ -194,7 +195,7 @@ static void runSpecificPasses(StringRef Binary, llvm::Module *M,
194195 Passes.add (TPC);
195196 }
196197
197- for (const llvm::PassInfo *PassInfo : PassList) {
198+ for (const llvm::PassInfo *PassInfo : options. PassList ) {
198199 llvm::Pass *P = nullptr ;
199200 if (PassInfo->getNormalCtor ())
200201 P = PassInfo->getNormalCtor ()();
@@ -203,7 +204,7 @@ static void runSpecificPasses(StringRef Binary, llvm::Module *M,
203204 << " : cannot create pass: " << PassInfo->getPassName ()
204205 << " \n " ;
205206 if (P) {
206- addPass (Passes, P);
207+ addPass (Passes, P, options );
207208 }
208209 }
209210
@@ -215,8 +216,7 @@ static void runSpecificPasses(StringRef Binary, llvm::Module *M,
215216// Main Implementation
216217// ===----------------------------------------------------------------------===//
217218
218- int main (int argc, char **argv) {
219- PROGRAM_START (argc, argv);
219+ int swift_llvm_opt_main (ArrayRef<const char *> argv, void *MainAddr) {
220220 INITIALIZE_LLVM ();
221221
222222 // Initialize passes
@@ -247,42 +247,44 @@ int main(int argc, char **argv) {
247247 initializeInlineTreePrinterPass (Registry);
248248 initializeLegacySwiftMergeFunctionsPass (Registry);
249249
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 " );
251253
252- if (PrintStats)
254+ if (options. PrintStats )
253255 llvm::EnableStatistics ();
254256
255257 llvm::SMDiagnostic Err;
256258
257259 // Load the input module...
258260 auto LLVMContext = std::make_unique<llvm::LLVMContext>();
259261 std::unique_ptr<llvm::Module> M =
260- parseIRFile (InputFilename, Err, *LLVMContext.get ());
262+ parseIRFile (options. InputFilename , Err, *LLVMContext.get ());
261263
262264 if (!M) {
263265 Err.print (argv[0 ], llvm::errs ());
264266 return 1 ;
265267 }
266268
267269 if (verifyModule (*M, &llvm::errs ())) {
268- llvm::errs () << argv[0 ] << " : " << InputFilename
270+ llvm::errs () << argv[0 ] << " : " << options. InputFilename
269271 << " : error: input module is broken!\n " ;
270272 return 1 ;
271273 }
272274
273275 // 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 ));
276278
277279 // Figure out what stream we are supposed to write to...
278280 std::unique_ptr<llvm::ToolOutputFile> Out;
279281 // Default to standard output.
280- if (OutputFilename.empty ())
281- OutputFilename = " -" ;
282+ if (options. OutputFilename .empty ())
283+ options. OutputFilename = " -" ;
282284
283285 std::error_code EC;
284286 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));
286288 if (EC) {
287289 llvm::errs () << EC.message () << ' \n ' ;
288290 return 1 ;
@@ -291,13 +293,13 @@ int main(int argc, char **argv) {
291293 llvm::Triple ModuleTriple (M->getTargetTriple ());
292294 std::string CPUStr, FeaturesStr;
293295 llvm::TargetMachine *Machine = nullptr ;
294- const llvm::TargetOptions Options =
296+ const llvm::TargetOptions targetOptions =
295297 llvm::codegen::InitTargetOptionsFromCodeGenFlags (ModuleTriple);
296298
297299 if (ModuleTriple.getArch ()) {
298300 CPUStr = llvm::codegen::getCPUStr ();
299301 FeaturesStr = llvm::codegen::getFeaturesStr ();
300- Machine = getTargetMachine (ModuleTriple, CPUStr, FeaturesStr, Options );
302+ Machine = getTargetMachine (ModuleTriple, CPUStr, FeaturesStr, targetOptions, options );
301303 }
302304
303305 std::unique_ptr<llvm::TargetMachine> TM (Machine);
@@ -306,15 +308,15 @@ int main(int argc, char **argv) {
306308 // flags.
307309 llvm::codegen::setFunctionAttributes (CPUStr, FeaturesStr, *M);
308310
309- if (Optimized) {
311+ if (options. Optimized ) {
310312 IRGenOptions Opts;
311313 Opts.OptMode = OptimizationMode::ForSpeed;
312314 Opts.OutputKind = IRGenOutputKind::LLVMAssemblyAfterOptimization;
313315
314316 // Then perform the optimizations.
315317 performLLVMOptimizations (Opts, M.get (), TM.get (), &Out->os ());
316318 } else {
317- runSpecificPasses (argv[0 ], M.get (), TM.get (), ModuleTriple);
319+ runSpecificPasses (argv[0 ], M.get (), TM.get (), ModuleTriple, options );
318320 // Finally dump the output.
319321 dumpOutput (*M, Out->os ());
320322 }
0 commit comments