use inkwell::module::Module;
use inkwell::passes::PassBuilderOptions;
use inkwell::targets::TargetMachine;
use inkwell::OptimizationLevel;
pub(crate) fn codegen_level() -> OptimizationLevel {
level_of(crate::opt_level::opt_level())
}
pub(crate) fn level_of(level: u8) -> OptimizationLevel {
match level {
0 => OptimizationLevel::None,
1 => OptimizationLevel::Less,
2 => OptimizationLevel::Default,
3 => OptimizationLevel::Aggressive,
_ => unreachable!("optimization level {} is past {}", level, crate::opt_level::MAX),
}
}
pub(crate) fn run_llvm_passes(module: &Module<'static>, machine: &TargetMachine) -> Result<(), String> {
let level = crate::opt_level::opt_level();
if level == 0 {
return Ok(());
}
module
.run_passes(&format!("default<O{}>", level), machine, PassBuilderOptions::create())
.map_err(|e| format!("internal error: LLVM's -O{} pipeline failed: {}", level, e))?;
module
.verify()
.map_err(|e| format!("internal error: the module failed verification after optimizing it at -O{}: {}", level, e))
}