Skip to content

Commit

Permalink
Use new LLVM pass manager
Browse files Browse the repository at this point in the history
  • Loading branch information
tamird committed Jul 28, 2023
1 parent 0fa12bc commit 665e1b0
Showing 1 changed file with 26 additions and 44 deletions.
70 changes: 26 additions & 44 deletions src/llvm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ use llvm_sys::prelude::*;
use llvm_sys::support::LLVMParseCommandLineOptions;
use llvm_sys::target::*;
use llvm_sys::target_machine::*;
use llvm_sys::transforms::ipo::*;
use llvm_sys::transforms::pass_manager_builder::*;
use llvm_sys::transforms::pass_builder::*;
use llvm_sys::LLVMAttributeFunctionIndex;
use llvm_sys::{LLVMLinkage, LLVMVisibility};
use log::*;
Expand Down Expand Up @@ -176,65 +175,48 @@ pub unsafe fn optimize(
LLVMSetModuleInlineAsm2(module, ptr::null_mut(), 0);
}

let mpm = LLVMCreatePassManager();
let fpm = LLVMCreateFunctionPassManagerForModule(module);

LLVMAddAnalysisPasses(tm, mpm);
LLVMAddAnalysisPasses(tm, fpm);

// even with -O0 and without LTO we still want to avoid linking in unused code from core etc
LLVMAddGlobalDCEPass(mpm);

let pmb = LLVMPassManagerBuilderCreate();

use OptLevel::*;
let (inline_threshold, opt) = match opt_level {
No | SizeMin => (0, 1), // Pretty much nothing compiles with -O0 s∫o make it an alias for -O1
Less => (25, 1),
Default => (225, 2),
Aggressive => (275, 3),
Size => (25, 0),
};
LLVMPassManagerBuilderSetOptLevel(pmb, opt);
LLVMPassManagerBuilderSetSizeLevel(
pmb,
match opt_level {
Size => 1,
SizeMin => 2,
_ => 0,
},
);
LLVMPassManagerBuilderUseInlinerWithThreshold(pmb, inline_threshold);

// populate the pass managers
LLVMPassManagerBuilderPopulateFunctionPassManager(pmb, fpm);
LLVMPassManagerBuilderPopulateModulePassManager(pmb, mpm);

for sym in module.globals_iter() {
internalize(sym, symbol_name(sym), export_symbols);
}
for sym in module.global_aliases_iter() {
internalize(sym, symbol_name(sym), export_symbols);
}

debug!("running function passes");
LLVMInitializeFunctionPassManager(fpm);
for function in module.functions_iter() {
let name = symbol_name(function);
if !name.starts_with("llvm.") {
if ignore_inline_never {
remove_attribute(function, "noinline");
}
internalize(function, name, export_symbols);
if LLVMIsDeclaration(function) == 0 {
LLVMRunFunctionPassManager(fpm, function);
}
}
}
LLVMFinalizeFunctionPassManager(fpm);

debug!("running module passes");
LLVMRunPassManager(mpm, module);
let options = LLVMCreatePassBuilderOptions();

let passes = [
// NB: "default<_>" must be the first pass in the list, otherwise it will be ignored.
match opt_level {
// Pretty much nothing compiles with -O0 so make it an alias for -O1.
OptLevel::No | OptLevel::Less => "default<O1>",
OptLevel::Default => "default<O2>",
OptLevel::Aggressive => "default<O3>",
OptLevel::Size => "default<Os>",
OptLevel::SizeMin => "default<Oz>",
},
// NB: This seems to be included in most default pipelines, but not obviously all of them.
// See
// https://github.com/llvm/llvm-project/blob/bbe2887f/llvm/lib/Passes/PassBuilderPipelines.cpp#L2011-L2012
// for a case which includes DCE only conditionally. Better safe than sorry; include it always.
"dce",
];

let passes = passes.join(",");
debug!("running passes: {passes}");
let passes = CString::new(passes).unwrap();
LLVMRunPasses(module, passes.as_ptr(), tm, options);

LLVMDisposePassBuilderOptions(options);

// Some debug info generated by rustc seems to trigger a segfault in the
// BTF code in llvm, so strip it until that is fixed
Expand Down

0 comments on commit 665e1b0

Please sign in to comment.