Skip to content

Commit 665e1b0

Browse files
committed
Use new LLVM pass manager
1 parent 0fa12bc commit 665e1b0

File tree

1 file changed

+26
-44
lines changed

1 file changed

+26
-44
lines changed

src/llvm/mod.rs

Lines changed: 26 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ use llvm_sys::prelude::*;
1818
use llvm_sys::support::LLVMParseCommandLineOptions;
1919
use llvm_sys::target::*;
2020
use llvm_sys::target_machine::*;
21-
use llvm_sys::transforms::ipo::*;
22-
use llvm_sys::transforms::pass_manager_builder::*;
21+
use llvm_sys::transforms::pass_builder::*;
2322
use llvm_sys::LLVMAttributeFunctionIndex;
2423
use llvm_sys::{LLVMLinkage, LLVMVisibility};
2524
use log::*;
@@ -176,65 +175,48 @@ pub unsafe fn optimize(
176175
LLVMSetModuleInlineAsm2(module, ptr::null_mut(), 0);
177176
}
178177

179-
let mpm = LLVMCreatePassManager();
180-
let fpm = LLVMCreateFunctionPassManagerForModule(module);
181-
182-
LLVMAddAnalysisPasses(tm, mpm);
183-
LLVMAddAnalysisPasses(tm, fpm);
184-
185-
// even with -O0 and without LTO we still want to avoid linking in unused code from core etc
186-
LLVMAddGlobalDCEPass(mpm);
187-
188-
let pmb = LLVMPassManagerBuilderCreate();
189-
190-
use OptLevel::*;
191-
let (inline_threshold, opt) = match opt_level {
192-
No | SizeMin => (0, 1), // Pretty much nothing compiles with -O0 s∫o make it an alias for -O1
193-
Less => (25, 1),
194-
Default => (225, 2),
195-
Aggressive => (275, 3),
196-
Size => (25, 0),
197-
};
198-
LLVMPassManagerBuilderSetOptLevel(pmb, opt);
199-
LLVMPassManagerBuilderSetSizeLevel(
200-
pmb,
201-
match opt_level {
202-
Size => 1,
203-
SizeMin => 2,
204-
_ => 0,
205-
},
206-
);
207-
LLVMPassManagerBuilderUseInlinerWithThreshold(pmb, inline_threshold);
208-
209-
// populate the pass managers
210-
LLVMPassManagerBuilderPopulateFunctionPassManager(pmb, fpm);
211-
LLVMPassManagerBuilderPopulateModulePassManager(pmb, mpm);
212-
213178
for sym in module.globals_iter() {
214179
internalize(sym, symbol_name(sym), export_symbols);
215180
}
216181
for sym in module.global_aliases_iter() {
217182
internalize(sym, symbol_name(sym), export_symbols);
218183
}
219184

220-
debug!("running function passes");
221-
LLVMInitializeFunctionPassManager(fpm);
222185
for function in module.functions_iter() {
223186
let name = symbol_name(function);
224187
if !name.starts_with("llvm.") {
225188
if ignore_inline_never {
226189
remove_attribute(function, "noinline");
227190
}
228191
internalize(function, name, export_symbols);
229-
if LLVMIsDeclaration(function) == 0 {
230-
LLVMRunFunctionPassManager(fpm, function);
231-
}
232192
}
233193
}
234-
LLVMFinalizeFunctionPassManager(fpm);
235194

236-
debug!("running module passes");
237-
LLVMRunPassManager(mpm, module);
195+
let options = LLVMCreatePassBuilderOptions();
196+
197+
let passes = [
198+
// NB: "default<_>" must be the first pass in the list, otherwise it will be ignored.
199+
match opt_level {
200+
// Pretty much nothing compiles with -O0 so make it an alias for -O1.
201+
OptLevel::No | OptLevel::Less => "default<O1>",
202+
OptLevel::Default => "default<O2>",
203+
OptLevel::Aggressive => "default<O3>",
204+
OptLevel::Size => "default<Os>",
205+
OptLevel::SizeMin => "default<Oz>",
206+
},
207+
// NB: This seems to be included in most default pipelines, but not obviously all of them.
208+
// See
209+
// https://github.com/llvm/llvm-project/blob/bbe2887f/llvm/lib/Passes/PassBuilderPipelines.cpp#L2011-L2012
210+
// for a case which includes DCE only conditionally. Better safe than sorry; include it always.
211+
"dce",
212+
];
213+
214+
let passes = passes.join(",");
215+
debug!("running passes: {passes}");
216+
let passes = CString::new(passes).unwrap();
217+
LLVMRunPasses(module, passes.as_ptr(), tm, options);
218+
219+
LLVMDisposePassBuilderOptions(options);
238220

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

0 commit comments

Comments
 (0)