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() {
use ConstValue::*;
use ConstValueKind::*;
use Instr::*;
let context = Context::new("libtest");

View File

@ -4,8 +4,8 @@
use std::{cell::RefCell, rc::Rc};
use crate::{
Block, BlockData, CompileResult, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData, ModuleData,
NamedStruct, TerminatorKind, Type, TypeCategory, TypeData,
Block, BlockData, CompileResult, ConstValueKind, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData,
ModuleData, NamedStruct, TerminatorKind, Type, TypeCategory, TypeData,
debug_information::{
DebugInformation, DebugLocationValue, DebugMetadataValue, DebugScopeValue, InstructionDebugRecordData,
},
@ -27,6 +27,12 @@ pub struct BlockValue(pub(crate) FunctionValue, pub(crate) usize);
#[derive(Clone, Hash, Copy, PartialEq, Eq)]
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)]
pub struct ModuleHolder {
pub(crate) value: ModuleValue,
@ -34,6 +40,20 @@ pub struct ModuleHolder {
pub(crate) functions: Vec<FunctionHolder>,
pub(crate) types: Vec<TypeHolder>,
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)]
@ -88,6 +108,8 @@ impl Builder {
functions: Vec::new(),
types: Vec::new(),
debug_information: None,
constants: Vec::new(),
globals: Vec::new(),
});
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> {
unsafe {
let mut modules = self.modules.borrow_mut();

View File

@ -33,7 +33,7 @@ use crate::{
};
use super::{
CmpPredicate, ConstValue, Context, TerminatorKind, Type,
CmpPredicate, ConstValueKind, Context, TerminatorKind, Type,
builder::{
BlockHolder, BlockValue, Builder, FunctionHolder, FunctionValue, InstructionHolder, InstructionValue,
ModuleHolder,
@ -1144,32 +1144,32 @@ impl CmpPredicate {
}
}
impl ConstValue {
impl ConstValueKind {
fn as_llvm(&self, module: &LLVMModule) -> LLVMValueRef {
unsafe {
let t = self.get_type().as_llvm(module.context_ref, &module.types);
match self {
ConstValue::Bool(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::I8(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::I16(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::I32(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::I64(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::I128(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U8(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U16(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U32(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U64(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::U128(val) => LLVMConstInt(t, *val as u64, 1),
ConstValue::Str(val) => {
ConstValueKind::Bool(val) => LLVMConstInt(t, *val as u64, 1),
ConstValueKind::I8(val) => LLVMConstInt(t, *val as u64, 1),
ConstValueKind::I16(val) => LLVMConstInt(t, *val as u64, 1),
ConstValueKind::I32(val) => LLVMConstInt(t, *val as u64, 1),
ConstValueKind::I64(val) => LLVMConstInt(t, *val as u64, 1),
ConstValueKind::I128(val) => LLVMConstInt(t, *val as u64, 1),
ConstValueKind::U8(val) => LLVMConstInt(t, *val as u64, 1),
ConstValueKind::U16(val) => LLVMConstInt(t, *val as u64, 1),
ConstValueKind::U32(val) => LLVMConstInt(t, *val as u64, 1),
ConstValueKind::U64(val) => LLVMConstInt(t, *val as u64, 1),
ConstValueKind::U128(val) => LLVMConstInt(t, *val as u64, 1),
ConstValueKind::Str(val) => {
LLVMBuildGlobalString(module.builder_ref, into_cstring(val).as_ptr(), c"string".as_ptr())
}
ConstValue::F16(val) => LLVMConstReal(t, *val as f64),
ConstValue::F32B(val) => LLVMConstReal(t, *val as f64),
ConstValue::F32(val) => LLVMConstReal(t, *val as f64),
ConstValue::F64(val) => LLVMConstReal(t, *val as f64),
ConstValue::F80(val) => LLVMConstReal(t, *val as f64),
ConstValue::F128(val) => LLVMConstReal(t, *val as f64),
ConstValue::F128PPC(val) => LLVMConstReal(t, *val as f64),
ConstValueKind::F16(val) => LLVMConstReal(t, *val as f64),
ConstValueKind::F32B(val) => LLVMConstReal(t, *val as f64),
ConstValueKind::F32(val) => LLVMConstReal(t, *val as f64),
ConstValueKind::F64(val) => LLVMConstReal(t, *val as f64),
ConstValueKind::F80(val) => LLVMConstReal(t, *val as f64),
ConstValueKind::F128(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 fmt::PrintableModule;
use crate::debug_information::DebugScopeValue;
use crate::{
builder::{ConstantValue, GlobalValue},
debug_information::DebugScopeValue,
};
pub mod builder;
pub mod compile;
@ -121,6 +124,14 @@ impl<'ctx> Module<'ctx> {
pub fn get_debug_info(&self) -> &Option<DebugInformation> {
&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> {
@ -361,7 +372,7 @@ pub enum CmpPredicate {
#[derive(Clone)]
pub enum Instr {
Param(usize),
Constant(ConstValue),
Constant(ConstValueKind),
/// Add two integers
Add(InstructionValue, InstructionValue),
@ -487,7 +498,7 @@ pub enum Type {
}
#[derive(Debug, Clone)]
pub enum ConstValue {
pub enum ConstValueKind {
I8(i8),
I16(i16),
I32(i32),
@ -531,29 +542,29 @@ pub enum CustomTypeKind {
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct NamedStruct(pub String, pub Vec<Type>);
impl ConstValue {
impl ConstValueKind {
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::Str(_) => Type::Ptr(Box::new(U8)),
ConstValue::Bool(_) => Bool,
ConstValue::F16(_) => F16,
ConstValue::F32B(_) => F32B,
ConstValue::F32(_) => F32,
ConstValue::F64(_) => F64,
ConstValue::F80(_) => F80,
ConstValue::F128(_) => F128,
ConstValue::F128PPC(_) => F128PPC,
ConstValueKind::I8(_) => I8,
ConstValueKind::I16(_) => I16,
ConstValueKind::I32(_) => I32,
ConstValueKind::I64(_) => I64,
ConstValueKind::I128(_) => I128,
ConstValueKind::U8(_) => U8,
ConstValueKind::U16(_) => U16,
ConstValueKind::U32(_) => U32,
ConstValueKind::U64(_) => U64,
ConstValueKind::U128(_) => U128,
ConstValueKind::Str(_) => Type::Ptr(Box::new(U8)),
ConstValueKind::Bool(_) => Bool,
ConstValueKind::F16(_) => F16,
ConstValueKind::F32B(_) => F32B,
ConstValueKind::F32(_) => F32,
ConstValueKind::F64(_) => F64,
ConstValueKind::F80(_) => F80,
ConstValueKind::F128(_) => F128,
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::{
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> {
let instr = scope
.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();
Ok(StackValue(StackValueKind::Literal(instr), self.0.clone()))
}
@ -382,7 +382,7 @@ impl IntrinsicFunction for IntrinsicMalloc {
let sizeof = scope
.block
.build(Instr::Constant(ConstValue::U64(self.0.size_of() / 8)))
.build(Instr::Constant(ConstValueKind::U64(self.0.size_of() / 8)))
.unwrap();
let bytes = scope.block.build(Instr::Mul(sizeof, amount.instr())).unwrap();
let instr = scope.block.build(Instr::FunctionCall(function, vec![bytes])).unwrap();
@ -394,7 +394,7 @@ impl IntrinsicFunction for IntrinsicMalloc {
pub struct IntrinsicNullPtr(TypeKind);
impl IntrinsicFunction for IntrinsicNullPtr {
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
.block
.build(Instr::IntToPtr(

View File

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

View File

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

View File

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