run LLVM passes

This commit is contained in:
Sebastien Bourdeauducq 2020-03-30 16:58:44 +08:00
parent 8e9bd3df04
commit 38cdab01cb

View File

@ -21,6 +21,7 @@ use inkwell::types;
use inkwell::types::BasicType; use inkwell::types::BasicType;
use inkwell::values; use inkwell::values;
use inkwell::{IntPredicate, FloatPredicate}; use inkwell::{IntPredicate, FloatPredicate};
use inkwell::passes;
#[derive(Debug)] #[derive(Debug)]
@ -71,6 +72,7 @@ type CompileResult<T> = Result<T, CompileError>;
struct CodeGen<'ctx> { struct CodeGen<'ctx> {
context: &'ctx Context, context: &'ctx Context,
module: Module<'ctx>, module: Module<'ctx>,
pass_manager: passes::PassManager<values::FunctionValue<'ctx>>,
builder: Builder<'ctx>, builder: Builder<'ctx>,
current_source_location: ast::Location, current_source_location: ast::Location,
namespace: HashMap<String, values::PointerValue<'ctx>>, namespace: HashMap<String, values::PointerValue<'ctx>>,
@ -78,9 +80,21 @@ struct CodeGen<'ctx> {
impl<'ctx> CodeGen<'ctx> { impl<'ctx> CodeGen<'ctx> {
fn new(context: &'ctx Context) -> CodeGen<'ctx> { fn new(context: &'ctx Context) -> CodeGen<'ctx> {
let module = context.create_module("kernel");
let pass_manager = passes::PassManager::create(&module);
pass_manager.add_instruction_combining_pass();
pass_manager.add_reassociate_pass();
pass_manager.add_gvn_pass();
pass_manager.add_cfg_simplification_pass();
pass_manager.add_basic_alias_analysis_pass();
pass_manager.add_promote_memory_to_register_pass();
pass_manager.add_instruction_combining_pass();
pass_manager.add_reassociate_pass();
pass_manager.initialize();
CodeGen { CodeGen {
context, context, module, pass_manager,
module: context.create_module("kernel"),
builder: context.create_builder(), builder: context.create_builder(),
current_source_location: ast::Location::default(), current_source_location: ast::Location::default(),
namespace: HashMap::new(), namespace: HashMap::new(),
@ -117,7 +131,7 @@ impl<'ctx> CodeGen<'ctx> {
decorator_list: &[ast::Expression], decorator_list: &[ast::Expression],
returns: &Option<ast::Expression>, returns: &Option<ast::Expression>,
is_async: bool, is_async: bool,
) -> CompileResult<()> { ) -> CompileResult<values::FunctionValue<'ctx>> {
if is_async { if is_async {
return Err(self.compile_error(CompileErrorKind::Unsupported("async functions"))) return Err(self.compile_error(CompileErrorKind::Unsupported("async functions")))
} }
@ -174,7 +188,7 @@ impl<'ctx> CodeGen<'ctx> {
for statement in body.iter() { for statement in body.iter() {
self.compile_statement(statement, return_type)?; self.compile_statement(statement, return_type)?;
} }
Ok(()) Ok(function)
} }
fn compile_expression( fn compile_expression(
@ -418,7 +432,9 @@ impl<'ctx> CodeGen<'ctx> {
decorator_list, decorator_list,
returns, returns,
} = &statement.node { } = &statement.node {
self.compile_function_def(name, args, body, decorator_list, returns, *is_async) let function = self.compile_function_def(name, args, body, decorator_list, returns, *is_async)?;
self.pass_manager.run_on(&function);
Ok(())
} else { } else {
Err(self.compile_error(CompileErrorKind::Internal("top-level is not a function definition"))) Err(self.compile_error(CompileErrorKind::Internal("top-level is not a function definition")))
} }