Skip to content

Commit 4335cf7

Browse files
committed
Merge pull request #1106 from hash-org/vm-main
2 parents dcfd6c0 + ba89f82 commit 4335cf7

53 files changed

Lines changed: 1283 additions & 631 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@
1313

1414
# Example files that shouldn't be kept in sources
1515
examples/
16+
branch_structure.json
17+
temp_auto_push.bat
18+
temp_interactive_push.bat

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/hash-abi/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! and to be able to call functions from other languages, but to also provide
44
//! information to code generation backends about how values are represented.
55
6+
use hash_ir::ty::ReprTyId;
67
use hash_repr::{LayoutId, TyInfo};
78
use hash_storage::{new_store_key, store::statics::StoreId};
89
use hash_target::{
@@ -51,6 +52,9 @@ new_store_key!(pub FnAbiId, derives = Debug);
5152
/// them)?
5253
#[derive(Debug, Clone)]
5354
pub struct FnAbi {
55+
/// The ID of the function ABI if any.
56+
pub ty: ReprTyId,
57+
5458
/// All the types of the arguments in order, and how they should
5559
/// be passed to the function (as per convention).
5660
pub args: Box<[ArgAbi]>,

compiler/hash-codegen-llvm/src/ctx.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ use hash_codegen::{
1010
target::{HasTarget, Target},
1111
traits::{BackendTypes, HasCtxMethods},
1212
};
13-
use hash_ir::{
14-
IrCtx,
15-
ty::{InstanceId, ReprTyId, VariantIdx},
16-
};
13+
use hash_ir::{IrCtx, ty::ReprTyId};
1714
use hash_pipeline::settings::CompilerSettings;
1815
use hash_source::constant::AllocId;
1916
use hash_utils::fxhash::FxHashMap;
@@ -24,8 +21,6 @@ use llvm::{
2421
values::FunctionValue,
2522
};
2623

27-
use crate::translation::ty::TyMemoryRemap;
28-
2924
/// The [CodeGenCtx] is used a context for converting Hash IR into LLVM IR. It
3025
/// stores references to all of the required information about the IR, as well
3126
/// as several stores in order to reduce the amount of work that is required to
@@ -59,15 +54,9 @@ pub struct CodeGenCtx<'b, 'm> {
5954
/// of pointers and pointer offsets.
6055
pub size_ty: llvm::types::IntType<'m>,
6156

62-
/// A mapping between [InstanceId]s to [FunctionValue]s in order
57+
/// A mapping between [ReprTyId]s to [FunctionValue]s in order
6358
/// to avoid re-generating declaring instance references.
64-
pub(crate) instances: RefCell<FxHashMap<InstanceId, llvm::values::FunctionValue<'m>>>,
65-
66-
/// A collection of [TyMemoryRemap]s that have occurred for
67-
/// all of the types that have been translated. Additionally, this is used
68-
/// as a cache to avoid re-lowering [ReprTyId]s into the equivalent
69-
/// LLVM types.
70-
pub(crate) ty_remaps: RefCell<FxHashMap<(ReprTyId, Option<VariantIdx>), TyMemoryRemap<'m>>>,
59+
pub(crate) instances: RefCell<FxHashMap<ReprTyId, llvm::values::FunctionValue<'m>>>,
7160

7261
/// A map which stores the created [AnyValueEnum]s for the constant
7362
/// strings [InternedStr] that have been created.
@@ -111,7 +100,6 @@ impl<'b, 'm> CodeGenCtx<'b, 'm> {
111100
symbol_counter: Cell::new(0),
112101
size_ty,
113102
instances: RefCell::new(FxHashMap::default()),
114-
ty_remaps: RefCell::new(FxHashMap::default()),
115103
str_consts: RefCell::new(FxHashMap::default()),
116104
global_consts: RefCell::new(FxHashMap::default()),
117105
intrinsics: RefCell::new(FxHashMap::default()),

compiler/hash-codegen-llvm/src/lib.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,16 @@ impl<'b, 'm> LLVMBackend<'b> {
223223
}
224224

225225
// Get the instance of the function.
226-
let instance = body.metadata().ty().borrow().as_instance();
226+
let ty = body.metadata().ty();
227+
let instance = ty.borrow().as_instance();
227228

228229
// So, we create the mangled symbol name, and then call `predefine()` which
229230
// should create the function ABI from the instance, with the correct
230231
// attributes and linkage, etc.
231232
let symbol_name = compute_symbol_name(instance);
232233

233234
let abis = self.codegen_storage.abis();
234-
let abi = abis.create_fn_abi_from_instance(ctx, instance);
235+
let abi = abis.create_fn_abi_from_ty(ctx, ty);
235236

236237
abis.map_fast(abi, |abi| {
237238
ctx.predefine_fn(instance, symbol_name.as_str(), abi);
@@ -252,19 +253,19 @@ impl<'b, 'm> LLVMBackend<'b> {
252253
continue;
253254
}
254255

255-
// Get the instance of the function.
256-
let instance = body.metadata().ty().borrow().as_instance();
257-
258256
// @@ErrorHandling: we should be able to handle the error here
259-
codegen_body::<LLVMBuilder>(instance, body, ctx).unwrap();
257+
codegen_body::<LLVMBuilder>(body, ctx).unwrap();
260258

261259
// Check if we should dump the generated LLVM IR
260+
let ty = body.metadata().ty();
261+
let instance = ty.borrow().as_instance();
262+
262263
if instance.borrow().has_attr(attrs::DUMP_LLVM_IR) {
263-
// @@Messaging
264+
// @@Messaging§
264265
log::info!(
265266
"LLVM IR for function {}\n{}",
266267
body.meta.name(),
267-
ctx.get_fn(instance).print_to_string().to_string()
268+
ctx.get_fn(ty).print_to_string().to_string()
268269
);
269270
}
270271
}
Lines changed: 3 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
//! Implements all of the required methods for computing the layouts of types.
22
33
use hash_codegen::{
4-
repr::{Layout, LayoutShape, TyInfo, Variants},
4+
repr::{Layout, TyInfo},
55
target::abi::AbiRepresentation,
66
traits::layout::LayoutMethods,
77
};
8-
use hash_ir::ty::ReprTyId;
98
use hash_storage::store::statics::StoreId;
109

11-
use super::{LLVMBuilder, ty::TyMemoryRemap};
10+
use super::LLVMBuilder;
1211
use crate::ctx::CodeGenCtx;
1312

1413
impl<'b> LayoutMethods<'b> for CodeGenCtx<'b, '_> {
15-
fn backend_field_index(&self, info: TyInfo, index: usize) -> u64 {
16-
info.layout.map(|layout| layout.llvm_field_index(self, info.ty, index))
17-
}
18-
1914
fn is_backend_immediate(&self, info: TyInfo) -> bool {
2015
info.layout.map(|layout| layout.is_llvm_immediate())
2116
}
@@ -26,10 +21,6 @@ impl<'b> LayoutMethods<'b> for CodeGenCtx<'b, '_> {
2621
}
2722

2823
impl<'b> LayoutMethods<'b> for LLVMBuilder<'_, 'b, '_> {
29-
fn backend_field_index(&self, info: TyInfo, index: usize) -> u64 {
30-
self.ctx.backend_field_index(info, index)
31-
}
32-
3324
fn is_backend_immediate(&self, ty: TyInfo) -> bool {
3425
self.ctx.is_backend_immediate(ty)
3526
}
@@ -40,14 +31,11 @@ impl<'b> LayoutMethods<'b> for LLVMBuilder<'_, 'b, '_> {
4031
}
4132

4233
pub trait ExtendedLayoutMethods<'m> {
43-
/// Compute the field index from the backend specific type.
44-
fn llvm_field_index(&self, cx: &CodeGenCtx<'_, 'm>, ty: ReprTyId, index: usize) -> u64;
45-
4634
/// Check if this is type is represented as an immediate value.
4735
fn is_llvm_immediate(&self) -> bool;
4836

4937
/// Returns true if this [Layout] ABI is represented as is a
50-
/// [`AbiRepresentation::Pair(..)`]
38+
/// [`AbiRepresentation::Pair`]
5139
fn is_llvm_scalar_pair(&self) -> bool;
5240
}
5341

@@ -63,40 +51,4 @@ impl<'m> ExtendedLayoutMethods<'m> for &Layout {
6351
fn is_llvm_scalar_pair(&self) -> bool {
6452
matches!(self.abi, AbiRepresentation::Pair(..))
6553
}
66-
67-
fn llvm_field_index(&self, ctx: &CodeGenCtx<'_, 'm>, ty: ReprTyId, index: usize) -> u64 {
68-
// Field index of scalar and scalar pairs is not applicable since
69-
// it is handled else where.
70-
match self.abi {
71-
AbiRepresentation::Scalar(_) | AbiRepresentation::Pair(..) => {
72-
panic!("cannot get field index of scalar or scalar pair")
73-
}
74-
_ => {}
75-
};
76-
77-
match self.shape {
78-
LayoutShape::Primitive | LayoutShape::Union { .. } => {
79-
panic!("cannot get field index of primitive or union")
80-
}
81-
LayoutShape::Array { .. } => index as u64,
82-
83-
// Here, we have to rely on the re-mapped version of the layout since
84-
// we had to adjust it to account for all of the padding that was added
85-
// to the struct/aggregate.
86-
LayoutShape::Aggregate { .. } => {
87-
let variant_index = match self.variants {
88-
Variants::Single { index } => Some(index),
89-
Variants::Multiple { .. } => None,
90-
};
91-
92-
match ctx.ty_remaps.borrow().get(&(ty, variant_index)) {
93-
Some(TyMemoryRemap { remap: Some(remap), .. }) => remap[index] as u64,
94-
Some(TyMemoryRemap { remap: None, .. }) => {
95-
self.shape.memory_index(index) as u64
96-
}
97-
None => panic!("cannot find remapped layout for `{}`", ty),
98-
}
99-
}
100-
}
101-
}
10254
}

compiler/hash-codegen-llvm/src/translation/misc.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use hash_codegen::{
77
target::HasTarget,
88
traits::{HasCtxMethods, misc::MiscBuilderMethods, ty::TypeBuilderMethods},
99
};
10-
use hash_ir::ty::{InstanceHelpers, InstanceId};
10+
use hash_ir::ty::{InstanceHelpers, InstanceId, ReprTyId};
1111
use hash_storage::store::{Store, statics::StoreId};
1212
use inkwell::{
1313
GlobalVisibility,
@@ -20,19 +20,20 @@ use crate::ctx::CodeGenCtx;
2020

2121
impl<'m> CodeGenCtx<'_, 'm> {
2222
/// Generate code for a reference to a function or method item. The
23-
/// [Instance] specifies the function reference to generate, and any
23+
/// [InstanceId] specifies the function reference to generate, and any
2424
/// attributes that need to be applied to the function. If the function
2525
/// has already been generated, a reference will be returned from the
2626
/// cache.
27-
pub fn get_fn_or_create_ref(&self, instance: InstanceId) -> FunctionValue<'m> {
27+
pub fn get_fn_or_create_ref(&self, ty: ReprTyId) -> FunctionValue<'m> {
2828
// First check if we have already created the function reference...
29-
if let Some(fn_val) = self.instances.borrow().get(&instance) {
29+
if let Some(fn_val) = self.instances.borrow().get(&ty) {
3030
return *fn_val;
3131
}
3232

33+
let instance = ty.borrow().as_instance();
3334
let name = compute_symbol_name(instance);
3435
let abis = self.cg_ctx().abis();
35-
let fn_abi = abis.create_fn_abi_from_instance(self, instance);
36+
let fn_abi = abis.create_fn_abi_from_ty(self, ty);
3637

3738
// See if this item has already been declared in the module
3839
let func = if let Some(func) = self.module.get_function(name.as_str()) {
@@ -55,25 +56,25 @@ impl<'m> CodeGenCtx<'_, 'm> {
5556

5657
// We insert the function into the cache so that we can
5758
// reference it later on...
58-
self.instances.borrow_mut().insert(instance, func);
59+
self.instances.borrow_mut().insert(ty, func);
5960

6061
func
6162
}
6263
}
6364

6465
impl<'b> MiscBuilderMethods<'b> for CodeGenCtx<'b, '_> {
65-
fn get_fn(&self, instance: InstanceId) -> Self::Function {
66-
self.get_fn_or_create_ref(instance)
66+
fn get_fn(&self, ty: ReprTyId) -> Self::Function {
67+
self.get_fn_or_create_ref(ty)
6768
}
6869

69-
fn get_fn_ptr(&self, instance: InstanceId) -> Self::Value {
70-
self.get_fn_or_create_ref(instance).as_any_value_enum()
70+
fn get_fn_ptr(&self, ty: ReprTyId) -> Self::Value {
71+
self.get_fn_or_create_ref(ty).as_any_value_enum()
7172
}
7273

73-
fn get_fn_addr(&self, instance: InstanceId) -> Self::Value {
74+
fn get_fn_addr(&self, ty: ReprTyId) -> Self::Value {
7475
// @@Inkwell: PointerValue(..).as_any_value_enum() is bugged
7576
AnyValueEnum::PointerValue(
76-
self.get_fn_or_create_ref(instance).as_global_value().as_pointer_value(),
77+
self.get_fn_or_create_ref(ty).as_global_value().as_pointer_value(),
7778
)
7879
}
7980

@@ -117,6 +118,6 @@ impl<'b> MiscBuilderMethods<'b> for CodeGenCtx<'b, '_> {
117118

118119
// We insert the function into the cache so that we can
119120
// reference it later on...
120-
self.instances.borrow_mut().insert(instance, decl);
121+
self.instances.borrow_mut().insert(fn_abi.ty, decl);
121122
}
122123
}

compiler/hash-codegen-llvm/src/translation/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub(crate) const EMPTY_NAME: *const c_char = EMPTY_C_STR.as_ptr();
3737
/// A [Builder] is defined as being a context that is used to implement
3838
/// all of the specified builder methods.
3939
pub struct LLVMBuilder<'a, 'b, 'm> {
40-
/// The actual InkWell builder
40+
/// The actual Inkwell builder.
4141
pub(crate) builder: inkwell::builder::Builder<'m>,
4242

4343
/// The context for the builder.

compiler/hash-codegen-llvm/src/translation/ty.rs

Lines changed: 7 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -251,23 +251,6 @@ impl<'b> TypeBuilderMethods<'b> for CodeGenCtx<'b, '_> {
251251
}
252252
}
253253

254-
/// A [TyMemoryRemap] is a type that is used to represent the occurred
255-
/// memory field re-mapping that occurs when lowering a type to LLVM.
256-
/// This re-mapping originates from the fact that "padding" within types
257-
/// now becomes a concrete type, and thus the memory layout of the type
258-
/// changes if padding slots are inserted. If the type had any re-maps,
259-
/// then the [TyMemoryRemap] will contain a `remap` field with the
260-
/// new memory to source field mapping.
261-
pub(crate) struct TyMemoryRemap<'m> {
262-
/// The lowered type.
263-
pub ty: AnyTypeEnum<'m>,
264-
265-
/// If the type was re-mapped, this is a reference
266-
/// to the new memory map which should be used over the
267-
/// one that is stored in the [LayoutShape] of a [Layout].
268-
pub remap: Option<SmallVec<[u32; 4]>>,
269-
}
270-
271254
/// Define a trait that provides additional methods on the [CodeGenCtx]
272255
/// for computing types as LLVM types, and various other related LLVM
273256
/// specific type utilities.
@@ -296,20 +279,7 @@ pub(crate) trait ExtendedTyBuilderMethods<'m> {
296279

297280
impl<'m> ExtendedTyBuilderMethods<'m> for TyInfo {
298281
fn llvm_ty(&self, ctx: &CodeGenCtx<'_, 'm>) -> llvm::types::AnyTypeEnum<'m> {
299-
let (abi, variant_index) = self.layout.map(|layout| {
300-
let variant_index = match &layout.variants {
301-
Variants::Single { index } => Some(*index),
302-
_ => None,
303-
};
304-
305-
(layout.abi, variant_index)
306-
});
307-
308-
// Check the cache if we have already computed the lowered type
309-
// for this ir-type.
310-
if let Some(ty_remap) = ctx.ty_remaps.borrow().get(&(self.ty, variant_index)) {
311-
return ty_remap.ty;
312-
}
282+
let abi = self.layout.map(|layout| layout.abi);
313283

314284
match abi {
315285
AbiRepresentation::Scalar(scalar) => self.scalar_llvm_type_at(ctx, scalar),
@@ -386,9 +356,9 @@ impl<'m> ExtendedTyBuilderMethods<'m> for TyInfo {
386356
ctx.type_array(field_ty, elements)
387357
}
388358
LayoutShape::Aggregate { .. } => {
389-
let (ty, field_remapping) = match name {
359+
match name {
390360
Some(ref name) => {
391-
let (fields, packed, new_field_remapping) =
361+
let (fields, packed, _) =
392362
create_and_pad_struct_fields_from_layout(
393363
ctx, *self, layout,
394364
);
@@ -404,24 +374,17 @@ impl<'m> ExtendedTyBuilderMethods<'m> for TyInfo {
404374
.collect::<Vec<_>>();
405375

406376
ty.set_body(&fields, packed);
407-
(ty.into(), new_field_remapping)
377+
ty.into()
408378
}
409379
None => {
410-
let (fields, packed, new_field_remapping) =
380+
let (fields, packed, _) =
411381
create_and_pad_struct_fields_from_layout(
412382
ctx, *self, layout,
413383
);
414384

415-
(ctx.type_struct(&fields, packed), new_field_remapping)
385+
ctx.type_struct(&fields, packed)
416386
}
417-
};
418-
419-
ctx.ty_remaps.borrow_mut().insert(
420-
(self.ty, variant_index),
421-
TyMemoryRemap { ty, remap: field_remapping },
422-
);
423-
424-
ty
387+
}
425388
}
426389
}
427390
})

0 commit comments

Comments
 (0)