diff --git a/src/linker.rs b/src/linker.rs index 85e0da39..a35e30c9 100644 --- a/src/linker.rs +++ b/src/linker.rs @@ -492,6 +492,20 @@ impl Linker { if !self.options.disable_expand_memcpy_in_order { args.push("--bpf-expand-memcpy-in-order".into()); } + args.push( + format!( + "--inline-threshold={}", + match self.options.optimize { + OptLevel::No => 0, + OptLevel::Less => 25, + OptLevel::Default => 225, + OptLevel::Aggressive => 275, + OptLevel::Size => 25, + OptLevel::SizeMin => 0, + } + ) + .into(), + ); args.extend(self.options.llvm_args.iter().map(Into::into)); info!("LLVM command line: {:?}", args); unsafe { diff --git a/src/llvm/mod.rs b/src/llvm/mod.rs index 4cc41810..f2bf8147 100644 --- a/src/llvm/mod.rs +++ b/src/llvm/mod.rs @@ -19,8 +19,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::*; @@ -179,40 +178,6 @@ 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); } @@ -220,8 +185,6 @@ pub unsafe fn optimize( 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.") { @@ -229,15 +192,30 @@ pub unsafe fn optimize( 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(); + + // even with -O0 and without LTO we still want to avoid linking in unused code from core etc + let dce = CString::new("dce").unwrap(); + debug!("running dce passe"); + LLVMRunPasses(module, dce.as_ptr(), tm, options); + + let opt = CString::new(match opt_level { + // Pretty much nothing compiles with -O0 so make it an alias for -O1 + OptLevel::No | OptLevel::Less => "default", + OptLevel::Default => "default", + OptLevel::Aggressive => "default", + OptLevel::Size => "default", + OptLevel::SizeMin => "default", + }) + .unwrap(); + + debug!("running optimization pass"); + LLVMRunPasses(module, opt.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