nac3core/codegen: optimize for every function

This speeds up compilation and reduces memory usage.
This commit is contained in:
pca006132 2021-10-17 12:56:11 +08:00
parent 1f5bea2448
commit 9850cbe313

View File

@ -12,9 +12,10 @@ use inkwell::{
builder::Builder, builder::Builder,
context::Context, context::Context,
module::Module, module::Module,
passes::{PassManager, PassManagerBuilder},
types::{BasicType, BasicTypeEnum}, types::{BasicType, BasicTypeEnum},
values::PointerValue, values::{FunctionValue, PointerValue},
AddressSpace, AddressSpace, OptimizationLevel,
}; };
use itertools::Itertools; use itertools::Itertools;
use parking_lot::{Condvar, Mutex}; use parking_lot::{Condvar, Mutex};
@ -168,17 +169,27 @@ impl WorkerRegistry {
let mut builder = context.create_builder(); let mut builder = context.create_builder();
let mut module = context.create_module(generator.get_name()); let mut module = context.create_module(generator.get_name());
let pass_builder = PassManagerBuilder::create();
pass_builder.set_optimization_level(OptimizationLevel::Default);
let passes = PassManager::create(&module);
pass_builder.populate_function_pass_manager(&passes);
while let Some(task) = self.receiver.recv().unwrap() { while let Some(task) = self.receiver.recv().unwrap() {
let result = let result =
gen_func(&context, generator, self, builder, module, task, top_level_ctx.clone()); gen_func(&context, generator, self, builder, module, task, top_level_ctx.clone());
builder = result.0; builder = result.0;
module = result.1; module = result.1;
passes.run_on(&result.2);
*self.task_count.lock() -= 1; *self.task_count.lock() -= 1;
self.wait_condvar.notify_all(); self.wait_condvar.notify_all();
} }
// do whatever... let result = module.verify();
module.verify().unwrap(); if let Err(err) = result {
println!("{}", module.print_to_string().to_str().unwrap());
println!("{}", err);
panic!()
}
f.run(&module); f.run(&module);
let mut lock = self.task_count.lock(); let mut lock = self.task_count.lock();
*lock += 1; *lock += 1;
@ -254,8 +265,7 @@ pub fn gen_func<'ctx, G: CodeGenerator + ?Sized>(
module: Module<'ctx>, module: Module<'ctx>,
task: CodeGenTask, task: CodeGenTask,
top_level_ctx: Arc<TopLevelContext>, top_level_ctx: Arc<TopLevelContext>,
) -> (Builder<'ctx>, Module<'ctx>) { ) -> (Builder<'ctx>, Module<'ctx>, FunctionValue<'ctx>) {
// unwrap_or(0) is for unit tests without using rayon
let (mut unifier, primitives) = { let (mut unifier, primitives) = {
let (unifier, primitives) = task.unifier; let (unifier, primitives) = task.unifier;
(Unifier::from_shared_unifier(&unifier), primitives) (Unifier::from_shared_unifier(&unifier), primitives)
@ -367,5 +377,5 @@ pub fn gen_func<'ctx, G: CodeGenerator + ?Sized>(
let CodeGenContext { builder, module, .. } = code_gen_context; let CodeGenContext { builder, module, .. } = code_gen_context;
(builder, module) (builder, module, fn_val)
} }