From a1f244834fdaf8baa153e7efe8663b76bdbd5049 Mon Sep 17 00:00:00 2001 From: David Mak Date: Wed, 18 Oct 2023 13:40:37 +0800 Subject: [PATCH] meta: Bringup some documentation --- nac3artiq/src/symbol_resolver.rs | 8 ++--- nac3core/src/codegen/generator.rs | 3 ++ nac3core/src/codegen/mod.rs | 59 ++++++++++++++++++++++++++++--- nac3core/src/symbol_resolver.rs | 12 +++++-- 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index a736732..31c9640 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -265,12 +265,12 @@ impl InnerResolver { Ok(Ok(ty)) } - /// handle python objects that represent types themselves + /// Handles python objects that represent types themselves, /// - /// primitives and class types should be themselves, use `ty_id` to check, - /// TypeVars and GenericAlias(`A[int, bool]`) should use `ty_ty_id` to check + /// Primitives and class types should be themselves, use `ty_id` to check; + /// TypeVars and GenericAlias(`A[int, bool]`) should use `ty_ty_id` to check. /// - /// the `bool` value returned indicates whether they are instantiated or not + /// The `bool` value returned indicates whether they are instantiated or not fn get_pyty_obj_type( &self, py: Python, diff --git a/nac3core/src/codegen/generator.rs b/nac3core/src/codegen/generator.rs index e7a43b7..ae92ab5 100644 --- a/nac3core/src/codegen/generator.rs +++ b/nac3core/src/codegen/generator.rs @@ -226,10 +226,13 @@ impl DefaultCodeGenerator { } impl CodeGenerator for DefaultCodeGenerator { + + /// Returns the name for this [CodeGenerator]. fn get_name(&self) -> &str { &self.name } + /// Returns an LLVM integer type representing `size_t`. fn get_size_type<'ctx>(&self, ctx: &'ctx Context) -> IntType<'ctx> { // it should be unsigned, but we don't really need unsigned and this could save us from // having to do a bit cast... diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index ae330c4..2f4aca5 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -126,42 +126,74 @@ impl CodeGenTargetMachineOptions { } pub struct CodeGenContext<'ctx, 'a> { + /// The LLVM context associated with [this context][CodeGenContext]. pub ctx: &'ctx Context, + + /// The [Builder] instance for creating LLVM IR statements. pub builder: Builder<'ctx>, /// The [DebugInfoBuilder], [compilation unit information][DICompileUnit], and /// [scope information][DIScope] of this context. pub debug_info: (DebugInfoBuilder<'ctx>, DICompileUnit<'ctx>, DIScope<'ctx>), + + /// The module for which [this context][CodeGenContext] is generating into. pub module: Module<'ctx>, + + /// The [TopLevelContext] associated with [this context][CodeGenContext]. pub top_level: &'a TopLevelContext, pub unifier: Unifier, pub resolver: Arc, pub static_value_store: Arc>, + + /// A [HashMap] containing the mapping between the names of variables currently in-scope and + /// its value information. pub var_assignment: HashMap>, + + /// pub type_cache: HashMap>, pub primitives: PrimitiveStore, pub calls: Arc>, pub registry: &'a WorkerRegistry, - // const string cache + + /// Cache for constant strings. pub const_strings: HashMap>, - // stores the alloca for variables + + /// [BasicBlock] containing all `alloca` statements for the current function. pub init_bb: BasicBlock<'ctx>, pub exception_val: Option>, + /// The header and exit basic blocks of a loop in this context. See /// https://llvm.org/docs/LoopTerminology.html for explanation of these terminology. pub loop_target: Option<(BasicBlock<'ctx>, BasicBlock<'ctx>)>, - // unwind target bb + + /// The target [BasicBlock] to jump to when performing stack unwind. pub unwind_target: Option>, - // return target bb, just emit ret if no such target + + /// The target [BasicBlock] to jump to before returning from the function. + /// + /// If this field is [None] when generating a return from a function, `ret` with no argument can + /// be emitted. pub return_target: Option>, + + /// The [PointerValue] containing the return value of the function. pub return_buffer: Option>, + // outer catch clauses pub outer_catch_clauses: Option<(Vec>>, BasicBlock<'ctx>, PhiValue<'ctx>)>, + + /// Whether `sret` is needed for the first parameter of the function. + /// + /// See [need_sret]. pub need_sret: bool, + + /// The current source location. pub current_loc: Location, } impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { + + /// 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(|bb| bb.get_terminator()).is_some() } @@ -186,17 +218,26 @@ impl WithCall { pub struct WorkerRegistry { sender: Arc>>, receiver: Arc>>, + + /// Whether any thread in this registry has panicked. panicked: AtomicBool, + + /// The total number of tasks queued or completed in the registry. task_count: Mutex, + + /// The number of threads available for this registry. thread_count: usize, wait_condvar: Condvar, top_level_ctx: Arc, static_value_store: Arc>, + /// LLVM-related options for code generation. llvm_options: CodeGenLLVMOptions, } impl WorkerRegistry { + + /// Creates workers for this registry. pub fn create_workers( generators: Vec>, top_level_ctx: Arc, @@ -278,11 +319,13 @@ impl WorkerRegistry { } } + /// Adds a task to this [WorkerRegistry]. pub fn add_task(&self, task: CodeGenTask) { *self.task_count.lock() += 1; self.sender.send(Some(task)).unwrap(); } + /// Function executed by worker thread for generating IR for each function. fn worker_thread(&self, generator: &mut G, f: Arc) { let context = Context::create(); let mut builder = context.create_builder(); @@ -502,6 +545,14 @@ fn get_llvm_abi_type<'ctx>( } } +/// Whether `sret` is needed for a return value with type `ty`. +/// +/// When returning a large data structure (e.g. structures that do not fit in 1-2 native words of +/// the target processor) by value, a synthetic parameter with a pointer type will be passed in the +/// slot of the first parameter to act as the location of which the return value is passed into. +/// +/// See [https://releases.llvm.org/14.0.0/docs/LangRef.html#parameter-attributes] for more +/// information. fn need_sret(ty: BasicTypeEnum) -> bool { fn need_sret_impl(ty: BasicTypeEnum, maybe_large: bool) -> bool { match ty { diff --git a/nac3core/src/symbol_resolver.rs b/nac3core/src/symbol_resolver.rs index 25a9a53..02e3fa6 100644 --- a/nac3core/src/symbol_resolver.rs +++ b/nac3core/src/symbol_resolver.rs @@ -205,6 +205,7 @@ pub trait StaticValue { /// Returns a unique identifier for this value. fn get_unique_identifier(&self) -> u64; + /// Returns the constant object represented by this unique identifier. fn get_const_obj<'ctx>( &self, ctx: &mut CodeGenContext<'ctx, '_>, @@ -232,7 +233,10 @@ pub trait StaticValue { #[derive(Clone)] pub enum ValueEnum<'ctx> { + /// [ValueEnum] representing a static value. Static(Arc), + + /// [ValueEnum] representing a dynamic value. Dynamic(BasicValueEnum<'ctx>), } @@ -267,6 +271,8 @@ impl<'ctx> From> for ValueEnum<'ctx> { } impl<'ctx> ValueEnum<'ctx> { + + /// Converts this [ValueEnum] to a [BasicValueEnum]. pub fn to_basic_value_enum<'a>( self, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -281,7 +287,7 @@ impl<'ctx> ValueEnum<'ctx> { } pub trait SymbolResolver { - // get type of type variable identifier or top-level function type + /// Get type of type variable identifier or top-level function type, fn get_symbol_type( &self, unifier: &mut Unifier, @@ -290,7 +296,7 @@ pub trait SymbolResolver { str: StrRef, ) -> Result; - // get the top-level definition of identifiers + /// Get the top-level definition of identifiers. fn get_identifier_def(&self, str: StrRef) -> Result; fn get_symbol_value<'ctx>( @@ -329,7 +335,7 @@ thread_local! { ]; } -// convert type annotation into type +/// Converts a type annotation into a [Type]. pub fn parse_type_annotation( resolver: &dyn SymbolResolver, top_level_defs: &[Arc>],