From 233ddb60f7f31c67ae1399e8eaf68ac549e8e2c4 Mon Sep 17 00:00:00 2001 From: sofia Date: Wed, 16 Jul 2025 17:53:41 +0300 Subject: [PATCH] Fix struct gep return type, refactor a bit --- reid-llvm-lib/src/builder.rs | 116 +--------------------------------- reid-llvm-lib/src/compile.rs | 23 +++---- reid-llvm-lib/src/lib.rs | 117 +++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 128 deletions(-) diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index 71980b5..c04e156 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -4,8 +4,8 @@ use std::{cell::RefCell, rc::Rc}; use crate::{ - BlockData, ConstValue, CustomTypeKind, FunctionData, Instr, InstructionData, ModuleData, - NamedStruct, TerminatorKind, Type, TypeData, util::match_types, + BlockData, CustomTypeKind, FunctionData, Instr, InstructionData, ModuleData, NamedStruct, + TerminatorKind, Type, TypeData, util::match_types, }; #[derive(Clone, Hash, Copy, PartialEq, Eq)] @@ -373,115 +373,3 @@ impl Builder { } } } - -impl InstructionValue { - pub(crate) fn get_type(&self, builder: &Builder) -> Result { - use Instr::*; - unsafe { - match &builder.instr_data(self).kind { - Param(nth) => builder - .function_data(&self.0.0) - .params - .get(*nth) - .cloned() - .ok_or(()), - Constant(c) => Ok(c.get_type()), - Add(lhs, rhs) => match_types(lhs, rhs, &builder), - Sub(lhs, rhs) => match_types(lhs, rhs, &builder), - Mult(lhs, rhs) => match_types(lhs, rhs, &builder), - And(lhs, rhs) => match_types(lhs, rhs, &builder), - ICmp(_, _, _) => Ok(Type::Bool), - FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret), - Phi(values) => values.first().ok_or(()).and_then(|v| v.get_type(&builder)), - Alloca(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))), - 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), - GetStructElemPtr(instr, idx) => { - let instr_val = instr.get_type(builder)?; - let Type::CustomType(ty_value) = instr_val else { - panic!("GetStructElemPtr on non-struct! ({:?})", &instr_val) - }; - match builder.type_data(&ty_value).kind { - CustomTypeKind::NamedStruct(NamedStruct(_, fields)) => { - Ok(fields.get_unchecked(*idx as usize).clone()) - } - } - } - } - } - } -} - -impl ConstValue { - pub fn get_type(&self) -> Type { - use Type::*; - match self { - ConstValue::I8(_) => I8, - ConstValue::I16(_) => I16, - ConstValue::I32(_) => I32, - ConstValue::I64(_) => I64, - ConstValue::I128(_) => I128, - ConstValue::U8(_) => U8, - ConstValue::U16(_) => U16, - ConstValue::U32(_) => U32, - ConstValue::U64(_) => U64, - ConstValue::U128(_) => U128, - ConstValue::StringPtr(_) => Ptr(Box::new(I8)), - ConstValue::Bool(_) => Bool, - } - } -} - -impl Type { - pub fn comparable(&self) -> bool { - match self { - Type::I8 => true, - Type::I16 => true, - Type::I32 => true, - Type::I64 => true, - Type::I128 => true, - Type::U8 => true, - Type::U16 => true, - Type::U32 => true, - Type::U64 => true, - Type::U128 => true, - Type::Bool => true, - Type::Void => false, - Type::Ptr(_) => false, - Type::CustomType(_) => false, - } - } - - pub fn signed(&self) -> bool { - match self { - Type::I8 => true, - Type::I16 => true, - Type::I32 => true, - Type::I64 => true, - Type::I128 => true, - Type::U8 => false, - Type::U16 => false, - Type::U32 => false, - Type::U64 => false, - Type::U128 => false, - Type::Bool => false, - Type::Void => false, - Type::Ptr(_) => false, - Type::CustomType(_) => false, - } - } -} - -impl TerminatorKind { - pub(crate) fn get_type(&self, builder: &Builder) -> Result { - use TerminatorKind::*; - match self { - Ret(instr_val) => instr_val.get_type(builder), - RetVoid => Ok(Type::Void), - Br(_) => Ok(Type::Void), - CondBr(_, _, _) => Ok(Type::Void), - } - } -} diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index c2cd02b..7520c86 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -509,27 +509,22 @@ impl InstructionHolder { } GetStructElemPtr(struct_val, idx) => { let t = struct_val.get_type(module.builder).unwrap(); - let Type::Ptr(inner_t) = t else { panic!() }; + dbg!(&t); + let Type::Ptr(struct_t) = t else { panic!() }; - let Type::CustomType(struct_ty) = *inner_t else { - panic!(); - }; - let struct_ty_data = module.builder.type_data(&struct_ty); - let (name, elem_ty) = match struct_ty_data.kind { - CustomTypeKind::NamedStruct(NamedStruct(name, fields)) => ( - name, - fields - .get_unchecked(*idx as usize) - .as_llvm(module.context_ref, &module.types), - ), + let type_fmt = if let Type::CustomType(type_val) = *struct_t { + format!("M{}T{}", type_val.0.0, type_val.1) + } else { + format!("{:?}", struct_t) }; + dbg!(idx); LLVMBuildStructGEP2( module.builder_ref, - elem_ty, + struct_t.as_llvm(module.context_ref, &module.types), module.values.get(struct_val).unwrap().value_ref, *idx, - into_cstring(format!("struct_gep_{}_{}", name, idx)).as_ptr(), + into_cstring(format!("struct.{}.{}.gep", type_fmt, idx)).as_ptr(), ) } } diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index a23e51c..9eee9cd 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -6,6 +6,7 @@ use std::{fmt::Debug, marker::PhantomData}; use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue, TypeValue}; use debug::PrintableModule; +use util::match_types; pub mod builder; pub mod compile; @@ -289,3 +290,119 @@ pub enum CustomTypeKind { #[derive(Debug, PartialEq, Eq, Clone, Hash)] pub struct NamedStruct(pub String, pub Vec); + +impl InstructionValue { + pub(crate) fn get_type(&self, builder: &Builder) -> Result { + use Instr::*; + unsafe { + match &builder.instr_data(self).kind { + Param(nth) => builder + .function_data(&self.0.0) + .params + .get(*nth) + .cloned() + .ok_or(()), + Constant(c) => Ok(c.get_type()), + Add(lhs, rhs) => match_types(lhs, rhs, &builder), + Sub(lhs, rhs) => match_types(lhs, rhs, &builder), + Mult(lhs, rhs) => match_types(lhs, rhs, &builder), + And(lhs, rhs) => match_types(lhs, rhs, &builder), + ICmp(_, _, _) => Ok(Type::Bool), + FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret), + Phi(values) => values.first().ok_or(()).and_then(|v| v.get_type(&builder)), + Alloca(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))), + 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), + GetStructElemPtr(instr, idx) => { + let instr_ty = instr.get_type(builder)?; + let Type::Ptr(inner_ty) = instr_ty else { + panic!("GetStructElemPtr on non-pointer! ({:?})", &instr_ty) + }; + let Type::CustomType(ty_value) = *inner_ty else { + panic!("GetStructElemPtr on non-struct! ({:?})", &inner_ty) + }; + let field_ty = match builder.type_data(&ty_value).kind { + CustomTypeKind::NamedStruct(NamedStruct(_, fields)) => { + fields.get_unchecked(*idx as usize).clone() + } + }; + Ok(Type::Ptr(Box::new(field_ty))) + } + } + } + } +} + +impl ConstValue { + pub fn get_type(&self) -> Type { + use Type::*; + match self { + ConstValue::I8(_) => I8, + ConstValue::I16(_) => I16, + ConstValue::I32(_) => I32, + ConstValue::I64(_) => I64, + ConstValue::I128(_) => I128, + ConstValue::U8(_) => U8, + ConstValue::U16(_) => U16, + ConstValue::U32(_) => U32, + ConstValue::U64(_) => U64, + ConstValue::U128(_) => U128, + ConstValue::StringPtr(_) => Ptr(Box::new(I8)), + ConstValue::Bool(_) => Bool, + } + } +} + +impl Type { + pub fn comparable(&self) -> bool { + match self { + Type::I8 => true, + Type::I16 => true, + Type::I32 => true, + Type::I64 => true, + Type::I128 => true, + Type::U8 => true, + Type::U16 => true, + Type::U32 => true, + Type::U64 => true, + Type::U128 => true, + Type::Bool => true, + Type::Void => false, + Type::Ptr(_) => false, + Type::CustomType(_) => false, + } + } + + pub fn signed(&self) -> bool { + match self { + Type::I8 => true, + Type::I16 => true, + Type::I32 => true, + Type::I64 => true, + Type::I128 => true, + Type::U8 => false, + Type::U16 => false, + Type::U32 => false, + Type::U64 => false, + Type::U128 => false, + Type::Bool => false, + Type::Void => false, + Type::Ptr(_) => false, + Type::CustomType(_) => false, + } + } +} + +impl TerminatorKind { + pub(crate) fn get_type(&self, builder: &Builder) -> Result { + use TerminatorKind::*; + match self { + Ret(instr_val) => instr_val.get_type(builder), + RetVoid => Ok(Type::Void), + Br(_) => Ok(Type::Void), + CondBr(_, _, _) => Ok(Type::Void), + } + } +}