From 2207c3df83d11dae3693193bf3ccd29b626d447c Mon Sep 17 00:00:00 2001 From: sofia Date: Tue, 29 Jul 2025 00:06:47 +0300 Subject: [PATCH] Add initial support for array globals --- reid-llvm-lib/src/builder.rs | 2 +- reid-llvm-lib/src/compile.rs | 19 +++++++++++++++++-- reid-llvm-lib/src/lib.rs | 2 ++ reid/src/codegen/mod.rs | 29 ++++++++++++++++++++++------- reid/src/mir/mod.rs | 1 + 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index 90a2bd8..ed6d2f3 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -27,7 +27,7 @@ pub struct BlockValue(pub(crate) FunctionValue, pub(crate) usize); #[derive(Clone, Hash, Copy, PartialEq, Eq)] pub struct InstructionValue(pub(crate) BlockValue, pub(crate) usize); -#[derive(Clone, Hash, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Hash, Copy, PartialEq, Eq)] pub struct ConstantValue(pub(crate) usize); #[derive(Clone, Hash, Copy, PartialEq, Eq)] diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index 60fc909..f3ccbf2 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -329,7 +329,9 @@ impl ModuleHolder { constant.value, LLVMValue { ty: constant.kind.get_type(), - value_ref: constant.kind.as_llvm(context.context_ref, context.builder_ref, &types), + value_ref: constant + .kind + .as_llvm(context.context_ref, context.builder_ref, &constants, &types), }, ); } @@ -759,7 +761,7 @@ impl InstructionHolder { use super::Instr::*; match &self.data.kind { Param(nth) => LLVMGetParam(function.value_ref, *nth as u32), - Constant(val) => val.as_llvm(module.context_ref, module.builder_ref, &module.types), + Constant(val) => val.as_llvm(module.context_ref, module.builder_ref, &module.constants, &module.types), Add(lhs, rhs) => { let lhs_val = module.values.get(&lhs).unwrap().value_ref; let rhs_val = module.values.get(&rhs).unwrap().value_ref; @@ -1176,6 +1178,7 @@ impl ConstValueKind { &self, context: LLVMContextRef, builder: LLVMBuilderRef, + constants: &HashMap, types: &HashMap, ) -> LLVMValueRef { unsafe { @@ -1202,6 +1205,18 @@ impl ConstValueKind { ConstValueKind::F80(val) => LLVMConstReal(t, *val as f64), ConstValueKind::F128(val) => LLVMConstReal(t, *val as f64), ConstValueKind::F128PPC(val) => LLVMConstReal(t, *val as f64), + ConstValueKind::Array(constant_values, elem_ty) => { + let mut values = constant_values + .iter() + .map(|v| constants.get(v).unwrap().value_ref) + .collect::>(); + + LLVMConstArray2( + elem_ty.as_llvm(context, &types), + values.as_mut_ptr(), + values.len() as u64, + ) + } } } } diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index a926b2a..665feec 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -518,6 +518,7 @@ pub enum ConstValueKind { F80(f64), F128(f64), F128PPC(f64), + Array(Vec, Type), } #[derive(Clone, Hash)] @@ -565,6 +566,7 @@ impl ConstValueKind { ConstValueKind::F80(_) => F80, ConstValueKind::F128(_) => F128, ConstValueKind::F128PPC(_) => F128PPC, + ConstValueKind::Array(vals, ty) => Type::Array(Box::new(ty.clone()), vals.len() as u64), } } } diff --git a/reid/src/codegen/mod.rs b/reid/src/codegen/mod.rs index 83ff00c..43e8eba 100644 --- a/reid/src/codegen/mod.rs +++ b/reid/src/codegen/mod.rs @@ -98,9 +98,24 @@ impl Default for State { } impl mir::GlobalKind { - fn codegen<'ctx>(&'ctx self, context: &'ctx Context, module: &Module) -> Result { + fn codegen<'ctx>( + &'ctx self, + context: &'ctx Context, + types: &HashMap, + module: &Module, + ) -> Result<(ConstantValue, TypeKind), ErrorKind> { Ok(match self { - mir::GlobalKind::Literal(literal) => module.add_constant(literal.as_const_kind()), + mir::GlobalKind::Literal(literal) => (module.add_constant(literal.as_const_kind()), literal.as_type()), + mir::GlobalKind::Array(globals) => { + let values = try_all(globals.into_iter().map(|g| g.codegen(context, types, module)).collect()) + .map_err(|e| e.first().unwrap().clone())?; + let elem_ty = values.iter().map(|(_, t)| t.clone()).next().unwrap_or(TypeKind::Void); + let values = values.iter().map(|(v, _)| *v).collect::>(); + ( + module.add_constant(ConstValueKind::Array(values, elem_ty.get_type(&types))), + TypeKind::Array(Box::new(elem_ty), globals.len() as u64), + ) + } }) } } @@ -114,11 +129,6 @@ impl mir::Module { let mut module = context.module(&self.name, self.is_main); let tokens = &self.tokens; - for global in &self.globals { - let const_value = global.kind.codegen(context, &module)?; - module.add_global(&global.name, const_value); - } - let (debug, compile_unit) = if let Some(path) = &self.path { module.create_debug_info(DebugFileData { name: path.file_name().unwrap().to_str().unwrap().to_owned(), @@ -191,6 +201,11 @@ impl mir::Module { insert_debug!(&TypeKind::CustomType(type_key.clone())); } + for global in &self.globals { + let (const_value, _) = global.kind.codegen(context, &type_values, &module)?; + module.add_global(&global.name, const_value); + } + let mut functions = HashMap::new(); for function in &self.functions { diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index b61e403..4a1520f 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -436,6 +436,7 @@ pub struct GlobalValue { #[derive(Debug)] pub enum GlobalKind { Literal(Literal), + Array(Vec), } pub type ModuleMap = HashMap;