Add initial support for array globals

This commit is contained in:
Sofia 2025-07-29 00:06:47 +03:00
parent 735c3231b1
commit 2207c3df83
5 changed files with 43 additions and 10 deletions

View File

@ -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)]

View File

@ -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<ConstantValue, LLVMValue>,
types: &HashMap<TypeValue, LLVMTypeRef>,
) -> 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::<Vec<_>>();
LLVMConstArray2(
elem_ty.as_llvm(context, &types),
values.as_mut_ptr(),
values.len() as u64,
)
}
}
}
}

View File

@ -518,6 +518,7 @@ pub enum ConstValueKind {
F80(f64),
F128(f64),
F128PPC(f64),
Array(Vec<ConstantValue>, 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),
}
}
}

View File

@ -98,9 +98,24 @@ impl Default for State {
}
impl mir::GlobalKind {
fn codegen<'ctx>(&'ctx self, context: &'ctx Context, module: &Module) -> Result<ConstantValue, ErrorKind> {
fn codegen<'ctx>(
&'ctx self,
context: &'ctx Context,
types: &HashMap<CustomTypeKey, reid_lib::builder::TypeValue>,
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::<Vec<_>>();
(
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 {

View File

@ -436,6 +436,7 @@ pub struct GlobalValue {
#[derive(Debug)]
pub enum GlobalKind {
Literal(Literal),
Array(Vec<GlobalKind>),
}
pub type ModuleMap = HashMap<SourceModuleId, Module>;