Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ either = { version = "1.17.0", default-features = false }
enable-ansi-support = { version = "0.3.1", default-features = false }
ena = { version = "0.14.4", default-features = false }
heck = "0.5.0"
inkwell = { version = "0.2.0", default-features = false }
inkwell = { version = "0.10.0", default-features = false }
insta = { version = "1.48.0", default-features = false }
itertools = { version = "0.15.0", default-features = false, features = ["use_alloc"] }
la-arena = { version = "0.3.1", default-features = false }
libloading = { version = "0.9.0", default-features = false, features = ["std"] }
lld_rs = { version = "140.0.0", default-features = false }
lld_rs = { git = "https://github.com/mun-lang/lld-rs", rev = "b16fcb8fcc0b6d7215b25a85f0c9bd743d90481a", default-features = false }
log = { version = "0.4.33", default-features = false }
lsp-server = { version = "0.10.0", default-features = false }
lsp-types = { version = "0.97.0", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion crates/mun_codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ arwen-codesign = { workspace = true }
by_address = { workspace = true }
mun_hir = { version = "0.6.0-dev", path = "../mun_hir" }
mun_hir_input = { version = "0.6.0-dev", path = "../mun_hir_input" }
inkwell = { workspace = true, features = ["llvm14-0", "target-x86", "target-aarch64"] }
inkwell = { workspace = true, features = ["llvm22-1-no-llvm-linking", "target-x86", "target-aarch64"] }
itertools = { workspace = true }
mun_target = { version = "0.6.0-dev", path = "../mun_target" }
lld_rs = { workspace = true }
Expand Down
28 changes: 16 additions & 12 deletions crates/mun_codegen/src/code_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ pub use assembly_builder::AssemblyBuilder;
pub use context::CodeGenContext;
pub use error::CodeGenerationError;
use inkwell::{
module::Module,
passes::{PassManager, PassManagerBuilder},
OptimizationLevel,
module::Module, passes::PassBuilderOptions, targets::TargetMachine, OptimizationLevel,
};
pub(crate) use object_file::ObjectFile;

Expand All @@ -14,13 +12,19 @@ mod error;
mod object_file;
pub mod symbols;

/// Optimizes the specified LLVM `Module` using the default passes for the given
/// `OptimizationLevel`.
fn optimize_module(module: &Module<'_>, optimization_lvl: OptimizationLevel) {
let pass_builder = PassManagerBuilder::create();
pass_builder.set_optimization_level(optimization_lvl);

let module_pass_manager = PassManager::create(());
pass_builder.populate_module_pass_manager(&module_pass_manager);
module_pass_manager.run_on(module);
/// Optimizes the specified LLVM `Module` using LLVM's default pipeline.
fn optimize_module(
module: &Module<'_>,
target_machine: &TargetMachine,
optimization_lvl: OptimizationLevel,
) {
let pipeline = match optimization_lvl {
OptimizationLevel::None => "default<O0>",
OptimizationLevel::Less => "default<O1>",
OptimizationLevel::Default => "default<O2>",
OptimizationLevel::Aggressive => "default<O3>",
};
module
.run_passes(pipeline, target_machine, PassBuilderOptions::create())
.expect("LLVM module optimization failed");
}
7 changes: 5 additions & 2 deletions crates/mun_codegen/src/code_gen/assembly_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,15 @@ impl<'db, 'ink, 'ctx, 't> AssemblyBuilder<'db, 'ink, 'ctx, 't> {
&group_ir.dispatch_table,
&group_ir.type_table,
&self.code_gen.hir_types,
self.code_gen.optimization_level,
dependencies,
);

// Optimize the assembly module
optimize_module(&self.assembly_module, self.code_gen.optimization_level);
optimize_module(
&self.assembly_module,
&self.code_gen.target_machine,
self.code_gen.optimization_level,
);

// Debug print the IR
//println!("{}", assembly_module.print_to_string().to_string());
Expand Down
79 changes: 39 additions & 40 deletions crates/mun_codegen/src/code_gen/symbols/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use mun_hir::{HirDatabase, TyKind};
use crate::{
ir::{
dispatch_table::{DispatchTable, DispatchableFunction},
function,
ty::{guid_from_struct, HirTypeCache},
type_table::TypeTable,
types::{self as ir, AbiBuilder},
Expand Down Expand Up @@ -171,7 +170,7 @@ fn gen_struct_info<'ink>(
let field_names = abi.types.private_pointer_array(
abi.module,
&format!("struct_info::<{name}>::field_names"),
abi.context.i8_type().ptr_type(AddressSpace::default()),
abi.context.ptr_type(AddressSpace::default()),
&field_names,
true,
);
Expand Down Expand Up @@ -239,7 +238,7 @@ fn get_function_definition_array<'ink, 'a>(
fn_ptr: value
.as_global_value()
.as_pointer_value()
.const_cast(abi.context.i8_type().ptr_type(AddressSpace::default())),
.const_cast(abi.context.ptr_type(AddressSpace::default())),
}
})
.collect();
Expand Down Expand Up @@ -274,7 +273,7 @@ fn gen_type_lut<'ink>(
)
})
.collect();
let byte_ptr = abi.context.i8_type().ptr_type(AddressSpace::default());
let byte_ptr = abi.context.ptr_type(AddressSpace::default());
let type_names = abi.types.private_pointer_array(
abi.module,
"fn.get_info.typeLut.typeNames",
Expand All @@ -283,7 +282,7 @@ fn gen_type_lut<'ink>(
false,
);

let pointer_table_type = byte_ptr.ptr_type(AddressSpace::default());
let pointer_table_type = abi.context.ptr_type(AddressSpace::default());
let type_ptrs = TypeTable::find_global(abi.module).map_or_else(
|| pointer_table_type.const_null(),
|global| global.as_pointer_value().const_cast(pointer_table_type),
Expand Down Expand Up @@ -313,8 +312,7 @@ fn gen_dispatch_table<'ink>(
&prototypes,
);

let byte_ptr = abi.context.i8_type().ptr_type(AddressSpace::default());
let pointer_table_type = byte_ptr.ptr_type(AddressSpace::default());
let pointer_table_type = abi.context.ptr_type(AddressSpace::default());
let fn_ptrs = dispatch_table.global_value().map_or_else(
|| pointer_table_type.const_null(),
|_| {
Expand Down Expand Up @@ -347,7 +345,6 @@ pub(super) fn gen_reflection_ir<'db, 'ink>(
dispatch_table: &DispatchTable<'ink>,
type_table: &TypeTable<'ink>,
hir_types: &HirTypeCache<'db, 'ink>,
optimization_level: inkwell::OptimizationLevel,
dependencies: Vec<String>,
) {
let type_ids = TypeIdBuilder::new(abi);
Expand All @@ -360,11 +357,9 @@ pub(super) fn gen_reflection_ir<'db, 'ink>(
hir_types,
&type_ids,
);
let functions = functions.as_pointer_value().const_cast(
abi.types
.function_definition_type()
.ptr_type(AddressSpace::default()),
);
let functions = functions
.as_pointer_value()
.const_cast(abi.context.ptr_type(AddressSpace::default()));

let module_info = ir::ModuleInfo {
path: abi.types.intern_c_str(
Expand All @@ -386,7 +381,6 @@ pub(super) fn gen_reflection_ir<'db, 'ink>(
&module_info,
&dispatch_table,
&type_lut,
optimization_level,
dependencies,
);
gen_set_allocator_handle_fn(abi);
Expand All @@ -399,7 +393,6 @@ fn gen_get_info_fn<'ink>(
module_info: &ir::ModuleInfo<'ink>,
dispatch_table: &ir::DispatchTable<'ink>,
type_lut: &ir::TypeLut<'ink>,
optimization_level: inkwell::OptimizationLevel,
dependencies: Vec<String>,
) {
let is_windows = db.target().options.is_like_windows;
Expand Down Expand Up @@ -429,7 +422,7 @@ fn gen_get_info_fn<'ink>(
)
})
.collect();
let byte_ptr = abi.context.i8_type().ptr_type(AddressSpace::default());
let byte_ptr = abi.context.ptr_type(AddressSpace::default());
let dependencies_ptr = abi.types.private_pointer_array(
abi.module,
"dependencies",
Expand All @@ -452,23 +445,25 @@ fn gen_get_info_fn<'ink>(
let body = abi.context.append_basic_block(function, "body");
builder.position_at_end(body);
if is_windows {
builder.build_store(
function
.get_nth_param(0)
.expect("sret function must receive a result pointer")
.into_pointer_value(),
assembly_info,
);
builder.build_return(None);
builder
.build_store(
function
.get_nth_param(0)
.expect("sret function must receive a result pointer")
.into_pointer_value(),
assembly_info,
)
.expect("valid store");
builder.build_return(None).expect("valid return");
} else {
builder.build_return(Some(&assembly_info));
builder
.build_return(Some(&assembly_info))
.expect("valid return");
}

function::create_pass_manager(abi.module, optimization_level).run_on(&function);
}

fn gen_set_allocator_handle_fn(abi: &AbiBuilder<'_, '_>) {
let pointer_type = abi.context.i8_type().ptr_type(AddressSpace::default());
let pointer_type = abi.context.ptr_type(AddressSpace::default());
let function_type = abi
.context
.void_type()
Expand All @@ -483,14 +478,16 @@ fn gen_set_allocator_handle_fn(abi: &AbiBuilder<'_, '_>) {
builder.position_at_end(body);

if let Some(global) = abi.module.get_global("allocatorHandle") {
builder.build_store(
global.as_pointer_value(),
function
.get_nth_param(0)
.expect("allocator setter must receive the allocator handle"),
);
builder
.build_store(
global.as_pointer_value(),
function
.get_nth_param(0)
.expect("allocator setter must receive the allocator handle"),
)
.expect("valid store");
}
builder.build_return(None);
builder.build_return(None).expect("valid return");
}

fn gen_get_version_fn(abi: &AbiBuilder<'_, '_>) {
Expand All @@ -503,9 +500,11 @@ fn gen_get_version_fn(abi: &AbiBuilder<'_, '_>) {
let builder = abi.context.create_builder();
let body = abi.context.append_basic_block(function, "body");
builder.position_at_end(body);
builder.build_return(Some(
&abi.context
.i32_type()
.const_int(u64::from(abi::ABI_VERSION), false),
));
builder
.build_return(Some(
&abi.context
.i32_type()
.const_int(u64::from(abi::ABI_VERSION), false),
))
.expect("valid return");
}
12 changes: 6 additions & 6 deletions crates/mun_codegen/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,26 +107,26 @@ pub trait IsPointerType<'ink> {
}

impl<'ink, S: BasicType<'ink>, T: IsIrType<'ink, Type = S>> IsPointerType<'ink> for *const T {
fn ir_type(context: &'ink Context, target: &TargetData) -> PointerType<'ink> {
T::ir_type(context, target).ptr_type(AddressSpace::default())
fn ir_type(context: &'ink Context, _target: &TargetData) -> PointerType<'ink> {
context.ptr_type(AddressSpace::default())
}
}

impl<'ink> IsPointerType<'ink> for *const std::ffi::c_void {
fn ir_type(context: &'ink Context, _target: &TargetData) -> PointerType<'ink> {
context.i8_type().ptr_type(AddressSpace::default())
context.ptr_type(AddressSpace::default())
}
}

impl<'ink> IsPointerType<'ink> for *mut std::ffi::c_void {
fn ir_type(context: &'ink Context, _target: &TargetData) -> PointerType<'ink> {
context.i8_type().ptr_type(AddressSpace::default())
context.ptr_type(AddressSpace::default())
}
}

impl<'ink, S: BasicType<'ink>, T: IsIrType<'ink, Type = S>> IsPointerType<'ink> for *mut T {
fn ir_type(context: &'ink Context, target: &TargetData) -> PointerType<'ink> {
T::ir_type(context, target).ptr_type(AddressSpace::default())
fn ir_type(context: &'ink Context, _target: &TargetData) -> PointerType<'ink> {
context.ptr_type(AddressSpace::default())
}
}

Expand Down
Loading