Skip to content

Commit e505c20

Browse files
committed
Refactor LLVM optimization pipeline
1 parent 6b7770b commit e505c20

File tree

2 files changed

+72
-14
lines changed

2 files changed

+72
-14
lines changed

src/engine/internal/llvm/llvmcompilercontext.cpp

Lines changed: 68 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// SPDX-License-Identifier: Apache-2.0
22

33
#include <llvm/Support/TargetSelect.h>
4+
#include <llvm/TargetParser/Host.h>
5+
#include <llvm/MC/TargetRegistry.h>
46
#include <llvm/Passes/PassBuilder.h>
57
#include <llvm/IR/Verifier.h>
68

@@ -70,20 +72,7 @@ void LLVMCompilerContext::initJit()
7072
#endif
7173

7274
// Optimize
73-
llvm::PassBuilder passBuilder;
74-
llvm::LoopAnalysisManager loopAnalysisManager;
75-
llvm::FunctionAnalysisManager functionAnalysisManager;
76-
llvm::CGSCCAnalysisManager cGSCCAnalysisManager;
77-
llvm::ModuleAnalysisManager moduleAnalysisManager;
78-
79-
passBuilder.registerModuleAnalyses(moduleAnalysisManager);
80-
passBuilder.registerCGSCCAnalyses(cGSCCAnalysisManager);
81-
passBuilder.registerFunctionAnalyses(functionAnalysisManager);
82-
passBuilder.registerLoopAnalyses(loopAnalysisManager);
83-
passBuilder.crossRegisterProxies(loopAnalysisManager, functionAnalysisManager, cGSCCAnalysisManager, moduleAnalysisManager);
84-
85-
llvm::ModulePassManager modulePassManager = passBuilder.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::O3);
86-
modulePassManager.run(*m_module, moduleAnalysisManager);
75+
optimize(llvm::OptimizationLevel::O3);
8776

8877
const auto &functions = m_module->getFunctionList();
8978
std::vector<std::string> lookupNames;
@@ -151,6 +140,71 @@ void LLVMCompilerContext::initTarget()
151140
llvm::InitializeNativeTarget();
152141
llvm::InitializeNativeTargetAsmPrinter();
153142
llvm::InitializeNativeTargetAsmParser();
143+
144+
createTargetMachine();
145+
146+
m_module->setDataLayout(m_targetMachine->createDataLayout());
147+
}
148+
149+
void LLVMCompilerContext::createTargetMachine()
150+
{
151+
std::string error;
152+
std::string targetTriple = llvm::sys::getDefaultTargetTriple();
153+
m_module->setTargetTriple(targetTriple);
154+
155+
const llvm::Target *target = llvm::TargetRegistry::lookupTarget(targetTriple, error);
156+
157+
if (!target) {
158+
llvm::errs() << error;
159+
return;
160+
}
161+
162+
llvm::TargetOptions opt;
163+
const char *cpu = "generic";
164+
const char *features = "";
165+
166+
m_targetMachine = std::unique_ptr<llvm::TargetMachine>(target->createTargetMachine(targetTriple, cpu, features, opt, llvm::Reloc::PIC_));
167+
}
168+
169+
void LLVMCompilerContext::optimize(llvm::OptimizationLevel optLevel)
170+
{
171+
llvm::PassBuilder passBuilder(m_targetMachine.get());
172+
llvm::LoopAnalysisManager loopAnalysisManager;
173+
llvm::FunctionAnalysisManager functionAnalysisManager;
174+
llvm::CGSCCAnalysisManager cGSCCAnalysisManager;
175+
llvm::ModuleAnalysisManager moduleAnalysisManager;
176+
177+
passBuilder.registerModuleAnalyses(moduleAnalysisManager);
178+
passBuilder.registerCGSCCAnalyses(cGSCCAnalysisManager);
179+
passBuilder.registerFunctionAnalyses(functionAnalysisManager);
180+
passBuilder.registerLoopAnalyses(loopAnalysisManager);
181+
passBuilder.crossRegisterProxies(loopAnalysisManager, functionAnalysisManager, cGSCCAnalysisManager, moduleAnalysisManager);
182+
183+
llvm::ModulePassManager modulePassManager = passBuilder.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::O3);
184+
185+
std::string pipeline;
186+
187+
if (optLevel == llvm::OptimizationLevel::O0)
188+
pipeline = "default<O0>";
189+
else if (optLevel == llvm::OptimizationLevel::O1)
190+
pipeline = "default<O1>";
191+
else if (optLevel == llvm::OptimizationLevel::O2)
192+
pipeline = "default<O2>";
193+
else if (optLevel == llvm::OptimizationLevel::O3)
194+
pipeline = "default<O3>";
195+
else if (optLevel == llvm::OptimizationLevel::Os)
196+
pipeline = "default<Os>";
197+
else if (optLevel == llvm::OptimizationLevel::Oz)
198+
pipeline = "default<Oz>";
199+
else
200+
assert(false);
201+
202+
if (passBuilder.parsePassPipeline(modulePassManager, pipeline)) {
203+
llvm::errs() << "Failed to parse pipeline\n";
204+
return;
205+
}
206+
207+
modulePassManager.run(*m_module, moduleAnalysisManager);
154208
}
155209

156210
llvm::Function *LLVMCompilerContext::createCoroResumeFunction()

src/engine/internal/llvm/llvmcompilercontext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <llvm/IR/Module.h>
66
#include <llvm/ExecutionEngine/Orc/LLJIT.h>
7+
#include <llvm/Passes/OptimizationLevel.h>
78

89
#include <scratchcpp/compilercontext.h>
910

@@ -52,6 +53,8 @@ class LLVMCompilerContext : public CompilerContext
5253
using DestroyCoroFuncType = void (*)(void *);
5354

5455
void initTarget();
56+
void createTargetMachine();
57+
void optimize(llvm::OptimizationLevel optLevel);
5558

5659
llvm::Function *createCoroResumeFunction();
5760
llvm::Function *createCoroDestroyFunction();
@@ -62,6 +65,7 @@ class LLVMCompilerContext : public CompilerContext
6265
std::unique_ptr<llvm::Module> m_module;
6366
llvm::LLVMContext *m_llvmCtxPtr = nullptr;
6467
llvm::Module *m_modulePtr = nullptr;
68+
std::unique_ptr<llvm::TargetMachine> m_targetMachine;
6569
llvm::Expected<std::unique_ptr<llvm::orc::LLJIT>> m_jit;
6670
bool m_jitInitialized = false;
6771

0 commit comments

Comments
 (0)