forked from M-Labs/nac3
messy
This commit is contained in:
parent
b04631e935
commit
258aa4c9d6
|
@ -158,7 +158,9 @@
|
||||||
cargo-insta
|
cargo-insta
|
||||||
clippy
|
clippy
|
||||||
rustfmt
|
rustfmt
|
||||||
|
lldb_14
|
||||||
];
|
];
|
||||||
|
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
|
||||||
};
|
};
|
||||||
devShells.x86_64-linux.msys2 = pkgs.mkShell {
|
devShells.x86_64-linux.msys2 = pkgs.mkShell {
|
||||||
name = "nac3-dev-shell-msys2";
|
name = "nac3-dev-shell-msys2";
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::io::Write;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -763,34 +764,54 @@ impl Nac3 {
|
||||||
let membuffer = membuffers.clone();
|
let membuffer = membuffers.clone();
|
||||||
|
|
||||||
let f = Arc::new(WithCall::new(Box::new(move |module| {
|
let f = Arc::new(WithCall::new(Box::new(move |module| {
|
||||||
|
// println!("\n\n--------------\n{}\n--------------\n", module.print_to_string().to_string());
|
||||||
let buffer = module.write_bitcode_to_memory();
|
let buffer = module.write_bitcode_to_memory();
|
||||||
let buffer = buffer.as_slice().into();
|
let buffer = buffer.as_slice().into();
|
||||||
membuffer.lock().push(buffer);
|
membuffer.lock().push(buffer);
|
||||||
})));
|
})));
|
||||||
let size_t = if self.isa == Isa::Host { 64 } else { 32 };
|
let size_t = if self.isa == Isa::Host { 64 } else { 32 };
|
||||||
let thread_names: Vec<String> = (0..4).map(|_| "main".to_string()).collect();
|
print!("input number of thread: ");
|
||||||
|
std::io::stdout().flush().unwrap();
|
||||||
|
let mut buffer = String::with_capacity(2);
|
||||||
|
// std::io::stdin().read_line(&mut buffer)?;
|
||||||
|
// println!("{} as input", buffer);
|
||||||
|
let num_thread = buffer.trim().parse::<i32>().unwrap_or_else(|_| {/* println!("using default (4 thread)"); */4});
|
||||||
|
let thread_names: Vec<String> = (0..num_thread).map(|_| "main".to_string()).collect();
|
||||||
|
// println!("number of threads: {}", thread_names.len());
|
||||||
|
// let thread_names: Vec<String> = (0..4).map(|_| "main".to_string()).collect();
|
||||||
let threads: Vec<_> = thread_names
|
let threads: Vec<_> = thread_names
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| Box::new(ArtiqCodeGenerator::new(s.to_string(), size_t, self.time_fns)))
|
.map(|s| Box::new(ArtiqCodeGenerator::new(s.to_string(), size_t, self.time_fns)))
|
||||||
.collect();
|
.collect();
|
||||||
|
println!("------0:");
|
||||||
let membuffer = membuffers.clone();
|
// let membuffer = membuffers.clone();
|
||||||
py.allow_threads(|| {
|
py.allow_threads(|| {
|
||||||
let (registry, handles) = WorkerRegistry::create_workers(threads, top_level.clone(), f);
|
let (registry, handles) = WorkerRegistry::create_workers(threads, top_level.clone(), f);
|
||||||
registry.add_task(task);
|
registry.add_task(task);
|
||||||
registry.wait_tasks_complete(handles);
|
registry.wait_tasks_complete(handles);
|
||||||
|
println!("------1:");
|
||||||
|
|
||||||
let mut generator = ArtiqCodeGenerator::new("attributes_writeback".to_string(), size_t, self.time_fns);
|
// let mut generator = ArtiqCodeGenerator::new("attributes_writeback".to_string(), size_t, self.time_fns);
|
||||||
let context = inkwell::context::Context::create();
|
// let context = inkwell::context::Context::create();
|
||||||
let module = context.create_module("attributes_writeback");
|
// let module = context.create_module("attributes_writeback");
|
||||||
let builder = context.create_builder();
|
// module.add_basic_value_flag(
|
||||||
let (_, module, _) = gen_func_impl(&context, &mut generator, ®istry, builder, module,
|
// "Debug Info Version",
|
||||||
attributes_writeback_task, |generator, ctx| {
|
// inkwell::module::FlagBehavior::Warning,
|
||||||
attributes_writeback(ctx, generator, inner_resolver.as_ref(), host_attributes)
|
// context.i32_type().const_int(3, false),
|
||||||
}).unwrap();
|
// );
|
||||||
let buffer = module.write_bitcode_to_memory();
|
// module.add_basic_value_flag(
|
||||||
let buffer = buffer.as_slice().into();
|
// "Dwarf Version",
|
||||||
membuffer.lock().push(buffer);
|
// inkwell::module::FlagBehavior::Warning,
|
||||||
|
// context.i32_type().const_int(4, false),
|
||||||
|
// );
|
||||||
|
// let builder = context.create_builder();
|
||||||
|
// let (_, module, _) = gen_func_impl(&context, &mut generator, ®istry, builder, module,
|
||||||
|
// attributes_writeback_task, |generator, ctx| {
|
||||||
|
// attributes_writeback(ctx, generator, inner_resolver.as_ref(), host_attributes)
|
||||||
|
// }).unwrap();
|
||||||
|
// let buffer = module.write_bitcode_to_memory();
|
||||||
|
// let buffer = buffer.as_slice().into();
|
||||||
|
// membuffer.lock().push(buffer);
|
||||||
});
|
});
|
||||||
|
|
||||||
let context = inkwell::context::Context::create();
|
let context = inkwell::context::Context::create();
|
||||||
|
@ -798,21 +819,25 @@ impl Nac3 {
|
||||||
let main = context
|
let main = context
|
||||||
.create_module_from_ir(MemoryBuffer::create_from_memory_range(&buffers[0], "main"))
|
.create_module_from_ir(MemoryBuffer::create_from_memory_range(&buffers[0], "main"))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
// println!(":1: {}", buffers.len());
|
||||||
for buffer in buffers.iter().skip(1) {
|
for buffer in buffers.iter().skip(1) {
|
||||||
let other = context
|
let other = context
|
||||||
.create_module_from_ir(MemoryBuffer::create_from_memory_range(buffer, "main"))
|
.create_module_from_ir(MemoryBuffer::create_from_memory_range(buffer, "main"))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// println!(":2:");
|
||||||
main.link_in_module(other)
|
main.link_in_module(other)
|
||||||
.map_err(|err| CompileError::new_err(err.to_string()))?;
|
.map_err(|err| CompileError::new_err(err.to_string()))?;
|
||||||
}
|
}
|
||||||
let builder = context.create_builder();
|
// let builder = context.create_builder();
|
||||||
let modinit_return = main.get_function("__modinit__").unwrap().get_last_basic_block().unwrap().get_terminator().unwrap();
|
// let modinit_return = main.get_function("__modinit__").unwrap().get_last_basic_block().unwrap().get_terminator().unwrap();
|
||||||
builder.position_before(&modinit_return);
|
// builder.position_before(&modinit_return);
|
||||||
builder.build_call(main.get_function("attributes_writeback").unwrap(), &[], "attributes_writeback");
|
// builder.build_call(main.get_function("attributes_writeback").unwrap(), &[], "attributes_writeback");
|
||||||
|
|
||||||
main.link_in_module(load_irrt(&context))
|
// main.link_in_module(load_irrt(&context))
|
||||||
.map_err(|err| CompileError::new_err(err.to_string()))?;
|
// .map_err(|err| CompileError::new_err(err.to_string()))?;
|
||||||
|
|
||||||
|
// println!(":3:");
|
||||||
|
|
||||||
let mut function_iter = main.get_first_function();
|
let mut function_iter = main.get_first_function();
|
||||||
while let Some(func) = function_iter {
|
while let Some(func) = function_iter {
|
||||||
|
@ -822,12 +847,14 @@ impl Nac3 {
|
||||||
function_iter = func.get_next_function();
|
function_iter = func.get_next_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
let builder = PassManagerBuilder::create();
|
// let builder = PassManagerBuilder::create();
|
||||||
builder.set_optimization_level(OptimizationLevel::Aggressive);
|
// builder.set_optimization_level(OptimizationLevel::Aggressive);
|
||||||
let passes = PassManager::create(());
|
// let passes = PassManager::create(());
|
||||||
builder.set_inliner_with_threshold(255);
|
// builder.set_inliner_with_threshold(255);
|
||||||
builder.populate_module_pass_manager(&passes);
|
// builder.populate_module_pass_manager(&passes);
|
||||||
passes.run_on(&main);
|
// passes.run_on(&main);
|
||||||
|
|
||||||
|
// println!("\n\n==========={}\n=============", main.print_to_string().to_string());
|
||||||
|
|
||||||
let (triple, features) = match isa {
|
let (triple, features) = match isa {
|
||||||
Isa::Host => (
|
Isa::Host => (
|
||||||
|
|
|
@ -165,6 +165,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||||
) -> BasicTypeEnum<'ctx> {
|
) -> BasicTypeEnum<'ctx> {
|
||||||
get_llvm_type(
|
get_llvm_type(
|
||||||
self.ctx,
|
self.ctx,
|
||||||
|
&self.module,
|
||||||
generator,
|
generator,
|
||||||
&mut self.unifier,
|
&mut self.unifier,
|
||||||
self.top_level,
|
self.top_level,
|
||||||
|
@ -460,7 +461,8 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||||
let i1_true = i1.const_all_ones();
|
let i1_true = i1.const_all_ones();
|
||||||
let expect_fun = self.module.get_function("llvm.expect.i1").unwrap_or_else(|| {
|
let expect_fun = self.module.get_function("llvm.expect.i1").unwrap_or_else(|| {
|
||||||
self.module.add_function(
|
self.module.add_function(
|
||||||
"llvm.expect",
|
// FIXME:
|
||||||
|
"llvm.expect.i1",
|
||||||
i1.fn_type(&[i1.into(), i1.into()], false),
|
i1.fn_type(&[i1.into(), i1.into()], false),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
@ -693,6 +695,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>(
|
||||||
if let Some(obj) = &obj {
|
if let Some(obj) = &obj {
|
||||||
args.insert(0, FuncArg { name: "self".into(), ty: obj.0, default_value: None });
|
args.insert(0, FuncArg { name: "self".into(), ty: obj.0, default_value: None });
|
||||||
}
|
}
|
||||||
|
// println!("\n2=======getting types for func `{}`=======", symbol);
|
||||||
let ret_type = if ctx.unifier.unioned(fun.0.ret, ctx.primitives.none) {
|
let ret_type = if ctx.unifier.unioned(fun.0.ret, ctx.primitives.none) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -715,6 +718,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>(
|
||||||
Some(ret_type) if !has_sret => ret_type.fn_type(¶ms, false),
|
Some(ret_type) if !has_sret => ret_type.fn_type(¶ms, false),
|
||||||
_ => ctx.ctx.void_type().fn_type(¶ms, false)
|
_ => ctx.ctx.void_type().fn_type(¶ms, false)
|
||||||
};
|
};
|
||||||
|
// println!("2=======got types for func `{}`: {}=======\n", symbol, fun_ty.print_to_string().to_string());
|
||||||
let fun_val = ctx.module.add_function(&symbol, fun_ty, None);
|
let fun_val = ctx.module.add_function(&symbol, fun_ty, None);
|
||||||
let offset = if has_sret {
|
let offset = if has_sret {
|
||||||
fun_val.add_attribute(AttributeLoc::Param(0),
|
fun_val.add_attribute(AttributeLoc::Param(0),
|
||||||
|
|
|
@ -203,9 +203,13 @@ impl WorkerRegistry {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn worker_thread<G: CodeGenerator>(&self, generator: &mut G, f: Arc<WithCall>) {
|
fn worker_thread<G: CodeGenerator>(&self, generator: &mut G, f: Arc<WithCall>) {
|
||||||
|
// println!("thread start! 1");
|
||||||
let context = Context::create();
|
let context = Context::create();
|
||||||
|
// println!("thread start! 2");
|
||||||
let mut builder = context.create_builder();
|
let mut builder = context.create_builder();
|
||||||
let module = context.create_module(generator.get_name());
|
// println!("thread start! 3");
|
||||||
|
let mut module = context.create_module(generator.get_name());
|
||||||
|
// println!("thread start! 4");
|
||||||
|
|
||||||
module.add_basic_value_flag(
|
module.add_basic_value_flag(
|
||||||
"Debug Info Version",
|
"Debug Info Version",
|
||||||
|
@ -218,23 +222,46 @@ impl WorkerRegistry {
|
||||||
context.i32_type().const_int(4, false),
|
context.i32_type().const_int(4, false),
|
||||||
);
|
);
|
||||||
|
|
||||||
let pass_builder = PassManagerBuilder::create();
|
|
||||||
pass_builder.set_optimization_level(OptimizationLevel::Default);
|
|
||||||
let passes = PassManager::create(&module);
|
|
||||||
pass_builder.populate_function_pass_manager(&passes);
|
|
||||||
|
|
||||||
let mut errors = HashSet::new();
|
let mut errors = HashSet::new();
|
||||||
|
// while let Some(task) = self.receiver.recv().unwrap() {
|
||||||
|
// println!("creating tmp");
|
||||||
|
// let tmp_module = context.create_module("tmp");
|
||||||
|
// println!("creating tmp done {}", tmp_module.print_to_string().to_string());
|
||||||
|
// let n = task.symbol_name.clone();
|
||||||
|
// println!("{} start0:", n);
|
||||||
|
// let res = gen_func(&context, generator, self, builder, tmp_module, task);
|
||||||
|
// match res {
|
||||||
|
// Ok(result) => {
|
||||||
|
// builder = result.0;
|
||||||
|
// passes.run_on(&result.2);
|
||||||
|
// result.1.verify().unwrap();
|
||||||
|
// module.link_in_module(result.1).unwrap();
|
||||||
|
// }
|
||||||
|
// Err((old_builder, e)) => {
|
||||||
|
// builder = old_builder;
|
||||||
|
// errors.insert(e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// println!("{} done0:", n);
|
||||||
|
// *self.task_count.lock() -= 1;
|
||||||
|
// self.wait_condvar.notify_all();
|
||||||
|
// }
|
||||||
|
|
||||||
while let Some(task) = self.receiver.recv().unwrap() {
|
while let Some(task) = self.receiver.recv().unwrap() {
|
||||||
let tmp_module = context.create_module("tmp");
|
match gen_func(&context, generator, self, builder, module, task) {
|
||||||
match gen_func(&context, generator, self, builder, tmp_module, task) {
|
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
builder = result.0;
|
builder = result.0;
|
||||||
passes.run_on(&result.2);
|
// passes.run_on(&result.2);
|
||||||
module.link_in_module(result.1).unwrap();
|
// module.link_in_module(result.1).unwrap();
|
||||||
|
module = result.1;
|
||||||
}
|
}
|
||||||
Err((old_builder, e)) => {
|
Err((old_builder, e)) => {
|
||||||
builder = old_builder;
|
// builder = old_builder;
|
||||||
|
// create a new module to continue to just collect other errors
|
||||||
|
// module = context.create_module(generator.get_name());
|
||||||
errors.insert(e);
|
errors.insert(e);
|
||||||
|
panic!("Codegen error: {}", errors.into_iter().sorted().join("\n----------\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*self.task_count.lock() -= 1;
|
*self.task_count.lock() -= 1;
|
||||||
|
@ -246,10 +273,20 @@ impl WorkerRegistry {
|
||||||
|
|
||||||
let result = module.verify();
|
let result = module.verify();
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
println!("{}", module.print_to_string().to_str().unwrap());
|
println!("\n\n!!!!!!!!!!!!!!!!!!error!!!!!!!!!!!!!!!!!!!!!");
|
||||||
println!("{}", err);
|
println!("{}", module.print_to_string().to_string());
|
||||||
|
println!("{}", err.to_string());
|
||||||
|
println!("!!!!!!!!!!!!!!!!!!error!!!!!!!!!!!!!!!!!!!!!\n\n");
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("aaaa");
|
||||||
|
let pass_builder = PassManagerBuilder::create();
|
||||||
|
pass_builder.set_optimization_level(OptimizationLevel::Default);
|
||||||
|
let passes = PassManager::create(&module);
|
||||||
|
pass_builder.populate_function_pass_manager(&passes);
|
||||||
|
println!("ddddd");
|
||||||
|
|
||||||
f.run(&module);
|
f.run(&module);
|
||||||
let mut lock = self.task_count.lock();
|
let mut lock = self.task_count.lock();
|
||||||
*lock += 1;
|
*lock += 1;
|
||||||
|
@ -271,6 +308,7 @@ pub struct CodeGenTask {
|
||||||
|
|
||||||
fn get_llvm_type<'ctx>(
|
fn get_llvm_type<'ctx>(
|
||||||
ctx: &'ctx Context,
|
ctx: &'ctx Context,
|
||||||
|
module: &Module<'ctx>,
|
||||||
generator: &mut dyn CodeGenerator,
|
generator: &mut dyn CodeGenerator,
|
||||||
unifier: &mut Unifier,
|
unifier: &mut Unifier,
|
||||||
top_level: &TopLevelContext,
|
top_level: &TopLevelContext,
|
||||||
|
@ -282,6 +320,7 @@ fn get_llvm_type<'ctx>(
|
||||||
// we assume the type cache should already contain primitive types,
|
// we assume the type cache should already contain primitive types,
|
||||||
// and they should be passed by value instead of passing as pointer.
|
// and they should be passed by value instead of passing as pointer.
|
||||||
type_cache.get(&unifier.get_representative(ty)).cloned().unwrap_or_else(|| {
|
type_cache.get(&unifier.get_representative(ty)).cloned().unwrap_or_else(|| {
|
||||||
|
// println!("getting new: {}", unifier.stringify(ty));
|
||||||
let ty_enum = unifier.get_ty(ty);
|
let ty_enum = unifier.get_ty(ty);
|
||||||
let result = match &*ty_enum {
|
let result = match &*ty_enum {
|
||||||
TObj { obj_id, fields, .. } => {
|
TObj { obj_id, fields, .. } => {
|
||||||
|
@ -295,6 +334,7 @@ fn get_llvm_type<'ctx>(
|
||||||
) if *obj_id == *opt_id => {
|
) if *obj_id == *opt_id => {
|
||||||
return get_llvm_type(
|
return get_llvm_type(
|
||||||
ctx,
|
ctx,
|
||||||
|
module,
|
||||||
generator,
|
generator,
|
||||||
unifier,
|
unifier,
|
||||||
top_level,
|
top_level,
|
||||||
|
@ -314,6 +354,28 @@ fn get_llvm_type<'ctx>(
|
||||||
let ty = if let TopLevelDef::Class { name, fields: fields_list, .. } =
|
let ty = if let TopLevelDef::Class { name, fields: fields_list, .. } =
|
||||||
&*definition.read()
|
&*definition.read()
|
||||||
{
|
{
|
||||||
|
// let struct_type = {
|
||||||
|
// let struct_type = ctx.opaque_struct_type(&name.to_string());
|
||||||
|
// type_cache.insert(unifier.get_representative(ty), struct_type.ptr_type(AddressSpace::Generic).into());
|
||||||
|
// let fields = fields_list
|
||||||
|
// .iter()
|
||||||
|
// .map(|f| {
|
||||||
|
// get_llvm_type(
|
||||||
|
// ctx,
|
||||||
|
// module,
|
||||||
|
// generator,
|
||||||
|
// unifier,
|
||||||
|
// top_level,
|
||||||
|
// type_cache,
|
||||||
|
// primitives,
|
||||||
|
// fields[&f.0].0,
|
||||||
|
// )
|
||||||
|
// })
|
||||||
|
// .collect_vec();
|
||||||
|
// struct_type.set_body(&fields, false);
|
||||||
|
// struct_type
|
||||||
|
// };
|
||||||
|
let struct_type = module.get_struct_type(&name.to_string()).unwrap_or_else(|| {
|
||||||
let struct_type = ctx.opaque_struct_type(&name.to_string());
|
let struct_type = ctx.opaque_struct_type(&name.to_string());
|
||||||
type_cache.insert(unifier.get_representative(ty), struct_type.ptr_type(AddressSpace::Generic).into());
|
type_cache.insert(unifier.get_representative(ty), struct_type.ptr_type(AddressSpace::Generic).into());
|
||||||
let fields = fields_list
|
let fields = fields_list
|
||||||
|
@ -321,6 +383,7 @@ fn get_llvm_type<'ctx>(
|
||||||
.map(|f| {
|
.map(|f| {
|
||||||
get_llvm_type(
|
get_llvm_type(
|
||||||
ctx,
|
ctx,
|
||||||
|
module,
|
||||||
generator,
|
generator,
|
||||||
unifier,
|
unifier,
|
||||||
top_level,
|
top_level,
|
||||||
|
@ -331,7 +394,11 @@ fn get_llvm_type<'ctx>(
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
struct_type.set_body(&fields, false);
|
struct_type.set_body(&fields, false);
|
||||||
struct_type.ptr_type(AddressSpace::Generic).into()
|
struct_type
|
||||||
|
});
|
||||||
|
let res = struct_type.ptr_type(AddressSpace::Generic).into();
|
||||||
|
// println!("got: {:?}", res);
|
||||||
|
res
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
@ -341,14 +408,14 @@ fn get_llvm_type<'ctx>(
|
||||||
// a struct with fields in the order present in the tuple
|
// a struct with fields in the order present in the tuple
|
||||||
let fields = ty
|
let fields = ty
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| get_llvm_type(ctx, generator, unifier, top_level, type_cache, primitives, *ty))
|
.map(|ty| get_llvm_type(ctx, module, generator, unifier, top_level, type_cache, primitives, *ty))
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
ctx.struct_type(&fields, false).into()
|
ctx.struct_type(&fields, false).into()
|
||||||
}
|
}
|
||||||
TList { ty } => {
|
TList { ty } => {
|
||||||
// a struct with an integer and a pointer to an array
|
// a struct with an integer and a pointer to an array
|
||||||
let element_type =
|
let element_type =
|
||||||
get_llvm_type(ctx, generator, unifier, top_level, type_cache, primitives, *ty);
|
get_llvm_type(ctx, module, generator, unifier, top_level, type_cache, primitives, *ty);
|
||||||
let fields = [
|
let fields = [
|
||||||
element_type.ptr_type(AddressSpace::Generic).into(),
|
element_type.ptr_type(AddressSpace::Generic).into(),
|
||||||
generator.get_size_type(ctx).into(),
|
generator.get_size_type(ctx).into(),
|
||||||
|
@ -475,10 +542,11 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
// println!("\n=======getting types for func `{}`=======", task.symbol_name);
|
||||||
let ret_type = if unifier.unioned(ret, primitives.none) {
|
let ret_type = if unifier.unioned(ret, primitives.none) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(get_llvm_type(context, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, &primitives, ret))
|
Some(get_llvm_type(context, &module, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, &primitives, ret))
|
||||||
};
|
};
|
||||||
|
|
||||||
let has_sret = ret_type.map_or(false, |ty| need_sret(context, ty));
|
let has_sret = ret_type.map_or(false, |ty| need_sret(context, ty));
|
||||||
|
@ -487,6 +555,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
|
||||||
.map(|arg| {
|
.map(|arg| {
|
||||||
get_llvm_type(
|
get_llvm_type(
|
||||||
context,
|
context,
|
||||||
|
&module,
|
||||||
generator,
|
generator,
|
||||||
&mut unifier,
|
&mut unifier,
|
||||||
top_level_ctx.as_ref(),
|
top_level_ctx.as_ref(),
|
||||||
|
@ -497,7 +566,6 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|
||||||
if has_sret {
|
if has_sret {
|
||||||
params.insert(0, ret_type.unwrap().ptr_type(AddressSpace::Generic).into());
|
params.insert(0, ret_type.unwrap().ptr_type(AddressSpace::Generic).into());
|
||||||
}
|
}
|
||||||
|
@ -506,7 +574,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
|
||||||
Some(ret_type) if !has_sret => ret_type.fn_type(¶ms, false),
|
Some(ret_type) if !has_sret => ret_type.fn_type(¶ms, false),
|
||||||
_ => context.void_type().fn_type(¶ms, false)
|
_ => context.void_type().fn_type(¶ms, false)
|
||||||
};
|
};
|
||||||
|
// println!("=======got types for func `{}`: {:?}=======\n", task.symbol_name, fn_type);
|
||||||
let symbol = &task.symbol_name;
|
let symbol = &task.symbol_name;
|
||||||
let fn_val =
|
let fn_val =
|
||||||
module.get_function(symbol).unwrap_or_else(|| module.add_function(symbol, fn_type, None));
|
module.get_function(symbol).unwrap_or_else(|| module.add_function(symbol, fn_type, None));
|
||||||
|
@ -535,6 +603,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
|
||||||
let alloca = builder.build_alloca(
|
let alloca = builder.build_alloca(
|
||||||
get_llvm_type(
|
get_llvm_type(
|
||||||
context,
|
context,
|
||||||
|
&module,
|
||||||
generator,
|
generator,
|
||||||
&mut unifier,
|
&mut unifier,
|
||||||
top_level_ctx.as_ref(),
|
top_level_ctx.as_ref(),
|
||||||
|
@ -678,11 +747,15 @@ pub fn gen_func<'ctx, G: CodeGenerator>(
|
||||||
module: Module<'ctx>,
|
module: Module<'ctx>,
|
||||||
task: CodeGenTask,
|
task: CodeGenTask,
|
||||||
) -> Result<(Builder<'ctx>, Module<'ctx>, FunctionValue<'ctx>), (Builder<'ctx>, String)> {
|
) -> Result<(Builder<'ctx>, Module<'ctx>, FunctionValue<'ctx>), (Builder<'ctx>, String)> {
|
||||||
|
let n = task.symbol_name.clone();
|
||||||
|
println!("{} start:", n);
|
||||||
let body = task.body.clone();
|
let body = task.body.clone();
|
||||||
gen_func_impl(context, generator, registry, builder, module, task, |generator, ctx| {
|
let res = gen_func_impl(context, generator, registry, builder, module, task, |generator, ctx| {
|
||||||
for stmt in body.iter() {
|
for stmt in body.iter() {
|
||||||
generator.gen_stmt(ctx, stmt)?;
|
generator.gen_stmt(ctx, stmt)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
});
|
||||||
|
println!("{} end:", n);
|
||||||
|
res
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ if [ -z "$1" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -e ../../target/release/nac3standalone ]; then
|
if [ -e ../../target/debug/nac3standalone ]; then
|
||||||
nac3standalone=../../target/release/nac3standalone
|
nac3standalone=../../target/debug/nac3standalone
|
||||||
else
|
else
|
||||||
# used by Nix builds
|
# used by Nix builds
|
||||||
nac3standalone=../../target/x86_64-unknown-linux-gnu/release/nac3standalone
|
nac3standalone=../../target/x86_64-unknown-linux-gnu/release/nac3standalone
|
||||||
|
|
|
@ -2,7 +2,7 @@ use inkwell::{
|
||||||
memory_buffer::MemoryBuffer,
|
memory_buffer::MemoryBuffer,
|
||||||
passes::{PassManager, PassManagerBuilder},
|
passes::{PassManager, PassManagerBuilder},
|
||||||
targets::*,
|
targets::*,
|
||||||
OptimizationLevel,
|
OptimizationLevel, module::Module, context::Context, AddressSpace,
|
||||||
};
|
};
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use std::{borrow::Borrow, collections::HashMap, env, fs, path::Path, sync::Arc};
|
use std::{borrow::Borrow, collections::HashMap, env, fs, path::Path, sync::Arc};
|
||||||
|
@ -156,7 +156,7 @@ fn handle_assignment_pattern(
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let file_name = env::args().nth(1).unwrap();
|
let file_name = env::args().nth(1).unwrap();
|
||||||
let threads: u32 = env::args().nth(2).map(|s| str::parse(&s).unwrap()).unwrap_or(1);
|
let threads: u32 = env::args().nth(2).map(|s| str::parse(&s).unwrap()).unwrap_or(2);
|
||||||
|
|
||||||
Target::initialize_all(&InitializationConfig::default());
|
Target::initialize_all(&InitializationConfig::default());
|
||||||
|
|
||||||
|
@ -313,4 +313,210 @@ fn main() {
|
||||||
target_machine
|
target_machine
|
||||||
.write_to_file(&main, FileType::Object, Path::new("module.o"))
|
.write_to_file(&main, FileType::Object, Path::new("module.o"))
|
||||||
.expect("couldn't write module to file");
|
.expect("couldn't write module to file");
|
||||||
|
|
||||||
|
|
||||||
|
// ===================================
|
||||||
|
// let ctxx = inkwell::context::Context::create();
|
||||||
|
// let ctxx2 = inkwell::context::Context::create();
|
||||||
|
// let ctxx3 = inkwell::context::Context::create();
|
||||||
|
|
||||||
|
// // let builder = PassManagerBuilder::create();
|
||||||
|
// // builder.set_optimization_level(OptimizationLevel::Aggressive);
|
||||||
|
// // let passes = PassManager::create(());
|
||||||
|
// // builder.set_inliner_with_threshold(255);
|
||||||
|
// // builder.populate_module_pass_manager(&passes);
|
||||||
|
|
||||||
|
// let mmm = test2(&ctxx, &ctxx, &ctxx3);
|
||||||
|
// // passes.run_on(&mmm);
|
||||||
|
// Target::initialize_all(&InitializationConfig::default());
|
||||||
|
// let triple = TargetMachine::get_default_triple();
|
||||||
|
// let target = Target::from_triple(&triple).expect("couldn't create target from target triple");
|
||||||
|
// let target_machine = target
|
||||||
|
// .create_target_machine(
|
||||||
|
// &triple,
|
||||||
|
// "",
|
||||||
|
// "",
|
||||||
|
// OptimizationLevel::Default,
|
||||||
|
// RelocMode::Default,
|
||||||
|
// CodeModel::Default,
|
||||||
|
// )
|
||||||
|
// .expect("couldn't create target machine");
|
||||||
|
// target_machine
|
||||||
|
// .write_to_file(&mmm, FileType::Object, Path::new("module.o"))
|
||||||
|
// .expect("couldn't write module to file");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test<'ctx>(ctx: &'ctx Context, ctx2: &'ctx Context, ctx3: &'ctx Context) -> Module<'ctx> {
|
||||||
|
let module = ctx.create_module("test");
|
||||||
|
let module2 = ctx2.create_module("test2");
|
||||||
|
let builder = ctx.create_builder();
|
||||||
|
let builder2 = ctx2.create_builder();
|
||||||
|
|
||||||
|
let int32 = ctx.i32_type();
|
||||||
|
let int8 = ctx.i8_type();
|
||||||
|
let int322 = ctx2.i32_type();
|
||||||
|
let int82 = ctx2.i8_type();
|
||||||
|
|
||||||
|
let opaque = ctx.opaque_struct_type("TestType");
|
||||||
|
let opaque = ctx.opaque_struct_type("TestType");
|
||||||
|
opaque.set_body(&[int32.into(), opaque.ptr_type(AddressSpace::Generic).into()], false);
|
||||||
|
let opaque = opaque.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
|
// let opaque2 = module.get_struct_type("TestType").unwrap();
|
||||||
|
let opaque2 = ctx2.opaque_struct_type("TestType");
|
||||||
|
// let opaque2 = ctx2.opaque_struct_type("TestType");
|
||||||
|
opaque2.set_body(&[int322.into(), opaque2.ptr_type(AddressSpace::Generic).into()], false);
|
||||||
|
let opaque2 = opaque2.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
|
|
||||||
|
let func2 = module2.add_function("f", ctx2.void_type().fn_type(&[opaque2.into()], false), None);
|
||||||
|
let func2_bb = ctx2.append_basic_block(func2, "init");
|
||||||
|
builder2.position_at_end(func2_bb);
|
||||||
|
builder2.build_return(None);
|
||||||
|
|
||||||
|
let func = module.add_function("run", ctx.void_type().fn_type(&[], false), None);
|
||||||
|
let fun2_mod1 = module.add_function("f", ctx.void_type().fn_type(&[opaque.into()], false), None);
|
||||||
|
let func1_bb = ctx.append_basic_block(func, "init");
|
||||||
|
builder.position_at_end(func1_bb);
|
||||||
|
let opaque1_ptr = builder.build_alloca(opaque.get_element_type().into_struct_type(), "alloc1");
|
||||||
|
let opaque2_ptr = builder.build_alloca(opaque.get_element_type().into_struct_type(), "alloc2");
|
||||||
|
builder.build_store(
|
||||||
|
unsafe { builder.build_gep(opaque1_ptr, &[int32.const_zero(), int32.const_zero()], "gep") },
|
||||||
|
int32.const_int(123, false)
|
||||||
|
);
|
||||||
|
builder.build_store(
|
||||||
|
unsafe { builder.build_gep(opaque2_ptr, &[int32.const_zero(), int32.const_zero()], "gep") },
|
||||||
|
int32.const_int(23, false)
|
||||||
|
);
|
||||||
|
builder.build_store(
|
||||||
|
unsafe { builder.build_gep(opaque1_ptr, &[int32.const_zero(), int32.const_int(1, false)], "gep") },
|
||||||
|
opaque2_ptr
|
||||||
|
);
|
||||||
|
builder.build_store(
|
||||||
|
unsafe { builder.build_gep(opaque2_ptr, &[int32.const_zero(), int32.const_int(1, false)], "gep") },
|
||||||
|
opaque1_ptr
|
||||||
|
);
|
||||||
|
// let arr = builder.build_array_alloca(opaque, int32.const_int(2, false), "arr");
|
||||||
|
// builder.build_store(
|
||||||
|
// unsafe { builder.build_gep(arr, &[int32.const_zero()], "zero")},
|
||||||
|
// opaque1_ptr
|
||||||
|
// );
|
||||||
|
let arr = module.add_global(
|
||||||
|
opaque.array_type(2),
|
||||||
|
None,
|
||||||
|
"arr_const",
|
||||||
|
);
|
||||||
|
arr.set_initializer(&opaque.const_array(&[opaque1_ptr, opaque2_ptr]));
|
||||||
|
let arr = arr.as_pointer_value();
|
||||||
|
let arg = builder.build_load(
|
||||||
|
unsafe { builder.build_gep(arr, &[int32.const_zero(), int32.const_zero()], "zero")},
|
||||||
|
"load"
|
||||||
|
);
|
||||||
|
builder.build_call(fun2_mod1, &[arg.into()], "call");
|
||||||
|
builder.build_return(None);
|
||||||
|
|
||||||
|
// builder.build_call(func2, args, name)
|
||||||
|
|
||||||
|
println!("before: \n========= module1: \n{}\n=========module2: \n{}=======\n\n", module.print_to_string().to_string(), module2.print_to_string().to_string());
|
||||||
|
module.verify().unwrap();
|
||||||
|
module2.verify().unwrap();
|
||||||
|
// module.link_in_module(module2).unwrap();
|
||||||
|
let mut mem: Vec<Vec<u8>> = Default::default();
|
||||||
|
let bitcode1 = module.write_bitcode_to_memory();
|
||||||
|
let bitcode1 = bitcode1.as_slice();
|
||||||
|
mem.push(bitcode1.into());
|
||||||
|
let bitcode2 = module2.write_bitcode_to_memory();
|
||||||
|
let bitcode2 = bitcode2.as_slice();
|
||||||
|
mem.push(bitcode2.into());
|
||||||
|
|
||||||
|
let mod1 = ctx3.create_module_from_ir(MemoryBuffer::create_from_memory_range(&mem[0], "mod1")).unwrap();
|
||||||
|
let mod2 = ctx3.create_module_from_ir(MemoryBuffer::create_from_memory_range(&mem[1], "mod2")).unwrap();
|
||||||
|
mod1.verify().unwrap();
|
||||||
|
mod2.verify().unwrap();
|
||||||
|
mod1.link_in_module(mod2).unwrap();
|
||||||
|
let module = mod1;
|
||||||
|
println!("after");
|
||||||
|
|
||||||
|
println!("\n\n====finish===\n{}\n=====finish=====\n\n\n", module.print_to_string().to_string());
|
||||||
|
|
||||||
|
|
||||||
|
println!("before2");
|
||||||
|
match module.verify() {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(s) => {
|
||||||
|
println!("after2");
|
||||||
|
println!("\n\n=======\n{}\n==========\n{}\n\n", module.print_to_string().to_string(), s.to_string());
|
||||||
|
println!("after3");
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
println!("\n=====done===========");
|
||||||
|
module
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test2<'ctx>(ctx: &'ctx Context, ctx2: &'ctx Context, ctx3: &'ctx Context) -> Module<'ctx> {
|
||||||
|
let module = ctx.create_module("test");
|
||||||
|
let module2 = ctx2.create_module("test2");
|
||||||
|
let builder = ctx.create_builder();
|
||||||
|
let builder2 = ctx2.create_builder();
|
||||||
|
|
||||||
|
let int32 = ctx.i32_type();
|
||||||
|
let int8 = ctx.i8_type();
|
||||||
|
let int322 = ctx2.i32_type();
|
||||||
|
let int82 = ctx2.i8_type();
|
||||||
|
|
||||||
|
let opaque = ctx.opaque_struct_type("TestType");
|
||||||
|
opaque.set_body(&[int32.into(), int8.into()], false);
|
||||||
|
let opaque = opaque.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
|
let opaque2 = module2.get_struct_type("TestType").unwrap();
|
||||||
|
// let opaque2 = ctx2.opaque_struct_type("TestType");
|
||||||
|
// let opaque2 = ctx2.opaque_struct_type("TestType");
|
||||||
|
opaque2.set_body(&[int322.into(), int82.into()], false);
|
||||||
|
let opaque2 = opaque2.ptr_type(AddressSpace::Generic);
|
||||||
|
|
||||||
|
|
||||||
|
let func2 = module2.add_function("f", ctx2.void_type().fn_type(&[opaque2.into()], false), None);
|
||||||
|
let func2_bb = ctx2.append_basic_block(func2, "init");
|
||||||
|
builder2.position_at_end(func2_bb);
|
||||||
|
builder2.build_return(None);
|
||||||
|
|
||||||
|
let func = module.add_function("run", ctx.void_type().fn_type(&[], false), None);
|
||||||
|
// let fun2_mod1 = module.add_function("f", ctx.void_type().fn_type(&[opaque2.into()], false), None);
|
||||||
|
let func1_bb = ctx.append_basic_block(func, "init");
|
||||||
|
builder.position_at_end(func1_bb);
|
||||||
|
let opaque1_ptr = builder.build_alloca(opaque.get_element_type().into_struct_type(), "alloc1");
|
||||||
|
builder.build_store(
|
||||||
|
unsafe { builder.build_gep(opaque1_ptr, &[int32.const_zero(), int32.const_zero()], "gep") },
|
||||||
|
int32.const_int(123, false)
|
||||||
|
);
|
||||||
|
builder.build_store(
|
||||||
|
unsafe { builder.build_gep(opaque1_ptr, &[int32.const_zero(), int32.const_int(1, false)], "gep") },
|
||||||
|
int8.const_int(12, false),
|
||||||
|
);
|
||||||
|
builder.build_call(func2, &[opaque1_ptr.into()], "call");
|
||||||
|
builder.build_return(None);
|
||||||
|
|
||||||
|
|
||||||
|
println!("before: \n========= module1: \n{}\n=========module2: \n{}=======\n\n", module.print_to_string().to_string(), module2.print_to_string().to_string());
|
||||||
|
module.verify().unwrap();
|
||||||
|
module2.verify().unwrap();
|
||||||
|
module.link_in_module(module2).unwrap();
|
||||||
|
println!("after");
|
||||||
|
|
||||||
|
// println!("\n\n====finish===\n{}\n=====finish=====\n\n\n", module.print_to_string().to_string());
|
||||||
|
|
||||||
|
|
||||||
|
println!("before2");
|
||||||
|
match module.verify() {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(s) => {
|
||||||
|
println!("after2");
|
||||||
|
println!("\n\n=======\n{}\n==========\n{}\n\n", module.print_to_string().to_string(), s.to_string());
|
||||||
|
println!("after3");
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
println!("\n=====done===========");
|
||||||
|
module
|
||||||
}
|
}
|
Loading…
Reference in New Issue