From cbb1be1161da61f6c60e378408363509a3c23719 Mon Sep 17 00:00:00 2001 From: sofia Date: Sun, 13 Jul 2025 23:14:16 +0300 Subject: [PATCH] Implement GEP instead of the weird thing before --- reid-llvm-lib/src/builder.rs | 44 +++++++-------------------- reid-llvm-lib/src/compile.rs | 57 +++++++++-------------------------- reid-llvm-lib/src/debug.rs | 11 +++++-- reid-llvm-lib/src/lib.rs | 5 ++- reid/src/ast/process.rs | 8 +++-- reid/src/codegen.rs | 21 ++++++++----- reid/src/mir/display.rs | 3 +- reid/src/mir/mod.rs | 2 +- reid/src/mir/typecheck.rs | 12 ++++++-- reid/src/mir/typeinference.rs | 9 ++++-- reid/src/mir/types.rs | 2 +- 11 files changed, 76 insertions(+), 98 deletions(-) diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index 9e91ee1..c3ed463 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -270,6 +270,7 @@ impl Builder { } Store(ptr, _) => { if let Ok(ty) = ptr.get_type(&self) { + dbg!(&ty); if let Type::Ptr(_) = ty { Ok(()) } else { @@ -279,24 +280,11 @@ impl Builder { Err(()) } } - Extract(arr, idx) => { - let arr_ty = arr.get_type(&self)?; - if let Type::Array(_, len) = arr_ty { - if len > idx { Ok(()) } else { Err(()) } - } else { - Err(()) - } - } ArrayAlloca(_, _) => Ok(()), - Insert(arr, idx, val) => { + ArrayGEP(arr, _) => { let arr_ty = arr.get_type(&self)?; - let val_ty = val.get_type(&self)?; - if let Type::Array(elem_ty, len) = arr_ty { - if val_ty == *elem_ty && len > idx { - Ok(()) - } else { - Err(()) - } + if let Type::ArrayPtr(_, _) = arr_ty { + Ok(()) } else { Err(()) } @@ -362,15 +350,14 @@ impl InstructionValue { Alloca(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))), Load(_, ty) => Ok(ty.clone()), Store(_, value) => value.get_type(builder), - Extract(arr, _) => match arr.get_type(builder) { - Ok(Type::Array(elem_t, _)) => Ok(*elem_t), + ArrayAlloca(ty, len_value) => { + Ok(Type::ArrayPtr(Box::new(ty.clone()), len_value.clone())) + } + ArrayGEP(arr, _) => match arr.get_type(builder) { + Ok(Type::ArrayPtr(elem_t, _)) => Ok(Type::Ptr(Box::new(*elem_t))), Ok(_) => Err(()), Err(_) => Err(()), }, - ArrayAlloca(ty, len_value) => { - Ok(Type::Array(Box::new(ty.clone()), len_value.clone())) - } - Insert(_, _, val) => val.get_type(builder), } } } @@ -391,15 +378,6 @@ impl ConstValue { ConstValue::U64(_) => U64, ConstValue::U128(_) => U128, ConstValue::Bool(_) => Bool, - // ConstValue::Array(arr) => Array( - // Box::new( - // arr.iter() - // .map(|a| a.get_type(builder).unwrap()) - // .next() - // .unwrap_or(Void), - // ), - // arr.len() as u32, - // ), } } } @@ -420,7 +398,7 @@ impl Type { Type::Bool => true, Type::Void => false, Type::Ptr(_) => false, - Type::Array(_, _) => false, + Type::ArrayPtr(_, _) => false, } } @@ -439,7 +417,7 @@ impl Type { Type::Bool => false, Type::Void => false, Type::Ptr(_) => false, - Type::Array(_, _) => false, + Type::ArrayPtr(_, _) => false, } } } diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index ca494a9..8632641 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -349,29 +349,9 @@ impl InstructionHolder { module.values.get(&val).unwrap().value_ref, module.values.get(&ptr).unwrap().value_ref, ), - Extract(arr, idx) => { - let t = arr.get_type(module.builder).unwrap(); - let Type::Array(elem_t, _) = t else { panic!() }; - - let indices = &mut [ConstValue::I32(*idx as i32).as_llvm(module.context_ref)]; - let ptr = LLVMBuildGEP2( - module.builder_ref, - elem_t.as_llvm(module.context_ref), - module.values.get(arr).unwrap().value_ref, - indices.as_mut_ptr(), - 1, - c"insert_gep".as_ptr(), - ); - LLVMBuildLoad2( - module.builder_ref, - elem_t.as_llvm(module.context_ref), - ptr, - c"load".as_ptr(), - ) - } ArrayAlloca(ty, len) => { let array_len = ConstValue::U16(*len as u16).as_llvm(module.context_ref); - let array_ty = Type::Array(Box::new(ty.clone()), *len); + let array_ty = Type::ArrayPtr(Box::new(ty.clone()), *len); dbg!( &ty.as_llvm(module.context_ref), &array_ty.as_llvm(module.context_ref) @@ -383,31 +363,24 @@ impl InstructionHolder { c"array_alloca".as_ptr(), ) } - Insert(arr, idx, val) => { - let indices = &mut [ConstValue::I32(*idx as i32).as_llvm(module.context_ref)]; - let ptr = LLVMBuildGEP2( + ArrayGEP(arr, indices) => { + let t = arr.get_type(module.builder).unwrap(); + let Type::ArrayPtr(elem_t, _) = t else { + panic!() + }; + + let mut indices: Vec<_> = indices + .iter() + .map(|idx| ConstValue::U32(*idx).as_llvm(module.context_ref)) + .collect(); + LLVMBuildGEP2( module.builder_ref, - val.get_type(module.builder) - .unwrap() - .as_llvm(module.context_ref), + elem_t.as_llvm(module.context_ref), module.values.get(arr).unwrap().value_ref, indices.as_mut_ptr(), 1, - c"insert_gep".as_ptr(), - ); - LLVMBuildStore( - module.builder_ref, - module.values.get(val).unwrap().value_ref, - ptr, + c"array_gep".as_ptr(), ) - - // LLVMBuildInsertValue( - // module.builder_ref, - // ptr, - // module.values.get(val).unwrap().value_ref, - // *idx, - // c"insert".as_ptr(), - // ) } } }; @@ -505,7 +478,7 @@ impl Type { Bool => LLVMInt1TypeInContext(context), Void => LLVMVoidType(), Ptr(ty) => LLVMPointerType(ty.as_llvm(context), 0), - Array(elem_t, _) => LLVMPointerType(elem_t.as_llvm(context), 0), + ArrayPtr(elem_t, _) => LLVMPointerType(elem_t.as_llvm(context), 0), } } } diff --git a/reid-llvm-lib/src/debug.rs b/reid-llvm-lib/src/debug.rs index 6a5ea79..77b878a 100644 --- a/reid-llvm-lib/src/debug.rs +++ b/reid-llvm-lib/src/debug.rs @@ -100,11 +100,18 @@ impl Debug for Instr { Instr::Alloca(name, ty) => write!(f, "alloca<{:?}>({})", ty, name), Instr::Load(val, ty) => write!(f, "load<{:?}>({:?})", ty, val), Instr::Store(ptr, val) => write!(f, "store({:?} = {:?})", ptr, val), - Instr::Extract(instruction_value, idx) => fmt_index(f, instruction_value, idx), Instr::ArrayAlloca(ty, instruction_value) => { write!(f, "array_alloca<{:?}>({:?})", ty, instruction_value) } - Instr::Insert(arr, idx, val) => write!(f, "{:?}[{}] = {:?}", arr, idx, val), + Instr::ArrayGEP(instruction_value, items) => fmt_index( + f, + instruction_value, + &items + .iter() + .map(|i| i.to_string()) + .collect::>() + .join(", "), + ), } } } diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 415253a..4006afa 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -178,8 +178,7 @@ pub enum Instr { Load(InstructionValue, Type), Store(InstructionValue, InstructionValue), ArrayAlloca(Type, u32), - Insert(InstructionValue, u32, InstructionValue), - Extract(InstructionValue, u32), + ArrayGEP(InstructionValue, Vec), /// Integer Comparison ICmp(CmpPredicate, InstructionValue, InstructionValue), @@ -202,7 +201,7 @@ pub enum Type { Bool, Void, Ptr(Box), - Array(Box, u32), + ArrayPtr(Box, u32), } #[derive(Debug, Clone, Hash)] diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 6ff2f37..72f4d6a 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -171,9 +171,11 @@ impl ast::Expression { ast::ExpressionKind::Array(expressions) => { mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect()) } - ast::ExpressionKind::Index(expression, idx) => { - mir::ExprKind::Index(Box::new(expression.process()), *idx) - } + ast::ExpressionKind::Index(expression, idx) => mir::ExprKind::Index( + Box::new(expression.process()), + mir::TypeKind::Vague(mir::VagueType::Unknown), + *idx, + ), }; mir::Expression(kind, self.1.into()) diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index 0ef715f..b4488be 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -334,12 +334,17 @@ impl mir::Expression { None } } - mir::ExprKind::Index(expression, idx) => { - let expr = expression.codegen(scope)?; + mir::ExprKind::Index(expression, val_t, idx) => { + let array = expression.codegen(scope)?; + let ptr = scope + .block + .build(Instr::ArrayGEP(array, vec![*idx as u32])) + .unwrap(); + Some( scope .block - .build(Instr::Extract(expr, *idx as u32)) + .build(Instr::Load(ptr, val_t.get_type())) .unwrap(), ) } @@ -354,7 +359,6 @@ impl mir::Expression { .next() .unwrap_or(TypeKind::Void); - dbg!(&instr_t); let array = scope .block .build(Instr::ArrayAlloca( @@ -364,10 +368,11 @@ impl mir::Expression { .unwrap(); for (i, instr) in instr_list.iter().enumerate() { - scope + let ptr = scope .block - .build(Instr::Insert(array, i as u32, *instr)) + .build(Instr::ArrayGEP(array, vec![i as u32])) .unwrap(); + scope.block.build(Instr::Store(ptr, *instr)).unwrap(); } Some(array) @@ -450,7 +455,9 @@ impl TypeKind { TypeKind::U64 => Type::U64, TypeKind::U128 => Type::U128, TypeKind::Bool => Type::Bool, - TypeKind::Array(elem_t, len) => Type::Array(Box::new(elem_t.get_type()), *len as u32), + TypeKind::Array(elem_t, len) => { + Type::ArrayPtr(Box::new(elem_t.get_type()), *len as u32) + } TypeKind::Void => panic!("Void not a supported type"), TypeKind::Vague(_) => panic!("Tried to compile a vague type!"), } diff --git a/reid/src/mir/display.rs b/reid/src/mir/display.rs index ef126f8..72d3fd4 100644 --- a/reid/src/mir/display.rs +++ b/reid/src/mir/display.rs @@ -128,8 +128,9 @@ impl Display for ExprKind { ExprKind::FunctionCall(fc) => Display::fmt(fc, f), ExprKind::If(if_exp) => Display::fmt(&if_exp, f), ExprKind::Block(block) => Display::fmt(block, f), - ExprKind::Index(expression, idx) => { + ExprKind::Index(expression, elem_ty, idx) => { Display::fmt(&expression, f)?; + write!(f, "<{}>", elem_ty)?; write_index(f, *idx) } ExprKind::Array(expressions) => { diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 772373a..609039e 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -208,7 +208,7 @@ pub struct Import(pub String, pub Metadata); #[derive(Debug)] pub enum ExprKind { Variable(NamedVariableRef), - Index(Box, u64), + Index(Box, TypeKind, u64), Array(Vec), Literal(Literal), BinOp(BinaryOperator, Box, Box), diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index 3778608..e8ddb4c 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -380,7 +380,7 @@ impl Expression { Ok(collapsed) } ExprKind::Block(block) => block.typecheck(state, &hints, hint_t), - ExprKind::Index(expression, idx) => { + ExprKind::Index(expression, elem_ty, idx) => { // Try to unwrap hint type from array if possible let hint_t = hint_t.map(|t| match t { Array(type_kind, _) => &type_kind, @@ -388,11 +388,17 @@ impl Expression { }); let expr_t = expression.typecheck(state, hints, hint_t)?; - if let TypeKind::Array(elem_t, len) = expr_t { + if let TypeKind::Array(inferred_ty, len) = expr_t { if len < *idx { return Err(ErrorKind::IndexOutOfBounds(*idx, len)); } - Ok(*elem_t) + let ty = state.or_else( + elem_ty.resolve_hinted(hints).collapse_into(&inferred_ty), + TypeKind::Vague(Unknown), + self.1, + ); + *elem_ty = ty.clone(); + Ok(ty) } else { Err(ErrorKind::TriedIndexingNonArray(expr_t)) } diff --git a/reid/src/mir/typeinference.rs b/reid/src/mir/typeinference.rs index 8920d3b..b38ff6d 100644 --- a/reid/src/mir/typeinference.rs +++ b/reid/src/mir/typeinference.rs @@ -263,11 +263,16 @@ impl Expression { ReturnKind::Soft => Ok(block_ref.1), } } - ExprKind::Index(expression, _) => { + ExprKind::Index(expression, index_ty, _) => { let expr_ty = expression.infer_types(state, type_refs)?; + let kind = unsafe { expr_ty.resolve_type() }; match kind { - Array(type_kind, _) => Ok(type_refs.from_type(&type_kind).unwrap()), + Array(type_kind, _) => { + let elem_ty = type_refs.from_type(&type_kind).unwrap(); + *index_ty = elem_ty.as_type().clone(); + Ok(elem_ty) + } _ => Err(ErrorKind::TriedIndexingNonArray(kind)), } } diff --git a/reid/src/mir/types.rs b/reid/src/mir/types.rs index aa946c8..a0573c7 100644 --- a/reid/src/mir/types.rs +++ b/reid/src/mir/types.rs @@ -89,7 +89,7 @@ impl ReturnType for Expression { Block(block) => block.return_type(), FunctionCall(fcall) => fcall.return_type(), If(expr) => expr.return_type(), - Index(expression, _) => { + Index(expression, _, _) => { let expr_type = expression.return_type()?; if let (_, TypeKind::Array(elem_ty, _)) = expr_type { Ok((ReturnKind::Soft, *elem_ty))