diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 36e5e3248e..2e78b48d3b 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -3809,6 +3809,7 @@ fn make_specializations<'a>( ident_ids: &mut ident_ids, ptr_bytes, update_mode_counter: 0, + call_specialization_counter: 0, }; // TODO: for now this final specialization pass is sequential, @@ -3871,6 +3872,7 @@ fn build_pending_specializations<'a>( ident_ids: &mut ident_ids, ptr_bytes, update_mode_counter: 0, + call_specialization_counter: 0, }; // Add modules' decls to Procs diff --git a/compiler/mono/src/alias_analysis.rs b/compiler/mono/src/alias_analysis.rs index 7012cff0ed..7652635f39 100644 --- a/compiler/mono/src/alias_analysis.rs +++ b/compiler/mono/src/alias_analysis.rs @@ -218,9 +218,10 @@ fn call_spec( full_layout: _, ret_layout: _, arg_layouts: _, + specialization_id, } => { - // TODO annotate each call with a unique identifier - let spec_var = CalleeSpecVar(&[]); + let array = specialization_id.to_bytes(); + let spec_var = CalleeSpecVar(&array); let arg_value_id = build_tuple_value(builder, env, block, call.arguments)?; let slice = &symbol.to_ne_bytes(); diff --git a/compiler/mono/src/decision_tree.rs b/compiler/mono/src/decision_tree.rs index 12f049995d..3aa4a7f22d 100644 --- a/compiler/mono/src/decision_tree.rs +++ b/compiler/mono/src/decision_tree.rs @@ -1408,7 +1408,7 @@ fn compile_test_help<'a>( let test = Expr::Call(crate::ir::Call { call_type: crate::ir::CallType::LowLevel { op, - update_mode: env.next_update_mode_id(op), + update_mode: env.next_update_mode_id(), }, arguments: arena.alloc([lhs, rhs]), }); diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 0af046d8ba..9f70c9bcef 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -736,6 +736,7 @@ pub struct Env<'a, 'i> { pub ident_ids: &'i mut IdentIds, pub ptr_bytes: u32, pub update_mode_counter: u64, + pub call_specialization_counter: u64, } impl<'a, 'i> Env<'a, 'i> { @@ -747,10 +748,9 @@ impl<'a, 'i> Env<'a, 'i> { Symbol::new(self.home, ident_id) } - pub fn next_update_mode_id(&mut self, op: LowLevel) -> UpdateModeId { + pub fn next_update_mode_id(&mut self) -> UpdateModeId { let id = UpdateModeId { id: self.update_mode_counter, - op, }; self.update_mode_counter += 1; @@ -758,6 +758,16 @@ impl<'a, 'i> Env<'a, 'i> { id } + pub fn next_call_specialization_id(&mut self) -> CallSpecId { + let id = CallSpecId { + id: self.call_specialization_counter, + }; + + self.call_specialization_counter += 1; + + id + } + pub fn is_imported_symbol(&self, symbol: Symbol) -> bool { symbol.module_id() != self.home && !symbol.is_builtin() } @@ -1036,27 +1046,25 @@ impl<'a> Call<'a> { } } +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct CallSpecId { + id: u64, +} + +impl CallSpecId { + pub fn to_bytes(self) -> [u8; 8] { + self.id.to_ne_bytes() + } +} + #[derive(Clone, Copy, Debug, PartialEq)] pub struct UpdateModeId { - op: LowLevel, id: u64, } impl UpdateModeId { - const SIZE: usize = std::mem::size_of::() + std::mem::size_of::(); - - pub fn to_bytes(self) -> [u8; UpdateModeId::SIZE] { - debug_assert_eq!(Self::SIZE, 9); - - let mut result = [0; Self::SIZE]; - - result[0] = self.op as u8; - - for (i, b) in self.id.to_ne_bytes().iter().enumerate() { - result[i + 1] = *b; - } - - result + pub fn to_bytes(self) -> [u8; 8] { + self.id.to_ne_bytes() } } @@ -1067,6 +1075,7 @@ pub enum CallType<'a> { full_layout: Layout<'a>, ret_layout: Layout<'a>, arg_layouts: &'a [Layout<'a>], + specialization_id: CallSpecId, }, ByPointer { name: Symbol, @@ -4205,7 +4214,7 @@ pub fn with_hole<'a>( let call = self::Call { call_type: CallType::LowLevel { op, - update_mode: env.next_update_mode_id(op), + update_mode: env.next_update_mode_id(), }, arguments: arg_symbols, }; @@ -4357,7 +4366,7 @@ pub fn from_can<'a>( let op = LowLevel::ExpectTrue; let call_type = CallType::LowLevel { op, - update_mode: env.next_update_mode_id(op), + update_mode: env.next_update_mode_id(), }; let arguments = env.arena.alloc([cond_symbol]); let call = self::Call { @@ -5094,11 +5103,13 @@ fn substitute_in_call<'a>( arg_layouts, ret_layout, full_layout, + specialization_id, } => substitute(subs, *name).map(|new| CallType::ByName { name: new, arg_layouts, ret_layout: *ret_layout, full_layout: *full_layout, + specialization_id: *specialization_id, }), CallType::ByPointer { name, @@ -5880,6 +5891,7 @@ fn call_by_pointer<'a>( full_layout: layout, ret_layout: *ret_layout, arg_layouts, + specialization_id: env.next_call_specialization_id(), }; let call = Call { call_type, @@ -6138,6 +6150,7 @@ fn call_by_name<'a>( ret_layout: *ret_layout, full_layout, arg_layouts, + specialization_id: env.next_call_specialization_id(), }, arguments: field_symbols, }; @@ -6182,6 +6195,7 @@ fn call_by_name<'a>( ret_layout: *ret_layout, full_layout, arg_layouts, + specialization_id: env.next_call_specialization_id(), }, arguments: field_symbols, }; @@ -6288,6 +6302,7 @@ fn call_by_name<'a>( ret_layout: *ret_layout, full_layout, arg_layouts, + specialization_id: env.next_call_specialization_id(), }, arguments: field_symbols, } @@ -6351,6 +6366,7 @@ fn call_specialized_proc<'a>( ret_layout: function_layout.result, full_layout: function_layout.full, arg_layouts: function_layout.arguments, + specialization_id: env.next_call_specialization_id(), }, arguments: field_symbols, }; @@ -6372,6 +6388,7 @@ fn call_specialized_proc<'a>( ret_layout: function_layout.result, full_layout: function_layout.full, arg_layouts: function_layout.arguments, + specialization_id: env.next_call_specialization_id(), }, arguments: field_symbols, }; @@ -6391,6 +6408,7 @@ fn call_specialized_proc<'a>( ret_layout: function_layout.result, full_layout: function_layout.full, arg_layouts: function_layout.arguments, + specialization_id: env.next_call_specialization_id(), }, arguments: field_symbols, }; diff --git a/compiler/reporting/tests/test_reporting.rs b/compiler/reporting/tests/test_reporting.rs index 08bf509300..6f1ba3f687 100644 --- a/compiler/reporting/tests/test_reporting.rs +++ b/compiler/reporting/tests/test_reporting.rs @@ -101,6 +101,7 @@ mod test_reporting { ident_ids: &mut ident_ids, ptr_bytes: 8, update_mode_counter: 0, + call_specialization_counter: 0, }; let _mono_expr = Stmt::new( &mut mono_env,