Skip to content

Commit

Permalink
refactor: Finalize and run LTO optimization for LLVMBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
mauro-balades committed Jun 16, 2024
1 parent 3612de4 commit d930ae0
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 41 deletions.
4 changes: 1 addition & 3 deletions src/compiler/backend/llvm/builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,7 @@ void LLVMBuilder::build(std::vector<std::shared_ptr<sil::Module>>& modules) {
build(fn);
}
}
dbg.builder->finalize();
auto err = llvm::verifyModule(*builder_ctx.module, &llvm::errs());
sn_assert(!err, "Module verification failed");
finalize_and_run_lto();
}

void LLVMBuilder::dump(llvm::raw_ostream& os) {
Expand Down
9 changes: 5 additions & 4 deletions src/compiler/backend/llvm/builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ class LLVMBuilderContext {
bool dont_load = false;

LLVMBuilderContext(
std::unique_ptr<llvm::LLVMContext>& ctx,
std::unordered_map<uint64_t, sil::Inst*>& inst_map,
frontend::NamespacePath parent_crate
std::unique_ptr<llvm::LLVMContext>& ctx,
std::unordered_map<uint64_t, sil::Inst*>& inst_map,
frontend::NamespacePath parent_crate
)
: module(std::make_unique<llvm::Module>("main", *ctx)),
inst_map(inst_map), parent_crate(parent_crate) {}
Expand Down Expand Up @@ -98,6 +98,7 @@ class LLVMBuilder : public sil::Builder {

llvm::DISubprogram* get_disubprogram(const sil::FuncDecl* node);
void debug(const std::string& msg);
void finalize_and_run_lto();

bool just_declare = true;

Expand All @@ -119,7 +120,7 @@ class LLVMBuilder : public sil::Builder {
std::shared_ptr<llvm::LLVMContext> ctx, llvm::TargetMachine* target_machine,
EmitType emit_type
);
static void check_and_optimize(
static void optimize(
llvm::Module* module, llvm::TargetMachine* target_machine
);
static bool run_linker(
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/backend/llvm/link.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ bool LLVMBuilder::link(const Ctx& ctx, std::vector<std::filesystem::path>& paths
auto engine = llvm::EngineBuilder();
auto triple_str = libroot.get()->getTargetTriple();
auto target_machine = engine.selectTarget(llvm::Triple(triple_str), "", "", llvm::SmallVector<std::string, 1>());
check_and_optimize(libroot.get().get(), target_machine);
optimize(libroot.get().get(), target_machine);
SNOWBALL_VERBOSE(ctx, "Target triple: " + triple_str);
switch (global.emit_type) {
case EmitType::LlvmBc: {
Expand Down
80 changes: 47 additions & 33 deletions src/compiler/backend/llvm/optimize.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,53 @@ void applyDebugTransformations(llvm::Module* module, bool debug) {
}
} // namespace

void LLVMBuilder::check_and_optimize(llvm::Module* module, llvm::TargetMachine* target_machine) {
auto debug = global.debug_opt();
void LLVMBuilder::finalize_and_run_lto() {
dbg.builder->finalize();
auto err = llvm::verifyModule(*builder_ctx.module, &llvm::errs());
sn_assert(!err, "Module verification failed");

llvm::LoopAnalysisManager loop_analysis_manager;
llvm::FunctionAnalysisManager function_analysis_manager;
llvm::CGSCCAnalysisManager c_gscc_analysis_manager;
llvm::ModuleAnalysisManager module_analysis_manager;

llvm::PassBuilder pass_builder;
pass_builder.registerFunctionAnalyses(function_analysis_manager);
pass_builder.registerModuleAnalyses(module_analysis_manager);
pass_builder.registerCGSCCAnalyses(c_gscc_analysis_manager);
pass_builder.registerLoopAnalyses(loop_analysis_manager);
llvm::Triple module_triple(builder_ctx.module->getTargetTriple());
llvm::TargetLibraryInfoImpl tlii(module_triple);
// cross register them too?
pass_builder.crossRegisterProxies(
loop_analysis_manager, function_analysis_manager, c_gscc_analysis_manager, module_analysis_manager
);
function_analysis_manager.registerPass([&] { return llvm::TargetLibraryAnalysis(tlii); });
llvm::OptimizationLevel lopt_level;
switch (global.opt_level) {
case OptLevel::Debug:
lopt_level = llvm::OptimizationLevel::O0;
break;
case OptLevel::Release:
case OptLevel::ReleaseWithDebug:
lopt_level = llvm::OptimizationLevel::O2;
break;
case OptLevel::ReleaseFast:
lopt_level = llvm::OptimizationLevel::O3;
break;
}

llvm::ModulePassManager mpm;
if (global.opt_level == OptLevel::Debug) {
mpm = pass_builder.buildO0DefaultPipeline(lopt_level, true);
} else {
mpm = pass_builder.buildLTOPreLinkDefaultPipeline(lopt_level);
}
mpm.run(*builder_ctx.module, module_analysis_manager);
applyDebugTransformations(builder_ctx.module.get(), dbg.debug);
}

void LLVMBuilder::optimize(llvm::Module* module, llvm::TargetMachine* target_machine) {
auto opt_level = global.opt_level;

llvm::legacy::PassManager pass_manager;
Expand All @@ -48,7 +93,6 @@ void LLVMBuilder::check_and_optimize(llvm::Module* module, llvm::TargetMachine*
pass_manager.add(llvm::createInstructionCombiningPass());

pass_manager.run(*module);
applyDebugTransformations(module, debug);

if (opt_level == OptLevel::ReleaseWithDebug) {
llvm::legacy::PassManager debug_pass_manager;
Expand All @@ -59,36 +103,6 @@ void LLVMBuilder::check_and_optimize(llvm::Module* module, llvm::TargetMachine*

debug_pass_manager.run(*module);
}

llvm::LoopAnalysisManager loop_analysis_manager;
llvm::FunctionAnalysisManager function_analysis_manager;
llvm::CGSCCAnalysisManager c_gscc_analysis_manager;
llvm::ModuleAnalysisManager module_analysis_manager;

llvm::PassBuilder pass_builder;
pass_builder.registerFunctionAnalyses(function_analysis_manager);
pass_builder.registerModuleAnalyses(module_analysis_manager);
pass_builder.registerCGSCCAnalyses(c_gscc_analysis_manager);
pass_builder.registerLoopAnalyses(loop_analysis_manager);

llvm::OptimizationLevel lopt_level;
switch (opt_level) {
case OptLevel::Debug:
lopt_level = llvm::OptimizationLevel::O0;
break;
case OptLevel::Release:
case OptLevel::ReleaseWithDebug:
lopt_level = llvm::OptimizationLevel::O2;
break;
case OptLevel::ReleaseFast:
lopt_level = llvm::OptimizationLevel::O3;
break;
}

if (!debug) {
llvm::ModulePassManager module_pass_manager = pass_builder.buildLTOPreLinkDefaultPipeline(lopt_level);
//module_pass_manager.run(*builder_ctx.module, module_analysis_manager);
}
}

}
Expand Down

0 comments on commit d930ae0

Please sign in to comment.