diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index 9322144..6d7bf29 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -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(()), + } + } } } } diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index 913a105..b618b78 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -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 { - 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), } } } diff --git a/reid-llvm-lib/src/debug.rs b/reid-llvm-lib/src/debug.rs index 0066dd1..975c46d 100644 --- a/reid-llvm-lib/src/debug.rs +++ b/reid-llvm-lib/src/debug.rs @@ -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()) } } diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index ab88fb4..c39a6ee 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -318,6 +318,7 @@ pub enum Instr { ArrayAlloca(Type, u32), GetElemPtr(InstructionValue, Vec), 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, u64), Ptr(Box), } @@ -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, } } } diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index f53fa7f..cd15f05 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -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,28 +652,31 @@ 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 - .block - .build(Instr::Load( - ptr, - val_t.get_type(scope.type_values, scope.types), - )) - .unwrap() - .maybe_location(&mut scope.block, location); - } - - let TypeKind::Array(elem_ty, _) = ty else { + let TypeKind::Array(elem_ty, _) = array_ty else { panic!(); }; - Some(StackValue(kind.derive(ptr), *elem_ty)) + let elem_value = scope + .block + .build(Instr::Load( + ptr, + val_t.get_type(scope.type_values, scope.types), + )) + .unwrap() + .maybe_location(&mut scope.block, location); + + 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::>(); - 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))) diff --git a/reid/src/lib.rs b/reid/src/lib.rs index 0e2596a..179a6f7 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -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); diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index e8b66af..530faca 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -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)>>> = modules.values().cloned().collect();