From f8530e0ef694c7d8ac7690ecd9eab838b5d59831 Mon Sep 17 00:00:00 2001 From: David Mak Date: Mon, 13 Jan 2025 20:26:15 +0800 Subject: [PATCH] [core] codegen: Add CodeGenContext::get_size_type Convenience method for getting the `size_t` LLVM type without the use of `CodeGenerator`. --- nac3core/src/codegen/generator.rs | 3 +++ nac3core/src/codegen/mod.rs | 25 +++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/nac3core/src/codegen/generator.rs b/nac3core/src/codegen/generator.rs index a416f10a..620ede0e 100644 --- a/nac3core/src/codegen/generator.rs +++ b/nac3core/src/codegen/generator.rs @@ -19,6 +19,9 @@ pub trait CodeGenerator { fn get_name(&self) -> &str; /// Return an instance of [`IntType`] corresponding to the type of `size_t` for this instance. + /// + /// Prefer using [`CodeGenContext::get_size_type`] if [`CodeGenContext`] is available, as it is + /// equivalent to this function in a more concise syntax. fn get_size_type<'ctx>(&self, ctx: &'ctx Context) -> IntType<'ctx>; /// Generate function call and returns the function return value. diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index 28b9a654..797a62be 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -1,4 +1,5 @@ use std::{ + cell::OnceCell, collections::{HashMap, HashSet}, sync::{ atomic::{AtomicBool, Ordering}, @@ -19,7 +20,7 @@ use inkwell::{ module::Module, passes::PassBuilderOptions, targets::{CodeModel, RelocMode, Target, TargetMachine, TargetTriple}, - types::{AnyType, BasicType, BasicTypeEnum}, + types::{AnyType, BasicType, BasicTypeEnum, IntType}, values::{BasicValueEnum, FunctionValue, IntValue, PhiValue, PointerValue}, AddressSpace, IntPredicate, OptimizationLevel, }; @@ -226,14 +227,33 @@ pub struct CodeGenContext<'ctx, 'a> { /// The current source location. pub current_loc: Location, + + /// The cached type of `size_t`. + llvm_usize: OnceCell>, } -impl CodeGenContext<'_, '_> { +impl<'ctx> CodeGenContext<'ctx, '_> { /// Whether the [current basic block][Builder::get_insert_block] referenced by `builder` /// contains a [terminator statement][BasicBlock::get_terminator]. pub fn is_terminated(&self) -> bool { self.builder.get_insert_block().and_then(BasicBlock::get_terminator).is_some() } + + /// Returns a [`IntType`] representing `size_t` for the compilation target as specified by + /// [`self.registry`][WorkerRegistry]. + pub fn get_size_type(&self) -> IntType<'ctx> { + *self.llvm_usize.get_or_init(|| { + self.ctx.ptr_sized_int_type( + &self + .registry + .llvm_options + .create_target_machine() + .map(|tm| tm.get_target_data()) + .unwrap(), + None, + ) + }) + } } type Fp = Box; @@ -987,6 +1007,7 @@ pub fn gen_func_impl< need_sret: has_sret, current_loc: Location::default(), debug_info: (dibuilder, compile_unit, func_scope.as_debug_info_scope()), + llvm_usize: OnceCell::default(), }; let target_llvm_usize = context.ptr_sized_int_type(