Add global api support for llvm-lib

This commit is contained in:
Sofia 2025-07-28 23:20:13 +03:00
parent a7ac974f46
commit 30257e1a2b
8 changed files with 142 additions and 81 deletions

View File

@ -1,7 +1,7 @@
use reid_lib::{CmpPredicate, ConstValue, Context, FunctionFlags, Instr, TerminatorKind, Type}; use reid_lib::{CmpPredicate, ConstValueKind, Context, FunctionFlags, Instr, TerminatorKind, Type};
fn main() { fn main() {
use ConstValue::*; use ConstValueKind::*;
use Instr::*; use Instr::*;
let context = Context::new("libtest"); let context = Context::new("libtest");

View File

@ -4,8 +4,8 @@
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
use crate::{ use crate::{
Block, BlockData, CompileResult, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData, ModuleData, Block, BlockData, CompileResult, ConstValueKind, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData,
NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, ModuleData, NamedStruct, TerminatorKind, Type, TypeCategory, TypeData,
debug_information::{ debug_information::{
DebugInformation, DebugLocationValue, DebugMetadataValue, DebugScopeValue, InstructionDebugRecordData, DebugInformation, DebugLocationValue, DebugMetadataValue, DebugScopeValue, InstructionDebugRecordData,
}, },
@ -27,6 +27,12 @@ pub struct BlockValue(pub(crate) FunctionValue, pub(crate) usize);
#[derive(Clone, Hash, Copy, PartialEq, Eq)] #[derive(Clone, Hash, Copy, PartialEq, Eq)]
pub struct InstructionValue(pub(crate) BlockValue, pub(crate) usize); pub struct InstructionValue(pub(crate) BlockValue, pub(crate) usize);
#[derive(Clone, Hash, Copy, PartialEq, Eq)]
pub struct ConstantValue(pub(crate) usize);
#[derive(Clone, Hash, Copy, PartialEq, Eq)]
pub struct GlobalValue(pub(crate) usize);
#[derive(Clone)] #[derive(Clone)]
pub struct ModuleHolder { pub struct ModuleHolder {
pub(crate) value: ModuleValue, pub(crate) value: ModuleValue,
@ -34,6 +40,20 @@ pub struct ModuleHolder {
pub(crate) functions: Vec<FunctionHolder>, pub(crate) functions: Vec<FunctionHolder>,
pub(crate) types: Vec<TypeHolder>, pub(crate) types: Vec<TypeHolder>,
pub(crate) debug_information: Option<DebugInformation>, pub(crate) debug_information: Option<DebugInformation>,
pub(crate) constants: Vec<ConstantValueHolder>,
pub(crate) globals: Vec<GlobalValueHolder>,
}
#[derive(Clone)]
pub struct ConstantValueHolder {
pub(crate) value: ConstantValue,
pub(crate) kind: ConstValueKind,
}
#[derive(Clone)]
pub struct GlobalValueHolder {
pub(crate) value: GlobalValue,
pub(crate) name: String,
pub(crate) initializer: ConstantValue,
} }
#[derive(Clone)] #[derive(Clone)]
@ -88,6 +108,8 @@ impl Builder {
functions: Vec::new(), functions: Vec::new(),
types: Vec::new(), types: Vec::new(),
debug_information: None, debug_information: None,
constants: Vec::new(),
globals: Vec::new(),
}); });
value value
} }
@ -168,6 +190,35 @@ impl Builder {
} }
} }
pub(crate) unsafe fn build_constant(&self, module: ModuleValue, kind: ConstValueKind) -> ConstantValue {
unsafe {
let mut modules = self.modules.borrow_mut();
let module = modules.get_unchecked_mut(module.0);
let value = ConstantValue(module.constants.len());
module.constants.push(ConstantValueHolder { value, kind });
value
}
}
pub(crate) unsafe fn add_global(
&self,
module: ModuleValue,
name: String,
initializer: ConstantValue,
) -> GlobalValue {
unsafe {
let mut modules = self.modules.borrow_mut();
let module = modules.get_unchecked_mut(module.0);
let value = GlobalValue(module.globals.len());
module.globals.push(GlobalValueHolder {
value,
name,
initializer,
});
value
}
}
pub(crate) unsafe fn find_function(&self, module: ModuleValue, name: &String) -> Option<FunctionValue> { pub(crate) unsafe fn find_function(&self, module: ModuleValue, name: &String) -> Option<FunctionValue> {
unsafe { unsafe {
let mut modules = self.modules.borrow_mut(); let mut modules = self.modules.borrow_mut();

View File

@ -33,7 +33,7 @@ use crate::{
}; };
use super::{ use super::{
CmpPredicate, ConstValue, Context, TerminatorKind, Type, CmpPredicate, ConstValueKind, Context, TerminatorKind, Type,
builder::{ builder::{
BlockHolder, BlockValue, Builder, FunctionHolder, FunctionValue, InstructionHolder, InstructionValue, BlockHolder, BlockValue, Builder, FunctionHolder, FunctionValue, InstructionHolder, InstructionValue,
ModuleHolder, ModuleHolder,
@ -1144,32 +1144,32 @@ impl CmpPredicate {
} }
} }
impl ConstValue { impl ConstValueKind {
fn as_llvm(&self, module: &LLVMModule) -> LLVMValueRef { fn as_llvm(&self, module: &LLVMModule) -> LLVMValueRef {
unsafe { unsafe {
let t = self.get_type().as_llvm(module.context_ref, &module.types); let t = self.get_type().as_llvm(module.context_ref, &module.types);
match self { match self {
ConstValue::Bool(val) => LLVMConstInt(t, *val as u64, 1), ConstValueKind::Bool(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::I8(val) => LLVMConstInt(t, *val as u64, 1), ConstValueKind::I8(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::I16(val) => LLVMConstInt(t, *val as u64, 1), ConstValueKind::I16(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::I32(val) => LLVMConstInt(t, *val as u64, 1), ConstValueKind::I32(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::I64(val) => LLVMConstInt(t, *val as u64, 1), ConstValueKind::I64(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::I128(val) => LLVMConstInt(t, *val as u64, 1), ConstValueKind::I128(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U8(val) => LLVMConstInt(t, *val as u64, 1), ConstValueKind::U8(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U16(val) => LLVMConstInt(t, *val as u64, 1), ConstValueKind::U16(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U32(val) => LLVMConstInt(t, *val as u64, 1), ConstValueKind::U32(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U64(val) => LLVMConstInt(t, *val as u64, 1), ConstValueKind::U64(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U128(val) => LLVMConstInt(t, *val as u64, 1), ConstValueKind::U128(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::Str(val) => { ConstValueKind::Str(val) => {
LLVMBuildGlobalString(module.builder_ref, into_cstring(val).as_ptr(), c"string".as_ptr()) LLVMBuildGlobalString(module.builder_ref, into_cstring(val).as_ptr(), c"string".as_ptr())
} }
ConstValue::F16(val) => LLVMConstReal(t, *val as f64), ConstValueKind::F16(val) => LLVMConstReal(t, *val as f64),
ConstValue::F32B(val) => LLVMConstReal(t, *val as f64), ConstValueKind::F32B(val) => LLVMConstReal(t, *val as f64),
ConstValue::F32(val) => LLVMConstReal(t, *val as f64), ConstValueKind::F32(val) => LLVMConstReal(t, *val as f64),
ConstValue::F64(val) => LLVMConstReal(t, *val as f64), ConstValueKind::F64(val) => LLVMConstReal(t, *val as f64),
ConstValue::F80(val) => LLVMConstReal(t, *val as f64), ConstValueKind::F80(val) => LLVMConstReal(t, *val as f64),
ConstValue::F128(val) => LLVMConstReal(t, *val as f64), ConstValueKind::F128(val) => LLVMConstReal(t, *val as f64),
ConstValue::F128PPC(val) => LLVMConstReal(t, *val as f64), ConstValueKind::F128PPC(val) => LLVMConstReal(t, *val as f64),
} }
} }
} }

View File

@ -8,7 +8,10 @@ use builder::{BlockValue, Builder, FunctionValue, InstructionValue, ModuleValue,
use debug_information::{DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue}; use debug_information::{DebugFileData, DebugInformation, DebugLocationValue, DebugMetadataValue};
use fmt::PrintableModule; use fmt::PrintableModule;
use crate::debug_information::DebugScopeValue; use crate::{
builder::{ConstantValue, GlobalValue},
debug_information::DebugScopeValue,
};
pub mod builder; pub mod builder;
pub mod compile; pub mod compile;
@ -121,6 +124,14 @@ impl<'ctx> Module<'ctx> {
pub fn get_debug_info(&self) -> &Option<DebugInformation> { pub fn get_debug_info(&self) -> &Option<DebugInformation> {
&self.debug_info &self.debug_info
} }
pub fn add_constant(&self, constant: ConstValueKind) -> ConstantValue {
unsafe { self.builder.build_constant(self.value, constant) }
}
pub fn add_global(&self, name: String, constant: ConstantValue) -> GlobalValue {
unsafe { self.builder.add_global(self.value, name, constant) }
}
} }
impl<'ctx> Drop for Module<'ctx> { impl<'ctx> Drop for Module<'ctx> {
@ -361,7 +372,7 @@ pub enum CmpPredicate {
#[derive(Clone)] #[derive(Clone)]
pub enum Instr { pub enum Instr {
Param(usize), Param(usize),
Constant(ConstValue), Constant(ConstValueKind),
/// Add two integers /// Add two integers
Add(InstructionValue, InstructionValue), Add(InstructionValue, InstructionValue),
@ -487,7 +498,7 @@ pub enum Type {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ConstValue { pub enum ConstValueKind {
I8(i8), I8(i8),
I16(i16), I16(i16),
I32(i32), I32(i32),
@ -531,29 +542,29 @@ pub enum CustomTypeKind {
#[derive(Debug, PartialEq, Eq, Clone, Hash)] #[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct NamedStruct(pub String, pub Vec<Type>); pub struct NamedStruct(pub String, pub Vec<Type>);
impl ConstValue { impl ConstValueKind {
pub fn get_type(&self) -> Type { pub fn get_type(&self) -> Type {
use Type::*; use Type::*;
match self { match self {
ConstValue::I8(_) => I8, ConstValueKind::I8(_) => I8,
ConstValue::I16(_) => I16, ConstValueKind::I16(_) => I16,
ConstValue::I32(_) => I32, ConstValueKind::I32(_) => I32,
ConstValue::I64(_) => I64, ConstValueKind::I64(_) => I64,
ConstValue::I128(_) => I128, ConstValueKind::I128(_) => I128,
ConstValue::U8(_) => U8, ConstValueKind::U8(_) => U8,
ConstValue::U16(_) => U16, ConstValueKind::U16(_) => U16,
ConstValue::U32(_) => U32, ConstValueKind::U32(_) => U32,
ConstValue::U64(_) => U64, ConstValueKind::U64(_) => U64,
ConstValue::U128(_) => U128, ConstValueKind::U128(_) => U128,
ConstValue::Str(_) => Type::Ptr(Box::new(U8)), ConstValueKind::Str(_) => Type::Ptr(Box::new(U8)),
ConstValue::Bool(_) => Bool, ConstValueKind::Bool(_) => Bool,
ConstValue::F16(_) => F16, ConstValueKind::F16(_) => F16,
ConstValue::F32B(_) => F32B, ConstValueKind::F32B(_) => F32B,
ConstValue::F32(_) => F32, ConstValueKind::F32(_) => F32,
ConstValue::F64(_) => F64, ConstValueKind::F64(_) => F64,
ConstValue::F80(_) => F80, ConstValueKind::F80(_) => F80,
ConstValue::F128(_) => F128, ConstValueKind::F128(_) => F128,
ConstValue::F128PPC(_) => F128PPC, ConstValueKind::F128PPC(_) => F128PPC,
} }
} }
} }

View File

@ -1,4 +1,4 @@
use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValue, Instr, Type}; use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValueKind, Instr, Type};
use crate::{ use crate::{
codegen::{ErrorKind, StackValueKind}, codegen::{ErrorKind, StackValueKind},
@ -364,7 +364,7 @@ impl IntrinsicFunction for IntrinsicSizeOf {
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> { fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> {
let instr = scope let instr = scope
.block .block
.build(Instr::Constant(reid_lib::ConstValue::U64(self.0.size_of() / 8))) .build(Instr::Constant(reid_lib::ConstValueKind::U64(self.0.size_of() / 8)))
.unwrap(); .unwrap();
Ok(StackValue(StackValueKind::Literal(instr), self.0.clone())) Ok(StackValue(StackValueKind::Literal(instr), self.0.clone()))
} }
@ -382,7 +382,7 @@ impl IntrinsicFunction for IntrinsicMalloc {
let sizeof = scope let sizeof = scope
.block .block
.build(Instr::Constant(ConstValue::U64(self.0.size_of() / 8))) .build(Instr::Constant(ConstValueKind::U64(self.0.size_of() / 8)))
.unwrap(); .unwrap();
let bytes = scope.block.build(Instr::Mul(sizeof, amount.instr())).unwrap(); let bytes = scope.block.build(Instr::Mul(sizeof, amount.instr())).unwrap();
let instr = scope.block.build(Instr::FunctionCall(function, vec![bytes])).unwrap(); let instr = scope.block.build(Instr::FunctionCall(function, vec![bytes])).unwrap();
@ -394,7 +394,7 @@ impl IntrinsicFunction for IntrinsicMalloc {
pub struct IntrinsicNullPtr(TypeKind); pub struct IntrinsicNullPtr(TypeKind);
impl IntrinsicFunction for IntrinsicNullPtr { impl IntrinsicFunction for IntrinsicNullPtr {
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> { fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> {
let zero = scope.block.build(Instr::Constant(ConstValue::I8(0))).unwrap(); let zero = scope.block.build(Instr::Constant(ConstValueKind::I8(0))).unwrap();
let instr = scope let instr = scope
.block .block
.build(Instr::IntToPtr( .build(Instr::IntToPtr(

View File

@ -9,7 +9,7 @@ use reid_lib::{
DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DwarfFlags, DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DwarfFlags,
InstructionDebugRecordData, InstructionDebugRecordData,
}, },
CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr, Module, NamedStruct, CmpPredicate, ConstValueKind, Context, CustomTypeKind, Function, FunctionFlags, Instr, Module, NamedStruct,
TerminatorKind as Term, Type, TerminatorKind as Term, Type,
}; };
use scope::*; use scope::*;
@ -784,7 +784,7 @@ impl mir::Statement {
let condition_res = condition.codegen(&mut condition_scope, state)?.unwrap(); let condition_res = condition.codegen(&mut condition_scope, state)?.unwrap();
let true_instr = condition_scope let true_instr = condition_scope
.block .block
.build(Instr::Constant(ConstValue::Bool(true))) .build(Instr::Constant(ConstValueKind::Bool(true)))
.unwrap(); .unwrap();
let check = condition_scope let check = condition_scope
.block .block
@ -1031,7 +1031,7 @@ impl mir::Expression {
let first = scope let first = scope
.block .block
.build_named("array.zero", Instr::Constant(ConstValue::U32(0))) .build_named("array.zero", Instr::Constant(ConstValueKind::U32(0)))
.unwrap(); .unwrap();
( (
scope scope
@ -1098,11 +1098,11 @@ impl mir::Expression {
let index_expr = scope let index_expr = scope
.block .block
.build_named(index.to_string(), Instr::Constant(ConstValue::U32(index as u32))) .build_named(index.to_string(), Instr::Constant(ConstValueKind::U32(index as u32)))
.unwrap(); .unwrap();
let first = scope let first = scope
.block .block
.build_named("zero", Instr::Constant(ConstValue::U32(0))) .build_named("zero", Instr::Constant(ConstValueKind::U32(0)))
.unwrap(); .unwrap();
let ptr = scope let ptr = scope
.block .block

View File

@ -6,7 +6,7 @@ use reid_lib::{
DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocation, DebugPointerType, DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocation, DebugPointerType,
DebugPosition, DebugScopeValue, DebugStructType, DebugTypeData, DebugTypeValue, DwarfEncoding, DwarfFlags, DebugPosition, DebugScopeValue, DebugStructType, DebugTypeData, DebugTypeValue, DwarfEncoding, DwarfFlags,
}, },
Block, CmpPredicate, ConstValue, Instr, Type, Block, CmpPredicate, ConstValueKind, Instr, Type,
}; };
use crate::{ use crate::{
@ -39,28 +39,28 @@ impl mir::Literal {
pub(super) fn as_const_kind(&self) -> Instr { pub(super) fn as_const_kind(&self) -> Instr {
Instr::Constant(match self.clone() { Instr::Constant(match self.clone() {
mir::Literal::I8(val) => ConstValue::I8(val), mir::Literal::I8(val) => ConstValueKind::I8(val),
mir::Literal::I16(val) => ConstValue::I16(val), mir::Literal::I16(val) => ConstValueKind::I16(val),
mir::Literal::I32(val) => ConstValue::I32(val), mir::Literal::I32(val) => ConstValueKind::I32(val),
mir::Literal::I64(val) => ConstValue::I64(val), mir::Literal::I64(val) => ConstValueKind::I64(val),
mir::Literal::I128(val) => ConstValue::I128(val), mir::Literal::I128(val) => ConstValueKind::I128(val),
mir::Literal::U8(val) => ConstValue::U8(val), mir::Literal::U8(val) => ConstValueKind::U8(val),
mir::Literal::U16(val) => ConstValue::U16(val), mir::Literal::U16(val) => ConstValueKind::U16(val),
mir::Literal::U32(val) => ConstValue::U32(val), mir::Literal::U32(val) => ConstValueKind::U32(val),
mir::Literal::U64(val) => ConstValue::U64(val), mir::Literal::U64(val) => ConstValueKind::U64(val),
mir::Literal::U128(val) => ConstValue::U128(val), mir::Literal::U128(val) => ConstValueKind::U128(val),
mir::Literal::Bool(val) => ConstValue::Bool(val), mir::Literal::Bool(val) => ConstValueKind::Bool(val),
mir::Literal::String(val) => ConstValue::Str(val.clone()), mir::Literal::String(val) => ConstValueKind::Str(val.clone()),
mir::Literal::Vague(VagueLiteral::Number(val)) => ConstValue::I32(val as i32), mir::Literal::Vague(VagueLiteral::Number(val)) => ConstValueKind::I32(val as i32),
mir::Literal::Vague(VagueLiteral::Decimal(val)) => ConstValue::F32(val as f32), mir::Literal::Vague(VagueLiteral::Decimal(val)) => ConstValueKind::F32(val as f32),
mir::Literal::F16(val) => ConstValue::F16(val), mir::Literal::F16(val) => ConstValueKind::F16(val),
mir::Literal::F32B(val) => ConstValue::F32B(val), mir::Literal::F32B(val) => ConstValueKind::F32B(val),
mir::Literal::F32(val) => ConstValue::F32(val), mir::Literal::F32(val) => ConstValueKind::F32(val),
mir::Literal::F64(val) => ConstValue::F64(val), mir::Literal::F64(val) => ConstValueKind::F64(val),
mir::Literal::F80(val) => ConstValue::F80(val), mir::Literal::F80(val) => ConstValueKind::F80(val),
mir::Literal::F128(val) => ConstValue::F128(val), mir::Literal::F128(val) => ConstValueKind::F128(val),
mir::Literal::F128PPC(val) => ConstValue::F128PPC(val), mir::Literal::F128PPC(val) => ConstValueKind::F128PPC(val),
mir::Literal::Char(c) => ConstValue::U8(c as u8), mir::Literal::Char(c) => ConstValueKind::U8(c as u8),
}) })
} }
} }

View File

@ -82,7 +82,6 @@ impl mir::Statement {
impl mir::Expression { impl mir::Expression {
fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> PassResult { fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> PassResult {
dbg!("asd?");
match &mut self.0 { match &mut self.0 {
mir::ExprKind::FunctionCall(function_call) => { mir::ExprKind::FunctionCall(function_call) => {
if function_call.is_macro { if function_call.is_macro {