Get static arrays actually working alone

This commit is contained in:
Sofia 2025-07-20 19:23:42 +03:00
parent de95db7cc1
commit a62f9db422
7 changed files with 116 additions and 81 deletions

View File

@ -392,6 +392,7 @@ impl Builder {
Instr::Alloca(_, _) => Ok(()),
Instr::Load(ptr, load_ty) => {
let ptr_ty = ptr.get_type(&self)?;
dbg!(&ptr_ty, &load_ty);
if let Type::Ptr(ptr_ty_inner) = ptr_ty {
if *ptr_ty_inner == load_ty {
Ok(())
@ -414,10 +415,10 @@ impl Builder {
Instr::GetElemPtr(ptr_val, _) => {
let ptr_ty = ptr_val.get_type(&self)?;
match ptr_ty {
Type::CustomType(custom) => match self.type_data(&custom).kind {
CustomTypeKind::NamedStruct(_) => Ok(()),
Type::Ptr(inner) => match *inner {
Type::Array(_, _) => Ok(()),
_ => Err(()),
},
Type::Ptr(_) => Ok(()),
_ => Err(()),
}
}
@ -440,6 +441,16 @@ impl Builder {
Err(()) // TODO error: not a pointer
}
}
Instr::ExtractValue(val, _) => {
let val_ty = val.get_type(&self)?;
match val_ty {
Type::CustomType(custom) => match self.type_data(&custom).kind {
CustomTypeKind::NamedStruct(_) => Ok(()),
},
Type::Array(_, _) => Ok(()),
_ => Err(()),
}
}
}
}
}

View File

@ -861,7 +861,7 @@ impl InstructionHolder {
.map(|idx_elem| module.values.get(idx_elem).unwrap().value_ref)
.collect();
LLVMBuildGEP2(
LLVMBuildInBoundsGEP2(
module.builder_ref,
elem_t.as_llvm(module.context_ref, &module.types),
module.values.get(arr).unwrap().value_ref,
@ -888,6 +888,12 @@ impl InstructionHolder {
into_cstring(format!("struct.{}.{}.gep", type_fmt, idx)).as_ptr(),
)
}
ExtractValue(agg_val, idx) => LLVMBuildExtractValue(
module.builder_ref,
module.values.get(agg_val).unwrap().value_ref,
*idx,
c"extract".as_ptr(),
),
}
};
if let Some(record) = &self.record {
@ -932,7 +938,6 @@ impl InstructionHolder {
}
if let Some(location) = &self.data.location {
unsafe {
// dbg!(&self.data.kind, LLVMGetValueKind(val));
match LLVMGetValueKind(val) {
LLVMValueKind::LLVMInstructionValueKind
| LLVMValueKind::LLVMMemoryDefValueKind
@ -958,26 +963,6 @@ impl InstructionHolder {
value_ref: val,
}
}
fn get_inner_value(&self) -> Option<InstructionValue> {
match &self.data.kind {
crate::Instr::Param(_) => None,
crate::Instr::Constant(_) => None,
crate::Instr::Add(_, _) => None,
crate::Instr::Sub(_, _) => None,
crate::Instr::Mult(_, _) => None,
crate::Instr::And(_, _) => None,
crate::Instr::Phi(_) => None,
crate::Instr::Alloca(_, _) => todo!(),
crate::Instr::Load(_, _) => None,
crate::Instr::Store(_, val) => Some(*val),
crate::Instr::ArrayAlloca(_, _) => None,
crate::Instr::GetElemPtr(_, _) => None,
crate::Instr::GetStructElemPtr(_, _) => None,
crate::Instr::ICmp(_, _, _) => None,
crate::Instr::FunctionCall(_, _) => None,
}
}
}
impl TerminatorKind {
@ -1077,6 +1062,7 @@ impl Type {
Void => LLVMVoidTypeInContext(context),
Ptr(ty) => LLVMPointerType(ty.as_llvm(context, typemap), 0),
CustomType(struct_ty) => *typemap.get(struct_ty).unwrap(),
Array(r#type, len) => LLVMArrayType2(r#type.as_llvm(context, typemap), *len),
}
}
}

View File

@ -148,6 +148,11 @@ impl Debug for Instr {
.join(", "),
),
Instr::GetStructElemPtr(instruction_value, index) => {
write!(f, "GEP(")?;
fmt_index(f, instruction_value, &index.to_string())?;
write!(f, ")")
}
Instr::ExtractValue(instruction_value, index) => {
fmt_index(f, instruction_value, &index.to_string())
}
}

View File

@ -318,6 +318,7 @@ pub enum Instr {
ArrayAlloca(Type, u32),
GetElemPtr(InstructionValue, Vec<InstructionValue>),
GetStructElemPtr(InstructionValue, u32),
ExtractValue(InstructionValue, u32),
/// Integer Comparison
ICmp(CmpPredicate, InstructionValue, InstructionValue),
@ -340,6 +341,7 @@ pub enum Type {
Bool,
Void,
CustomType(TypeValue),
Array(Box<Type>, u64),
Ptr(Box<Type>),
}
@ -404,7 +406,16 @@ impl InstructionValue {
Load(_, ty) => Ok(ty.clone()),
Store(_, value) => value.get_type(builder),
ArrayAlloca(ty, _) => Ok(Type::Ptr(Box::new(ty.clone()))),
GetElemPtr(ptr, _) => ptr.get_type(builder),
GetElemPtr(instr, _) => {
let instr_ty = instr.get_type(builder)?;
let Type::Ptr(inner_ty) = instr_ty else {
panic!("GetStructElemPtr on non-pointer! ({:?})", &instr_ty)
};
let Type::Array(elem_ty, _) = *inner_ty else {
panic!("GetStructElemPtr on non-struct! ({:?})", &inner_ty)
};
Ok(Type::Ptr(Box::new(*elem_ty.clone())))
}
GetStructElemPtr(instr, idx) => {
let instr_ty = instr.get_type(builder)?;
let Type::Ptr(inner_ty) = instr_ty else {
@ -420,6 +431,21 @@ impl InstructionValue {
};
Ok(Type::Ptr(Box::new(field_ty)))
}
ExtractValue(instr, idx) => {
let instr_ty = instr.get_type(builder)?;
Ok(match instr_ty {
Type::CustomType(struct_ty) => {
let data = builder.type_data(&struct_ty);
match data.kind {
CustomTypeKind::NamedStruct(named_struct) => {
named_struct.1.get(*idx as usize).unwrap().clone()
}
}
}
Type::Array(elem_ty, _) => *elem_ty.clone(),
_ => return Err(()),
})
}
}
}
}
@ -462,6 +488,7 @@ impl Type {
Type::Void => false,
Type::Ptr(_) => false,
Type::CustomType(_) => false,
Type::Array(_, _) => false,
}
}
@ -481,6 +508,7 @@ impl Type {
Type::Void => false,
Type::Ptr(_) => false,
Type::CustomType(_) => false,
Type::Array(_, _) => false,
}
}
}

View File

@ -1,4 +1,4 @@
use std::{collections::HashMap, fmt::format, mem};
use std::{array, collections::HashMap, fmt::format, mem};
use reid_lib::{
builder::{InstructionValue, TypeValue},
@ -568,18 +568,7 @@ impl mir::Expression {
.stack_values
.get(&varref.1)
.expect("Variable reference not found?!");
Some(StackValue(
v.0.map(|val| {
scope
.block
.build(Instr::Load(
val,
v.1.get_type(scope.type_values, scope.types),
))
.unwrap()
}),
varref.0.clone(),
))
Some(StackValue(v.0, varref.0.clone()))
}
mir::ExprKind::Literal(lit) => Some(StackValue(
StackValueKind::Literal(lit.as_const(&mut scope.block)),
@ -655,7 +644,7 @@ impl mir::Expression {
}
}
mir::ExprKind::Indexed(expression, val_t, idx_expr) => {
let StackValue(kind, ty) = expression
let StackValue(kind, array_ty) = expression
.codegen(scope, &state.load(true))
.expect("array returned none!");
let idx = idx_expr
@ -663,14 +652,22 @@ impl mir::Expression {
.expect("index returned none!")
.instr();
let mut ptr = scope
let first = scope
.block
.build(Instr::GetElemPtr(kind.instr(), vec![idx]))
.build(Instr::Constant(ConstValue::U32(0)))
.unwrap();
let ptr = scope
.block
.build(Instr::GetElemPtr(kind.instr(), vec![first, idx]))
.unwrap()
.maybe_location(&mut scope.block, location);
if state.should_load {
ptr = scope
let TypeKind::Array(elem_ty, _) = array_ty else {
panic!();
};
let elem_value = scope
.block
.build(Instr::Load(
ptr,
@ -678,13 +675,8 @@ impl mir::Expression {
))
.unwrap()
.maybe_location(&mut scope.block, location);
}
let TypeKind::Array(elem_ty, _) = ty else {
panic!();
};
Some(StackValue(kind.derive(ptr), *elem_ty))
Some(StackValue(kind.derive(elem_value), *elem_ty))
}
mir::ExprKind::Array(expressions) => {
let stack_value_list = expressions
@ -696,18 +688,20 @@ impl mir::Expression {
.map(|s| s.instr())
.collect::<Vec<_>>();
let instr_t = stack_value_list
let elem_ty_kind = stack_value_list
.iter()
.map(|s| s.1.clone())
.next()
.unwrap_or(TypeKind::Void);
let array_ty = Type::Array(
Box::new(elem_ty_kind.get_type(scope.type_values, scope.types)),
instr_list.len() as u64,
);
let array = scope
.block
.build(Instr::ArrayAlloca(
instr_t.get_type(scope.type_values, scope.types),
instr_list.len() as u32,
))
.build(Instr::Alloca("array".to_owned(), array_ty.clone()))
.unwrap()
.maybe_location(&mut scope.block, location);
@ -716,9 +710,13 @@ impl mir::Expression {
.block
.build(Instr::Constant(ConstValue::U32(index as u32)))
.unwrap();
let first = scope
.block
.build(Instr::Constant(ConstValue::U32(0)))
.unwrap();
let ptr = scope
.block
.build(Instr::GetElemPtr(array, vec![index_expr]))
.build(Instr::GetElemPtr(array, vec![first, index_expr]))
.unwrap()
.maybe_location(&mut scope.block, location);
scope
@ -728,9 +726,15 @@ impl mir::Expression {
.maybe_location(&mut scope.block, location);
}
let array_val = scope
.block
.build(Instr::Load(array, array_ty))
.unwrap()
.maybe_location(&mut scope.block, location);
Some(StackValue(
StackValueKind::Literal(array),
TypeKind::Array(Box::new(instr_t), instr_list.len() as u64),
StackValueKind::Literal(array_val),
TypeKind::Array(Box::new(elem_ty_kind), instr_list.len() as u64),
))
}
mir::ExprKind::Accessed(expression, type_kind, field) => {
@ -766,12 +770,10 @@ impl mir::Expression {
))
}
mir::ExprKind::Struct(name, items) => {
let struct_ty = Type::CustomType(*scope.type_values.get(name)?);
let struct_ptr = scope
.block
.build(Instr::Alloca(
name.clone(),
Type::CustomType(*scope.type_values.get(name)?),
))
.build(Instr::Alloca(name.clone(), struct_ty.clone()))
.unwrap()
.maybe_location(&mut scope.block, location);
@ -790,8 +792,13 @@ impl mir::Expression {
}
}
let struct_val = scope
.block
.build(Instr::Load(struct_ptr, struct_ty))
.unwrap();
Some(StackValue(
StackValueKind::Literal(struct_ptr),
StackValueKind::Literal(struct_val),
TypeKind::CustomType(name.clone()),
))
}
@ -954,15 +961,14 @@ impl TypeKind {
TypeKind::U128 => Type::U128,
TypeKind::Bool => Type::Bool,
TypeKind::StringPtr => Type::Ptr(Box::new(Type::I8)),
TypeKind::Array(elem_t, _) => Type::Ptr(Box::new(elem_t.get_type(type_vals, typedefs))),
TypeKind::Array(elem_t, len) => {
Type::Array(Box::new(elem_t.get_type(type_vals, typedefs)), *len)
}
TypeKind::Void => Type::Void,
TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
TypeKind::CustomType(n) => {
let type_val = type_vals.get(n).unwrap().clone();
let custom_t = Type::CustomType(type_val);
match typedefs.get(&type_val).unwrap().kind {
TypeDefinitionKind::Struct(_) => Type::Ptr(Box::new(custom_t)),
}
Type::CustomType(type_val)
}
TypeKind::Ptr(type_kind) => {
Type::Ptr(Box::new(type_kind.get_type(type_vals, typedefs)))

View File

@ -194,13 +194,12 @@ pub fn compile_and_pass<'map>(
let mut mir_context = mir::Context::from(vec![module], path.parent().unwrap().to_owned());
dbg!(&mir_context);
println!("Context: {}", &mir_context);
perform_all_passes(&mut mir_context, module_map)?;
#[cfg(debug_assertions)]
dbg!(&mir_context);
println!("Context: {}", &mir_context);
#[cfg(debug_assertions)]
println!("{}", &mir_context);
let mut context = Context::new(format!("Reid ({})", env!("CARGO_PKG_VERSION")));
let codegen_modules = mir_context.codegen(&mut context, &module_map);

View File

@ -103,10 +103,10 @@ impl<'map> Pass for LinkerPass<'map> {
modules.insert(module.name.clone(), Rc::new(RefCell::new((module, tokens))));
}
modules.insert(
"std".to_owned(),
Rc::new(RefCell::new(compile_std(&mut self.module_map)?)),
);
// modules.insert(
// "std".to_owned(),
// Rc::new(RefCell::new(compile_std(&mut self.module_map)?)),
// );
let mut modules_to_process: Vec<Rc<RefCell<(Module, Vec<FullToken>)>>> =
modules.values().cloned().collect();