forked from M-Labs/nac3
meta: Bringup some documentation
This commit is contained in:
parent
d304afd333
commit
a1f244834f
|
@ -265,12 +265,12 @@ impl InnerResolver {
|
||||||
Ok(Ok(ty))
|
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,
|
/// 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
|
/// 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(
|
fn get_pyty_obj_type(
|
||||||
&self,
|
&self,
|
||||||
py: Python,
|
py: Python,
|
||||||
|
|
|
@ -226,10 +226,13 @@ impl DefaultCodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CodeGenerator for DefaultCodeGenerator {
|
impl CodeGenerator for DefaultCodeGenerator {
|
||||||
|
|
||||||
|
/// Returns the name for this [CodeGenerator].
|
||||||
fn get_name(&self) -> &str {
|
fn get_name(&self) -> &str {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an LLVM integer type representing `size_t`.
|
||||||
fn get_size_type<'ctx>(&self, ctx: &'ctx Context) -> IntType<'ctx> {
|
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
|
// it should be unsigned, but we don't really need unsigned and this could save us from
|
||||||
// having to do a bit cast...
|
// having to do a bit cast...
|
||||||
|
|
|
@ -126,42 +126,74 @@ impl CodeGenTargetMachineOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CodeGenContext<'ctx, 'a> {
|
pub struct CodeGenContext<'ctx, 'a> {
|
||||||
|
/// The LLVM context associated with [this context][CodeGenContext].
|
||||||
pub ctx: &'ctx Context,
|
pub ctx: &'ctx Context,
|
||||||
|
|
||||||
|
/// The [Builder] instance for creating LLVM IR statements.
|
||||||
pub builder: Builder<'ctx>,
|
pub builder: Builder<'ctx>,
|
||||||
/// The [DebugInfoBuilder], [compilation unit information][DICompileUnit], and
|
/// The [DebugInfoBuilder], [compilation unit information][DICompileUnit], and
|
||||||
/// [scope information][DIScope] of this context.
|
/// [scope information][DIScope] of this context.
|
||||||
pub debug_info: (DebugInfoBuilder<'ctx>, DICompileUnit<'ctx>, DIScope<'ctx>),
|
pub debug_info: (DebugInfoBuilder<'ctx>, DICompileUnit<'ctx>, DIScope<'ctx>),
|
||||||
|
|
||||||
|
/// The module for which [this context][CodeGenContext] is generating into.
|
||||||
pub module: Module<'ctx>,
|
pub module: Module<'ctx>,
|
||||||
|
|
||||||
|
/// The [TopLevelContext] associated with [this context][CodeGenContext].
|
||||||
pub top_level: &'a TopLevelContext,
|
pub top_level: &'a TopLevelContext,
|
||||||
pub unifier: Unifier,
|
pub unifier: Unifier,
|
||||||
pub resolver: Arc<dyn SymbolResolver + Send + Sync>,
|
pub resolver: Arc<dyn SymbolResolver + Send + Sync>,
|
||||||
pub static_value_store: Arc<Mutex<StaticValueStore>>,
|
pub static_value_store: Arc<Mutex<StaticValueStore>>,
|
||||||
|
|
||||||
|
/// A [HashMap] containing the mapping between the names of variables currently in-scope and
|
||||||
|
/// its value information.
|
||||||
pub var_assignment: HashMap<StrRef, VarValue<'ctx>>,
|
pub var_assignment: HashMap<StrRef, VarValue<'ctx>>,
|
||||||
|
|
||||||
|
///
|
||||||
pub type_cache: HashMap<Type, BasicTypeEnum<'ctx>>,
|
pub type_cache: HashMap<Type, BasicTypeEnum<'ctx>>,
|
||||||
pub primitives: PrimitiveStore,
|
pub primitives: PrimitiveStore,
|
||||||
pub calls: Arc<HashMap<CodeLocation, CallId>>,
|
pub calls: Arc<HashMap<CodeLocation, CallId>>,
|
||||||
pub registry: &'a WorkerRegistry,
|
pub registry: &'a WorkerRegistry,
|
||||||
// const string cache
|
|
||||||
|
/// Cache for constant strings.
|
||||||
pub const_strings: HashMap<String, BasicValueEnum<'ctx>>,
|
pub const_strings: HashMap<String, BasicValueEnum<'ctx>>,
|
||||||
// stores the alloca for variables
|
|
||||||
|
/// [BasicBlock] containing all `alloca` statements for the current function.
|
||||||
pub init_bb: BasicBlock<'ctx>,
|
pub init_bb: BasicBlock<'ctx>,
|
||||||
pub exception_val: Option<PointerValue<'ctx>>,
|
pub exception_val: Option<PointerValue<'ctx>>,
|
||||||
|
|
||||||
/// The header and exit basic blocks of a loop in this context. See
|
/// The header and exit basic blocks of a loop in this context. See
|
||||||
/// https://llvm.org/docs/LoopTerminology.html for explanation of these terminology.
|
/// https://llvm.org/docs/LoopTerminology.html for explanation of these terminology.
|
||||||
pub loop_target: Option<(BasicBlock<'ctx>, BasicBlock<'ctx>)>,
|
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<BasicBlock<'ctx>>,
|
pub unwind_target: Option<BasicBlock<'ctx>>,
|
||||||
// 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<BasicBlock<'ctx>>,
|
pub return_target: Option<BasicBlock<'ctx>>,
|
||||||
|
|
||||||
|
/// The [PointerValue] containing the return value of the function.
|
||||||
pub return_buffer: Option<PointerValue<'ctx>>,
|
pub return_buffer: Option<PointerValue<'ctx>>,
|
||||||
|
|
||||||
// outer catch clauses
|
// outer catch clauses
|
||||||
pub outer_catch_clauses:
|
pub outer_catch_clauses:
|
||||||
Option<(Vec<Option<BasicValueEnum<'ctx>>>, BasicBlock<'ctx>, PhiValue<'ctx>)>,
|
Option<(Vec<Option<BasicValueEnum<'ctx>>>, BasicBlock<'ctx>, PhiValue<'ctx>)>,
|
||||||
|
|
||||||
|
/// Whether `sret` is needed for the first parameter of the function.
|
||||||
|
///
|
||||||
|
/// See [need_sret].
|
||||||
pub need_sret: bool,
|
pub need_sret: bool,
|
||||||
|
|
||||||
|
/// The current source location.
|
||||||
pub current_loc: Location,
|
pub current_loc: Location,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
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 {
|
pub fn is_terminated(&self) -> bool {
|
||||||
self.builder.get_insert_block().and_then(|bb| bb.get_terminator()).is_some()
|
self.builder.get_insert_block().and_then(|bb| bb.get_terminator()).is_some()
|
||||||
}
|
}
|
||||||
|
@ -186,17 +218,26 @@ impl WithCall {
|
||||||
pub struct WorkerRegistry {
|
pub struct WorkerRegistry {
|
||||||
sender: Arc<Sender<Option<CodeGenTask>>>,
|
sender: Arc<Sender<Option<CodeGenTask>>>,
|
||||||
receiver: Arc<Receiver<Option<CodeGenTask>>>,
|
receiver: Arc<Receiver<Option<CodeGenTask>>>,
|
||||||
|
|
||||||
|
/// Whether any thread in this registry has panicked.
|
||||||
panicked: AtomicBool,
|
panicked: AtomicBool,
|
||||||
|
|
||||||
|
/// The total number of tasks queued or completed in the registry.
|
||||||
task_count: Mutex<usize>,
|
task_count: Mutex<usize>,
|
||||||
|
|
||||||
|
/// The number of threads available for this registry.
|
||||||
thread_count: usize,
|
thread_count: usize,
|
||||||
wait_condvar: Condvar,
|
wait_condvar: Condvar,
|
||||||
top_level_ctx: Arc<TopLevelContext>,
|
top_level_ctx: Arc<TopLevelContext>,
|
||||||
static_value_store: Arc<Mutex<StaticValueStore>>,
|
static_value_store: Arc<Mutex<StaticValueStore>>,
|
||||||
|
|
||||||
/// LLVM-related options for code generation.
|
/// LLVM-related options for code generation.
|
||||||
llvm_options: CodeGenLLVMOptions,
|
llvm_options: CodeGenLLVMOptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorkerRegistry {
|
impl WorkerRegistry {
|
||||||
|
|
||||||
|
/// Creates workers for this registry.
|
||||||
pub fn create_workers<G: CodeGenerator + Send + 'static>(
|
pub fn create_workers<G: CodeGenerator + Send + 'static>(
|
||||||
generators: Vec<Box<G>>,
|
generators: Vec<Box<G>>,
|
||||||
top_level_ctx: Arc<TopLevelContext>,
|
top_level_ctx: Arc<TopLevelContext>,
|
||||||
|
@ -278,11 +319,13 @@ impl WorkerRegistry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a task to this [WorkerRegistry].
|
||||||
pub fn add_task(&self, task: CodeGenTask) {
|
pub fn add_task(&self, task: CodeGenTask) {
|
||||||
*self.task_count.lock() += 1;
|
*self.task_count.lock() += 1;
|
||||||
self.sender.send(Some(task)).unwrap();
|
self.sender.send(Some(task)).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Function executed by worker thread for generating IR for each function.
|
||||||
fn worker_thread<G: CodeGenerator>(&self, generator: &mut G, f: Arc<WithCall>) {
|
fn worker_thread<G: CodeGenerator>(&self, generator: &mut G, f: Arc<WithCall>) {
|
||||||
let context = Context::create();
|
let context = Context::create();
|
||||||
let mut builder = context.create_builder();
|
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(ty: BasicTypeEnum) -> bool {
|
||||||
fn need_sret_impl(ty: BasicTypeEnum, maybe_large: bool) -> bool {
|
fn need_sret_impl(ty: BasicTypeEnum, maybe_large: bool) -> bool {
|
||||||
match ty {
|
match ty {
|
||||||
|
|
|
@ -205,6 +205,7 @@ pub trait StaticValue {
|
||||||
/// Returns a unique identifier for this value.
|
/// Returns a unique identifier for this value.
|
||||||
fn get_unique_identifier(&self) -> u64;
|
fn get_unique_identifier(&self) -> u64;
|
||||||
|
|
||||||
|
/// Returns the constant object represented by this unique identifier.
|
||||||
fn get_const_obj<'ctx>(
|
fn get_const_obj<'ctx>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
@ -232,7 +233,10 @@ pub trait StaticValue {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum ValueEnum<'ctx> {
|
pub enum ValueEnum<'ctx> {
|
||||||
|
/// [ValueEnum] representing a static value.
|
||||||
Static(Arc<dyn StaticValue + Send + Sync>),
|
Static(Arc<dyn StaticValue + Send + Sync>),
|
||||||
|
|
||||||
|
/// [ValueEnum] representing a dynamic value.
|
||||||
Dynamic(BasicValueEnum<'ctx>),
|
Dynamic(BasicValueEnum<'ctx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,6 +271,8 @@ impl<'ctx> From<StructValue<'ctx>> for ValueEnum<'ctx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> ValueEnum<'ctx> {
|
impl<'ctx> ValueEnum<'ctx> {
|
||||||
|
|
||||||
|
/// Converts this [ValueEnum] to a [BasicValueEnum].
|
||||||
pub fn to_basic_value_enum<'a>(
|
pub fn to_basic_value_enum<'a>(
|
||||||
self,
|
self,
|
||||||
ctx: &mut CodeGenContext<'ctx, 'a>,
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
|
@ -281,7 +287,7 @@ impl<'ctx> ValueEnum<'ctx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SymbolResolver {
|
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(
|
fn get_symbol_type(
|
||||||
&self,
|
&self,
|
||||||
unifier: &mut Unifier,
|
unifier: &mut Unifier,
|
||||||
|
@ -290,7 +296,7 @@ pub trait SymbolResolver {
|
||||||
str: StrRef,
|
str: StrRef,
|
||||||
) -> Result<Type, String>;
|
) -> Result<Type, String>;
|
||||||
|
|
||||||
// get the top-level definition of identifiers
|
/// Get the top-level definition of identifiers.
|
||||||
fn get_identifier_def(&self, str: StrRef) -> Result<DefinitionId, String>;
|
fn get_identifier_def(&self, str: StrRef) -> Result<DefinitionId, String>;
|
||||||
|
|
||||||
fn get_symbol_value<'ctx>(
|
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<T>(
|
pub fn parse_type_annotation<T>(
|
||||||
resolver: &dyn SymbolResolver,
|
resolver: &dyn SymbolResolver,
|
||||||
top_level_defs: &[Arc<RwLock<TopLevelDef>>],
|
top_level_defs: &[Arc<RwLock<TopLevelDef>>],
|
||||||
|
|
Loading…
Reference in New Issue