diff --git a/nac3artiq/src/codegen.rs b/nac3artiq/src/codegen.rs index 9baa0afe..daf539fd 100644 --- a/nac3artiq/src/codegen.rs +++ b/nac3artiq/src/codegen.rs @@ -29,6 +29,7 @@ use nac3core::{ inkwell::{ context::Context, module::Linkage, + targets::TargetMachine, types::{BasicType, IntType}, values::{BasicValueEnum, IntValue, PointerValue, StructValue}, AddressSpace, IntPredicate, OptimizationLevel, @@ -87,13 +88,13 @@ pub struct ArtiqCodeGenerator<'a> { impl<'a> ArtiqCodeGenerator<'a> { pub fn new( name: String, - size_t: u32, + size_t: IntType<'_>, timeline: &'a (dyn TimeFns + Sync), ) -> ArtiqCodeGenerator<'a> { - assert!(size_t == 32 || size_t == 64); + assert!(matches!(size_t.get_bit_width(), 32 | 64)); ArtiqCodeGenerator { name, - size_t, + size_t: size_t.get_bit_width(), name_counter: 0, start: None, end: None, @@ -102,6 +103,17 @@ impl<'a> ArtiqCodeGenerator<'a> { } } + #[must_use] + pub fn with_target_machine( + name: String, + ctx: &Context, + target_machine: &TargetMachine, + timeline: &'a (dyn TimeFns + Sync), + ) -> ArtiqCodeGenerator<'a> { + let llvm_usize = ctx.ptr_sized_int_type(&target_machine.get_target_data(), None); + Self::new(name, llvm_usize, timeline) + } + /// If the generator is currently in a direct-`parallel` block context, emits IR that resets the /// position of the timeline to the initial timeline position before entering the `parallel` /// block. diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 1601d4a4..9a69c1a3 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -703,14 +703,18 @@ impl Nac3 { let buffer = buffer.as_slice().into(); membuffer.lock().push(buffer); }))); - let size_t = context - .ptr_sized_int_type(&self.get_llvm_target_machine().get_target_data(), None) - .get_bit_width(); let num_threads = if is_multithreaded() { 4 } else { 1 }; let thread_names: Vec = (0..num_threads).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))) + .map(|s| { + Box::new(ArtiqCodeGenerator::with_target_machine( + s.to_string(), + &context, + &self.get_llvm_target_machine(), + self.time_fns, + )) + }) .collect(); let membuffer = membuffers.clone(); @@ -719,8 +723,13 @@ impl Nac3 { let (registry, handles) = WorkerRegistry::create_workers(threads, top_level.clone(), &self.llvm_options, &f); - let mut generator = ArtiqCodeGenerator::new("main".to_string(), size_t, self.time_fns); let context = Context::create(); + let mut generator = ArtiqCodeGenerator::with_target_machine( + "main".to_string(), + &context, + &self.get_llvm_target_machine(), + self.time_fns, + ); let module = context.create_module("main"); let target_machine = self.llvm_options.create_target_machine().unwrap(); module.set_data_layout(&target_machine.get_target_data().get_data_layout()); diff --git a/nac3core/src/codegen/generator.rs b/nac3core/src/codegen/generator.rs index be007c2a..a416f10a 100644 --- a/nac3core/src/codegen/generator.rs +++ b/nac3core/src/codegen/generator.rs @@ -1,5 +1,6 @@ use inkwell::{ context::Context, + targets::TargetMachine, types::{BasicTypeEnum, IntType}, values::{BasicValueEnum, IntValue, PointerValue}, }; @@ -270,19 +271,27 @@ pub struct DefaultCodeGenerator { impl DefaultCodeGenerator { #[must_use] - pub fn new(name: String, size_t: u32) -> DefaultCodeGenerator { - assert!(matches!(size_t, 32 | 64)); - DefaultCodeGenerator { name, size_t } + pub fn new(name: String, size_t: IntType<'_>) -> DefaultCodeGenerator { + assert!(matches!(size_t.get_bit_width(), 32 | 64)); + DefaultCodeGenerator { name, size_t: size_t.get_bit_width() } + } + + #[must_use] + pub fn with_target_machine( + name: String, + ctx: &Context, + target_machine: &TargetMachine, + ) -> DefaultCodeGenerator { + let llvm_usize = ctx.ptr_sized_int_type(&target_machine.get_target_data(), None); + Self::new(name, llvm_usize) } } impl CodeGenerator for DefaultCodeGenerator { - /// Returns the name for this [`CodeGenerator`]. fn get_name(&self) -> &str { &self.name } - /// Returns an LLVM integer type representing `size_t`. fn get_size_type<'ctx>(&self, ctx: &'ctx Context) -> IntType<'ctx> { // it should be unsigned, but we don't really need unsigned and this could save us from // having to do a bit cast... diff --git a/nac3core/src/codegen/test.rs b/nac3core/src/codegen/test.rs index 2701e138..48bef5f2 100644 --- a/nac3core/src/codegen/test.rs +++ b/nac3core/src/codegen/test.rs @@ -97,6 +97,7 @@ fn test_primitives() { "}; let statements = parse_program(source, FileName::default()).unwrap(); + let context = inkwell::context::Context::create(); let composer = TopLevelComposer::new(Vec::new(), Vec::new(), ComposerConfig::default(), 32).0; let mut unifier = composer.unifier.clone(); let primitives = composer.primitives_ty; @@ -107,7 +108,7 @@ fn test_primitives() { Arc::new(Resolver { id_to_type: HashMap::new(), id_to_def: RwLock::new(HashMap::new()) }) as Arc; - let threads = vec![DefaultCodeGenerator::new("test".into(), 32).into()]; + let threads = vec![DefaultCodeGenerator::new("test".into(), context.i32_type()).into()]; let signature = FunSignature { args: vec![ FuncArg { @@ -260,6 +261,7 @@ fn test_simple_call() { "}; let statements_2 = parse_program(source_2, FileName::default()).unwrap(); + let context = inkwell::context::Context::create(); let composer = TopLevelComposer::new(Vec::new(), Vec::new(), ComposerConfig::default(), 32).0; let mut unifier = composer.unifier.clone(); let primitives = composer.primitives_ty; @@ -307,7 +309,7 @@ fn test_simple_call() { unreachable!() } - let threads = vec![DefaultCodeGenerator::new("test".into(), 32).into()]; + let threads = vec![DefaultCodeGenerator::new("test".into(), context.i32_type()).into()]; let mut function_data = FunctionData { resolver: resolver.clone(), bound_variables: Vec::new(), @@ -439,7 +441,7 @@ fn test_simple_call() { #[test] fn test_classes_list_type_new() { let ctx = inkwell::context::Context::create(); - let generator = DefaultCodeGenerator::new(String::new(), 64); + let generator = DefaultCodeGenerator::new(String::new(), ctx.i64_type()); let llvm_i32 = ctx.i32_type(); let llvm_usize = generator.get_size_type(&ctx); @@ -459,7 +461,7 @@ fn test_classes_range_type_new() { #[test] fn test_classes_ndarray_type_new() { let ctx = inkwell::context::Context::create(); - let generator = DefaultCodeGenerator::new(String::new(), 64); + let generator = DefaultCodeGenerator::new(String::new(), ctx.i64_type()); let llvm_i32 = ctx.i32_type(); let llvm_usize = generator.get_size_type(&ctx); diff --git a/nac3standalone/src/main.rs b/nac3standalone/src/main.rs index 2fce5d16..d54e08e7 100644 --- a/nac3standalone/src/main.rs +++ b/nac3standalone/src/main.rs @@ -456,7 +456,13 @@ fn main() { membuffer.lock().push(buffer); }))); let threads = (0..threads) - .map(|i| Box::new(DefaultCodeGenerator::new(format!("module{i}"), size_t))) + .map(|i| { + Box::new(DefaultCodeGenerator::with_target_machine( + format!("module{i}"), + &context, + &target_machine, + )) + }) .collect(); let (registry, handles) = WorkerRegistry::create_workers(threads, top_level, &llvm_options, &f); registry.add_task(task);