Move pass managers into llvm::build

This commit is contained in:
Richard Feldman 2020-03-28 17:26:03 -04:00
parent 656bf5ccf8
commit 0a0a736153
2 changed files with 30 additions and 32 deletions

View file

@ -3,6 +3,7 @@ use bumpalo::Bump;
use inkwell::builder::Builder; use inkwell::builder::Builder;
use inkwell::context::Context; use inkwell::context::Context;
use inkwell::module::{Linkage, Module}; use inkwell::module::{Linkage, Module};
use inkwell::passes::PassManager;
use inkwell::types::{BasicTypeEnum, IntType, StructType}; use inkwell::types::{BasicTypeEnum, IntType, StructType};
use inkwell::values::BasicValueEnum::{self, *}; use inkwell::values::BasicValueEnum::{self, *};
use inkwell::values::{FunctionValue, IntValue, PointerValue, StructValue}; use inkwell::values::{FunctionValue, IntValue, PointerValue, StructValue};
@ -45,6 +46,25 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
} }
} }
pub fn add_passes(fpm: &PassManager<FunctionValue<'_>>) {
// tail-call elimination is always on
fpm.add_instruction_combining_pass();
fpm.add_tail_call_elimination_pass();
// Enable more optimizations when running cargo test --release
if !cfg!(debug_assertions) {
fpm.add_reassociate_pass();
fpm.add_basic_alias_analysis_pass();
fpm.add_promote_memory_to_register_pass();
fpm.add_cfg_simplification_pass();
fpm.add_gvn_pass();
// TODO figure out why enabling any of these (even alone) causes LLVM to segfault
// fpm.add_strip_dead_prototypes_pass();
// fpm.add_dead_arg_elimination_pass();
// fpm.add_function_inlining_pass();
}
}
#[allow(clippy::cognitive_complexity)] #[allow(clippy::cognitive_complexity)]
pub fn build_expr<'a, 'ctx, 'env>( pub fn build_expr<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,

View file

@ -4,36 +4,6 @@ pub const POINTER_SIZE: u32 = std::mem::size_of::<usize>() as u32;
// 0 is the C calling convention - see https://llvm.org/doxygen/namespacellvm_1_1CallingConv.html // 0 is the C calling convention - see https://llvm.org/doxygen/namespacellvm_1_1CallingConv.html
pub const MAIN_CALLING_CONVENTION: u32 = 0; pub const MAIN_CALLING_CONVENTION: u32 = 0;
#[macro_export]
macro_rules! get_fpm {
($module:expr) => {{
let fpm = PassManager::create(&$module);
// tail-call elimination is always on
fpm.add_instruction_combining_pass();
fpm.add_tail_call_elimination_pass();
// Enable more optimizations when running cargo test --release
if !cfg!(debug_assertions) {
fpm.add_reassociate_pass();
fpm.add_basic_alias_analysis_pass();
fpm.add_promote_memory_to_register_pass();
fpm.add_cfg_simplification_pass();
fpm.add_gvn_pass();
// TODO figure out why enabling any of these (even alone) causes LLVM to segfault
// fpm.add_strip_dead_prototypes_pass();
// fpm.add_dead_arg_elimination_pass();
// fpm.add_function_inlining_pass();
}
fpm.initialize();
// TODO when should we call initialize, and then finalize?
fpm
}};
}
#[macro_export] #[macro_export]
macro_rules! assert_llvm_evals_to { macro_rules! assert_llvm_evals_to {
($src:expr, $expected:expr, $ty:ty, $transform:expr) => { ($src:expr, $expected:expr, $ty:ty, $transform:expr) => {
@ -46,7 +16,11 @@ macro_rules! assert_llvm_evals_to {
let context = Context::create(); let context = Context::create();
let module = context.create_module("app"); let module = context.create_module("app");
let builder = context.create_builder(); let builder = context.create_builder();
let fpm = { get_fpm!(module) }; let fpm = inkwell::passes::PassManager::create(&module);
roc_gen::llvm::build::add_passes(&fpm);
fpm.initialize();
// Compute main_fn_type before moving subs to Env // Compute main_fn_type before moving subs to Env
let layout = Layout::from_content(&arena, content, &subs, $crate::helpers::eval::POINTER_SIZE) let layout = Layout::from_content(&arena, content, &subs, $crate::helpers::eval::POINTER_SIZE)
@ -173,7 +147,11 @@ macro_rules! assert_opt_evals_to {
let context = Context::create(); let context = Context::create();
let module = context.create_module("app"); let module = context.create_module("app");
let builder = context.create_builder(); let builder = context.create_builder();
let fpm = { get_fpm!(module) }; let fpm = PassManager::create(&module);
roc_gen::llvm::build::add_passes(&fpm);
fpm.initialize();
// Compute main_fn_type before moving subs to Env // Compute main_fn_type before moving subs to Env
let layout = Layout::from_content(&arena, content, &subs, $crate::helpers::eval::POINTER_SIZE) let layout = Layout::from_content(&arena, content, &subs, $crate::helpers::eval::POINTER_SIZE)