Add initial support for array globals
This commit is contained in:
parent
735c3231b1
commit
2207c3df83
@ -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)]
|
||||
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -436,6 +436,7 @@ pub struct GlobalValue {
|
||||
#[derive(Debug)]
|
||||
pub enum GlobalKind {
|
||||
Literal(Literal),
|
||||
Array(Vec<GlobalKind>),
|
||||
}
|
||||
|
||||
pub type ModuleMap = HashMap<SourceModuleId, Module>;
|
||||
|
Loading…
Reference in New Issue
Block a user