forked from M-Labs/nac3
messy
This commit is contained in:
parent
b04631e935
commit
258aa4c9d6
|
@ -158,7 +158,9 @@
|
|||
cargo-insta
|
||||
clippy
|
||||
rustfmt
|
||||
lldb_14
|
||||
];
|
||||
RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}";
|
||||
};
|
||||
devShells.x86_64-linux.msys2 = pkgs.mkShell {
|
||||
name = "nac3-dev-shell-msys2";
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::process::Command;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
@ -763,34 +764,54 @@ impl Nac3 {
|
|||
let membuffer = membuffers.clone();
|
||||
|
||||
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 = buffer.as_slice().into();
|
||||
membuffer.lock().push(buffer);
|
||||
})));
|
||||
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
|
||||
.iter()
|
||||
.map(|s| Box::new(ArtiqCodeGenerator::new(s.to_string(), size_t, self.time_fns)))
|
||||
.collect();
|
||||
|
||||
let membuffer = membuffers.clone();
|
||||
println!("------0:");
|
||||
// let membuffer = membuffers.clone();
|
||||
py.allow_threads(|| {
|
||||
let (registry, handles) = WorkerRegistry::create_workers(threads, top_level.clone(), f);
|
||||
registry.add_task(task);
|
||||
registry.wait_tasks_complete(handles);
|
||||
println!("------1:");
|
||||
|
||||
let mut generator = ArtiqCodeGenerator::new("attributes_writeback".to_string(), size_t, self.time_fns);
|
||||
let context = inkwell::context::Context::create();
|
||||
let module = context.create_module("attributes_writeback");
|
||||
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 mut generator = ArtiqCodeGenerator::new("attributes_writeback".to_string(), size_t, self.time_fns);
|
||||
// let context = inkwell::context::Context::create();
|
||||
// let module = context.create_module("attributes_writeback");
|
||||
// module.add_basic_value_flag(
|
||||
// "Debug Info Version",
|
||||
// inkwell::module::FlagBehavior::Warning,
|
||||
// context.i32_type().const_int(3, false),
|
||||
// );
|
||||
// module.add_basic_value_flag(
|
||||
// "Dwarf Version",
|
||||
// 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();
|
||||
|
@ -798,21 +819,25 @@ impl Nac3 {
|
|||
let main = context
|
||||
.create_module_from_ir(MemoryBuffer::create_from_memory_range(&buffers[0], "main"))
|
||||
.unwrap();
|
||||
// println!(":1: {}", buffers.len());
|
||||
for buffer in buffers.iter().skip(1) {
|
||||
let other = context
|
||||
.create_module_from_ir(MemoryBuffer::create_from_memory_range(buffer, "main"))
|
||||
.unwrap();
|
||||
|
||||
// println!(":2:");
|
||||
main.link_in_module(other)
|
||||
.map_err(|err| CompileError::new_err(err.to_string()))?;
|
||||
}
|
||||
let builder = context.create_builder();
|
||||
let modinit_return = main.get_function("__modinit__").unwrap().get_last_basic_block().unwrap().get_terminator().unwrap();
|
||||
builder.position_before(&modinit_return);
|
||||
builder.build_call(main.get_function("attributes_writeback").unwrap(), &[], "attributes_writeback");
|
||||
// let builder = context.create_builder();
|
||||
// let modinit_return = main.get_function("__modinit__").unwrap().get_last_basic_block().unwrap().get_terminator().unwrap();
|
||||
// builder.position_before(&modinit_return);
|
||||
// builder.build_call(main.get_function("attributes_writeback").unwrap(), &[], "attributes_writeback");
|
||||
|
||||
main.link_in_module(load_irrt(&context))
|
||||
.map_err(|err| CompileError::new_err(err.to_string()))?;
|
||||
// main.link_in_module(load_irrt(&context))
|
||||
// .map_err(|err| CompileError::new_err(err.to_string()))?;
|
||||
|
||||
// println!(":3:");
|
||||
|
||||
let mut function_iter = main.get_first_function();
|
||||
while let Some(func) = function_iter {
|
||||
|
@ -822,12 +847,14 @@ impl Nac3 {
|
|||
function_iter = func.get_next_function();
|
||||
}
|
||||
|
||||
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);
|
||||
passes.run_on(&main);
|
||||
// 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);
|
||||
// passes.run_on(&main);
|
||||
|
||||
// println!("\n\n==========={}\n=============", main.print_to_string().to_string());
|
||||
|
||||
let (triple, features) = match isa {
|
||||
Isa::Host => (
|
||||
|
|
|
@ -165,6 +165,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
|||
) -> BasicTypeEnum<'ctx> {
|
||||
get_llvm_type(
|
||||
self.ctx,
|
||||
&self.module,
|
||||
generator,
|
||||
&mut self.unifier,
|
||||
self.top_level,
|
||||
|
@ -460,7 +461,8 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
|||
let i1_true = i1.const_all_ones();
|
||||
let expect_fun = self.module.get_function("llvm.expect.i1").unwrap_or_else(|| {
|
||||
self.module.add_function(
|
||||
"llvm.expect",
|
||||
// FIXME:
|
||||
"llvm.expect.i1",
|
||||
i1.fn_type(&[i1.into(), i1.into()], false),
|
||||
None,
|
||||
)
|
||||
|
@ -693,6 +695,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>(
|
|||
if let Some(obj) = &obj {
|
||||
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) {
|
||||
None
|
||||
} 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),
|
||||
_ => 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 offset = if has_sret {
|
||||
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>) {
|
||||
// println!("thread start! 1");
|
||||
let context = Context::create();
|
||||
// println!("thread start! 2");
|
||||
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(
|
||||
"Debug Info Version",
|
||||
|
@ -218,23 +222,46 @@ impl WorkerRegistry {
|
|||
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();
|
||||
// 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() {
|
||||
let tmp_module = context.create_module("tmp");
|
||||
match gen_func(&context, generator, self, builder, tmp_module, task) {
|
||||
match gen_func(&context, generator, self, builder, module, task) {
|
||||
Ok(result) => {
|
||||
builder = result.0;
|
||||
passes.run_on(&result.2);
|
||||
module.link_in_module(result.1).unwrap();
|
||||
// passes.run_on(&result.2);
|
||||
// module.link_in_module(result.1).unwrap();
|
||||
module = result.1;
|
||||
}
|
||||
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);
|
||||
panic!("Codegen error: {}", errors.into_iter().sorted().join("\n----------\n"));
|
||||
}
|
||||
}
|
||||
*self.task_count.lock() -= 1;
|
||||
|
@ -246,10 +273,20 @@ impl WorkerRegistry {
|
|||
|
||||
let result = module.verify();
|
||||
if let Err(err) = result {
|
||||
println!("{}", module.print_to_string().to_str().unwrap());
|
||||
println!("{}", err);
|
||||
println!("\n\n!!!!!!!!!!!!!!!!!!error!!!!!!!!!!!!!!!!!!!!!");
|
||||
println!("{}", module.print_to_string().to_string());
|
||||
println!("{}", err.to_string());
|
||||
println!("!!!!!!!!!!!!!!!!!!error!!!!!!!!!!!!!!!!!!!!!\n\n");
|
||||
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);
|
||||
let mut lock = self.task_count.lock();
|
||||
*lock += 1;
|
||||
|
@ -271,6 +308,7 @@ pub struct CodeGenTask {
|
|||
|
||||
fn get_llvm_type<'ctx>(
|
||||
ctx: &'ctx Context,
|
||||
module: &Module<'ctx>,
|
||||
generator: &mut dyn CodeGenerator,
|
||||
unifier: &mut Unifier,
|
||||
top_level: &TopLevelContext,
|
||||
|
@ -282,6 +320,7 @@ fn get_llvm_type<'ctx>(
|
|||
// we assume the type cache should already contain primitive types,
|
||||
// and they should be passed by value instead of passing as pointer.
|
||||
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 result = match &*ty_enum {
|
||||
TObj { obj_id, fields, .. } => {
|
||||
|
@ -295,6 +334,7 @@ fn get_llvm_type<'ctx>(
|
|||
) if *obj_id == *opt_id => {
|
||||
return get_llvm_type(
|
||||
ctx,
|
||||
module,
|
||||
generator,
|
||||
unifier,
|
||||
top_level,
|
||||
|
@ -314,6 +354,28 @@ fn get_llvm_type<'ctx>(
|
|||
let ty = if let TopLevelDef::Class { name, fields: fields_list, .. } =
|
||||
&*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());
|
||||
type_cache.insert(unifier.get_representative(ty), struct_type.ptr_type(AddressSpace::Generic).into());
|
||||
let fields = fields_list
|
||||
|
@ -321,6 +383,7 @@ fn get_llvm_type<'ctx>(
|
|||
.map(|f| {
|
||||
get_llvm_type(
|
||||
ctx,
|
||||
module,
|
||||
generator,
|
||||
unifier,
|
||||
top_level,
|
||||
|
@ -331,7 +394,11 @@ fn get_llvm_type<'ctx>(
|
|||
})
|
||||
.collect_vec();
|
||||
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 {
|
||||
unreachable!()
|
||||
};
|
||||
|
@ -341,14 +408,14 @@ fn get_llvm_type<'ctx>(
|
|||
// a struct with fields in the order present in the tuple
|
||||
let fields = ty
|
||||
.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();
|
||||
ctx.struct_type(&fields, false).into()
|
||||
}
|
||||
TList { ty } => {
|
||||
// a struct with an integer and a pointer to an array
|
||||
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 = [
|
||||
element_type.ptr_type(AddressSpace::Generic).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 {
|
||||
unreachable!()
|
||||
};
|
||||
// println!("\n=======getting types for func `{}`=======", task.symbol_name);
|
||||
let ret_type = if unifier.unioned(ret, primitives.none) {
|
||||
None
|
||||
} 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));
|
||||
|
@ -487,6 +555,7 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
|
|||
.map(|arg| {
|
||||
get_llvm_type(
|
||||
context,
|
||||
&module,
|
||||
generator,
|
||||
&mut unifier,
|
||||
top_level_ctx.as_ref(),
|
||||
|
@ -497,7 +566,6 @@ pub fn gen_func_impl<'ctx, G: CodeGenerator, F: FnOnce(&mut G, &mut CodeGenConte
|
|||
.into()
|
||||
})
|
||||
.collect_vec();
|
||||
|
||||
if has_sret {
|
||||
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),
|
||||
_ => context.void_type().fn_type(¶ms, false)
|
||||
};
|
||||
|
||||
// println!("=======got types for func `{}`: {:?}=======\n", task.symbol_name, fn_type);
|
||||
let symbol = &task.symbol_name;
|
||||
let fn_val =
|
||||
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(
|
||||
get_llvm_type(
|
||||
context,
|
||||
&module,
|
||||
generator,
|
||||
&mut unifier,
|
||||
top_level_ctx.as_ref(),
|
||||
|
@ -678,11 +747,15 @@ pub fn gen_func<'ctx, G: CodeGenerator>(
|
|||
module: Module<'ctx>,
|
||||
task: CodeGenTask,
|
||||
) -> Result<(Builder<'ctx>, Module<'ctx>, FunctionValue<'ctx>), (Builder<'ctx>, String)> {
|
||||
let n = task.symbol_name.clone();
|
||||
println!("{} start:", n);
|
||||
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() {
|
||||
generator.gen_stmt(ctx, stmt)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
});
|
||||
println!("{} end:", n);
|
||||
res
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ if [ -z "$1" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [ -e ../../target/release/nac3standalone ]; then
|
||||
nac3standalone=../../target/release/nac3standalone
|
||||
if [ -e ../../target/debug/nac3standalone ]; then
|
||||
nac3standalone=../../target/debug/nac3standalone
|
||||
else
|
||||
# used by Nix builds
|
||||
nac3standalone=../../target/x86_64-unknown-linux-gnu/release/nac3standalone
|
||||
|
|
|
@ -2,7 +2,7 @@ use inkwell::{
|
|||
memory_buffer::MemoryBuffer,
|
||||
passes::{PassManager, PassManagerBuilder},
|
||||
targets::*,
|
||||
OptimizationLevel,
|
||||
OptimizationLevel, module::Module, context::Context, AddressSpace,
|
||||
};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use std::{borrow::Borrow, collections::HashMap, env, fs, path::Path, sync::Arc};
|
||||
|
@ -156,7 +156,7 @@ fn handle_assignment_pattern(
|
|||
|
||||
fn main() {
|
||||
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());
|
||||
|
||||
|
@ -313,4 +313,210 @@ fn main() {
|
|||
target_machine
|
||||
.write_to_file(&main, FileType::Object, Path::new("module.o"))
|
||||
.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