4040#include < llvm/Support/FileSystem.h>
4141#include < llvm/IR/LegacyPassManager.h>
4242
43+ #include " llvm/Passes/PassBuilder.h"
44+ #include " llvm/Passes/StandardInstrumentations.h"
45+ #include " llvm/Analysis/AliasAnalysis.h"
46+ #include " llvm/Transforms/Scalar.h"
47+ #include " llvm/Transforms/Utils.h"
4348
4449#include < llvm/TargetParser/Host.h>
4550
51+ // Optimize TheModule with the provided optimization flags (-O3, -Os, etc)
52+ void optimize ();
4653
4754extern " C" void initialize_llvm () {
48-
4955 TheContext = std::make_unique<llvm::LLVMContext>();
5056 Builder = std::unique_ptr<llvm::IRBuilder<>>(new llvm::IRBuilder<>(*TheContext));
5157 TheModule = std::make_unique<llvm::Module>(ctx.inputFile , *TheContext);
@@ -62,11 +68,9 @@ extern "C" void initialize_llvm() {
6268 LLVMInitializeAArch64TargetMC ();
6369 LLVMInitializeAArch64AsmParser ();
6470 LLVMInitializeAArch64AsmPrinter ();
65-
6671}
6772
6873extern " C" void export_asm () {
69-
7074 optimize (); // Apply any optimizations (will return if -O0)
7175
7276 std::string targetTriple = llvm::sys::getDefaultTargetTriple ();
@@ -100,10 +104,8 @@ extern "C" void export_asm() {
100104
101105 // Set file type: object file (.o)
102106#if defined(__APPLE__)
103- // macOS (old API)
104107 llvm::CodeGenFileType fileType = llvm::CodeGenFileType::AssemblyFile;
105108#else
106- // Linux, Windows (new API)
107109 llvm::CodeGenFileType fileType = llvm::CGFT_AssemblyFile;
108110#endif
109111
@@ -114,14 +116,10 @@ extern "C" void export_asm() {
114116
115117 pass.run (*TheModule);
116118 dest.flush ();
117-
118- llvm::outs () << " Wrote " << ctx.outputFilename << " \n " ;
119-
120119}
121120
122121
123122extern " C" void export_ir () {
124-
125123 optimize (); // Apply any optimizations (will return if -O0)
126124
127125 std::error_code EC;
@@ -135,7 +133,6 @@ extern "C" void export_ir() {
135133
136134
137135extern " C" void generate_binary () {
138-
139136 optimize (); // Apply any optimizations (will return if -O0)
140137
141138 std::string targetTriple = llvm::sys::getDefaultTargetTriple ();
@@ -181,10 +178,40 @@ extern "C" void generate_binary() {
181178
182179 pass.run (*TheModule);
183180 dest.flush ();
184-
185- llvm::outs () << " Wrote " << ctx.outputFilename << " \n " ;
186181}
187182
188183
189-
190-
184+ void optimize () {
185+ if (!ctx.optimization ) return ;
186+
187+ // Create analysis managers
188+ llvm::LoopAnalysisManager LAM;
189+ llvm::FunctionAnalysisManager FAM;
190+ llvm::CGSCCAnalysisManager CGAM;
191+ llvm::ModuleAnalysisManager MAM;
192+
193+ // Create pass builder
194+ llvm::PassBuilder PB;
195+
196+ // Register analysis passes
197+ PB.registerModuleAnalyses (MAM);
198+ PB.registerCGSCCAnalyses (CGAM);
199+ PB.registerFunctionAnalyses (FAM);
200+ PB.registerLoopAnalyses (LAM);
201+ PB.crossRegisterProxies (LAM, FAM, CGAM, MAM);
202+
203+ llvm::ModulePassManager MPM;
204+ // Create optimization pipeline
205+ if (ctx.optimization == 1 ) // Mild optimization
206+ MPM = PB.buildPerModuleDefaultPipeline (llvm::OptimizationLevel::O1);
207+ else if (ctx.optimization == 2 ) // Moderate optimization
208+ MPM = PB.buildPerModuleDefaultPipeline (llvm::OptimizationLevel::O2);
209+ else if (ctx.optimization == 3 ) // Aggressive optimization
210+ MPM = PB.buildPerModuleDefaultPipeline (llvm::OptimizationLevel::O3);
211+ else if (ctx.optimization == 4 ) // Optimize for size
212+ MPM = PB.buildPerModuleDefaultPipeline (llvm::OptimizationLevel::Os);
213+ else if (ctx.optimization == 5 ) // Aggressively optimize for size
214+ MPM = PB.buildPerModuleDefaultPipeline (llvm::OptimizationLevel::Oz);
215+
216+ MPM.run (*TheModule, MAM);
217+ }
0 commit comments