forked from M-Labs/nac3
CodeGenerator: Add with_target_machine factory function
Allows creating CodeGenerator with the LLVM target machine to infer the expected type for size_t.
This commit is contained in:
parent
8baf111734
commit
d1dcfa19ff
@ -29,6 +29,7 @@ use nac3core::{
|
|||||||
inkwell::{
|
inkwell::{
|
||||||
context::Context,
|
context::Context,
|
||||||
module::Linkage,
|
module::Linkage,
|
||||||
|
targets::TargetMachine,
|
||||||
types::{BasicType, IntType},
|
types::{BasicType, IntType},
|
||||||
values::{BasicValueEnum, IntValue, PointerValue, StructValue},
|
values::{BasicValueEnum, IntValue, PointerValue, StructValue},
|
||||||
AddressSpace, IntPredicate, OptimizationLevel,
|
AddressSpace, IntPredicate, OptimizationLevel,
|
||||||
@ -87,13 +88,13 @@ pub struct ArtiqCodeGenerator<'a> {
|
|||||||
impl<'a> ArtiqCodeGenerator<'a> {
|
impl<'a> ArtiqCodeGenerator<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
name: String,
|
name: String,
|
||||||
size_t: u32,
|
size_t: IntType<'_>,
|
||||||
timeline: &'a (dyn TimeFns + Sync),
|
timeline: &'a (dyn TimeFns + Sync),
|
||||||
) -> ArtiqCodeGenerator<'a> {
|
) -> ArtiqCodeGenerator<'a> {
|
||||||
assert!(size_t == 32 || size_t == 64);
|
assert!(matches!(size_t.get_bit_width(), 32 | 64));
|
||||||
ArtiqCodeGenerator {
|
ArtiqCodeGenerator {
|
||||||
name,
|
name,
|
||||||
size_t,
|
size_t: size_t.get_bit_width(),
|
||||||
name_counter: 0,
|
name_counter: 0,
|
||||||
start: None,
|
start: None,
|
||||||
end: 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
|
/// 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`
|
/// position of the timeline to the initial timeline position before entering the `parallel`
|
||||||
/// block.
|
/// block.
|
||||||
|
@ -703,14 +703,18 @@ impl Nac3 {
|
|||||||
let buffer = buffer.as_slice().into();
|
let buffer = buffer.as_slice().into();
|
||||||
membuffer.lock().push(buffer);
|
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 num_threads = if is_multithreaded() { 4 } else { 1 };
|
||||||
let thread_names: Vec<String> = (0..num_threads).map(|_| "main".to_string()).collect();
|
let thread_names: Vec<String> = (0..num_threads).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::with_target_machine(
|
||||||
|
s.to_string(),
|
||||||
|
&context,
|
||||||
|
&self.get_llvm_target_machine(),
|
||||||
|
self.time_fns,
|
||||||
|
))
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let membuffer = membuffers.clone();
|
let membuffer = membuffers.clone();
|
||||||
@ -719,8 +723,13 @@ impl Nac3 {
|
|||||||
let (registry, handles) =
|
let (registry, handles) =
|
||||||
WorkerRegistry::create_workers(threads, top_level.clone(), &self.llvm_options, &f);
|
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 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 module = context.create_module("main");
|
||||||
let target_machine = self.llvm_options.create_target_machine().unwrap();
|
let target_machine = self.llvm_options.create_target_machine().unwrap();
|
||||||
module.set_data_layout(&target_machine.get_target_data().get_data_layout());
|
module.set_data_layout(&target_machine.get_target_data().get_data_layout());
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use inkwell::{
|
use inkwell::{
|
||||||
context::Context,
|
context::Context,
|
||||||
|
targets::TargetMachine,
|
||||||
types::{BasicTypeEnum, IntType},
|
types::{BasicTypeEnum, IntType},
|
||||||
values::{BasicValueEnum, IntValue, PointerValue},
|
values::{BasicValueEnum, IntValue, PointerValue},
|
||||||
};
|
};
|
||||||
@ -270,19 +271,27 @@ pub struct DefaultCodeGenerator {
|
|||||||
|
|
||||||
impl DefaultCodeGenerator {
|
impl DefaultCodeGenerator {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(name: String, size_t: u32) -> DefaultCodeGenerator {
|
pub fn new(name: String, size_t: IntType<'_>) -> DefaultCodeGenerator {
|
||||||
assert!(matches!(size_t, 32 | 64));
|
assert!(matches!(size_t.get_bit_width(), 32 | 64));
|
||||||
DefaultCodeGenerator { name, size_t }
|
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 {
|
impl CodeGenerator for DefaultCodeGenerator {
|
||||||
/// Returns the name for this [`CodeGenerator`].
|
|
||||||
fn get_name(&self) -> &str {
|
fn get_name(&self) -> &str {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an LLVM integer type representing `size_t`.
|
|
||||||
fn get_size_type<'ctx>(&self, ctx: &'ctx Context) -> IntType<'ctx> {
|
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
|
// it should be unsigned, but we don't really need unsigned and this could save us from
|
||||||
// having to do a bit cast...
|
// having to do a bit cast...
|
||||||
|
@ -97,6 +97,7 @@ fn test_primitives() {
|
|||||||
"};
|
"};
|
||||||
let statements = parse_program(source, FileName::default()).unwrap();
|
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 composer = TopLevelComposer::new(Vec::new(), Vec::new(), ComposerConfig::default(), 32).0;
|
||||||
let mut unifier = composer.unifier.clone();
|
let mut unifier = composer.unifier.clone();
|
||||||
let primitives = composer.primitives_ty;
|
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()) })
|
Arc::new(Resolver { id_to_type: HashMap::new(), id_to_def: RwLock::new(HashMap::new()) })
|
||||||
as Arc<dyn SymbolResolver + Send + Sync>;
|
as Arc<dyn SymbolResolver + Send + Sync>;
|
||||||
|
|
||||||
let threads = vec![DefaultCodeGenerator::new("test".into(), 32).into()];
|
let threads = vec![DefaultCodeGenerator::new("test".into(), context.i32_type()).into()];
|
||||||
let signature = FunSignature {
|
let signature = FunSignature {
|
||||||
args: vec![
|
args: vec![
|
||||||
FuncArg {
|
FuncArg {
|
||||||
@ -260,6 +261,7 @@ fn test_simple_call() {
|
|||||||
"};
|
"};
|
||||||
let statements_2 = parse_program(source_2, FileName::default()).unwrap();
|
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 composer = TopLevelComposer::new(Vec::new(), Vec::new(), ComposerConfig::default(), 32).0;
|
||||||
let mut unifier = composer.unifier.clone();
|
let mut unifier = composer.unifier.clone();
|
||||||
let primitives = composer.primitives_ty;
|
let primitives = composer.primitives_ty;
|
||||||
@ -307,7 +309,7 @@ fn test_simple_call() {
|
|||||||
unreachable!()
|
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 {
|
let mut function_data = FunctionData {
|
||||||
resolver: resolver.clone(),
|
resolver: resolver.clone(),
|
||||||
bound_variables: Vec::new(),
|
bound_variables: Vec::new(),
|
||||||
@ -439,7 +441,7 @@ fn test_simple_call() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_classes_list_type_new() {
|
fn test_classes_list_type_new() {
|
||||||
let ctx = inkwell::context::Context::create();
|
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_i32 = ctx.i32_type();
|
||||||
let llvm_usize = generator.get_size_type(&ctx);
|
let llvm_usize = generator.get_size_type(&ctx);
|
||||||
@ -459,7 +461,7 @@ fn test_classes_range_type_new() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_classes_ndarray_type_new() {
|
fn test_classes_ndarray_type_new() {
|
||||||
let ctx = inkwell::context::Context::create();
|
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_i32 = ctx.i32_type();
|
||||||
let llvm_usize = generator.get_size_type(&ctx);
|
let llvm_usize = generator.get_size_type(&ctx);
|
||||||
|
@ -456,7 +456,13 @@ fn main() {
|
|||||||
membuffer.lock().push(buffer);
|
membuffer.lock().push(buffer);
|
||||||
})));
|
})));
|
||||||
let threads = (0..threads)
|
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();
|
.collect();
|
||||||
let (registry, handles) = WorkerRegistry::create_workers(threads, top_level, &llvm_options, &f);
|
let (registry, handles) = WorkerRegistry::create_workers(threads, top_level, &llvm_options, &f);
|
||||||
registry.add_task(task);
|
registry.add_task(task);
|
||||||
|
Loading…
Reference in New Issue
Block a user