mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Add a vtableDecl inst and use that in classes instead of VtablePtr (#5945)
This addresses/avoids the duplicate import of vtables. I went through a few iterations/etc along the way and left them in the commit history for the PR in case any of them are useful to illustrate how I got here, or worth revisiting. Essentially I ended up with a circularity in importing - importing the class imported the vtable_decl which imported the virtual functions - and then pending specifics of the virtual functions needed the self specific of the enclosing class which wasn't ready yet. Adding ImportRef to the vtable_decl to break the cycle caused me trouble when naming the vtable_decl instructions - so I tried making the functions in the vtable unloaded ImportRefs instead. That worked, but meant that importing a class still was doing O(number of vtable entries) even if the vtable wasn't used. So I revisited the lazy vtable_decl - figured out how to make the naming work (when building the vtable_ptr, even though the vtable_decl doesn't have to be loaded for the vtable_ptr, I force it to be loaded anyway, to load the vtable so it's usable by lowering, etc). And then I could go back to the old non-lazy loaded vtable entries (using some loaded ImportRefs in the cases where we needed them/had already adopted them). Then thinking about the VtablePtr instruction, went back/forth on exactly what it needed - went from VtablePtr's member being a VtableDecl InstId, to a ClassId, then back to a VtableId as it was before this patch. Naming the instructions has one oddity, that the VtableDecl and VtablePtr instructions seem to need to add the pending name for the VtableId - despite not using the VtableId in their own name - should the inst namer be doing this work for parameters of instructions rather than requiring the inst to do it deliberately? (or am I holding it wrong in some way?) --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
7727c62880
commit
3f9fc633fe
@@ -145,15 +145,15 @@ static auto BuildVtable(Context& context, Parse::ClassDefinitionId node_id,
|
||||
// Get some base class/type/specific info.
|
||||
if (base_class_type) {
|
||||
auto& base_class_info = context.classes().Get(base_class_type->class_id);
|
||||
auto base_vtable_ptr_inst_id = base_class_info.vtable_ptr_id;
|
||||
if (base_vtable_ptr_inst_id.has_value()) {
|
||||
LoadImportRef(context, base_vtable_ptr_inst_id);
|
||||
auto base_vtable_decl_inst_id = base_class_info.vtable_decl_id;
|
||||
if (base_vtable_decl_inst_id.has_value()) {
|
||||
LoadImportRef(context, base_vtable_decl_inst_id);
|
||||
auto canonical_base_vtable_inst_id =
|
||||
context.constant_values().GetConstantInstId(base_vtable_ptr_inst_id);
|
||||
const auto& base_vtable_ptr_inst =
|
||||
context.insts().GetAs<SemIR::VtablePtr>(
|
||||
context.constant_values().GetConstantInstId(base_vtable_decl_inst_id);
|
||||
const auto& base_vtable_decl_inst =
|
||||
context.insts().GetAs<SemIR::VtableDecl>(
|
||||
canonical_base_vtable_inst_id);
|
||||
base_vtable_id = base_vtable_ptr_inst.vtable_id;
|
||||
base_vtable_id = base_vtable_decl_inst.vtable_id;
|
||||
base_class_specific_id = base_class_type->specific_id;
|
||||
}
|
||||
}
|
||||
@@ -187,7 +187,6 @@ static auto BuildVtable(Context& context, Parse::ClassDefinitionId node_id,
|
||||
// TODO: Avoid quadratic search. Perhaps build a map from `NameId` to the
|
||||
// elements of the top of `vtable_stack`.
|
||||
for (auto base_vtable_entry_id : base_vtable_inst_block) {
|
||||
LoadImportRef(context, base_vtable_entry_id);
|
||||
auto [derived_vtable_entry_id, derived_vtable_entry_const_id, fn_id,
|
||||
specific_id] =
|
||||
DecomposeVirtualFunction(context.sem_ir(), base_vtable_entry_id,
|
||||
@@ -303,15 +302,9 @@ static auto CheckCompleteClassType(
|
||||
if (class_info.is_dynamic) {
|
||||
auto vtable_id = BuildVtable(context, node_id, class_id, base_class_type,
|
||||
vtable_contents);
|
||||
|
||||
auto vptr_type_id = GetPointerType(context, SemIR::VtableType::TypeInstId);
|
||||
auto generic_id = class_info.generic_id;
|
||||
auto self_specific_id = context.generics().GetSelfSpecific(generic_id);
|
||||
class_info.vtable_ptr_id =
|
||||
AddInst<SemIR::VtablePtr>(context, node_id,
|
||||
{.type_id = vptr_type_id,
|
||||
.vtable_id = vtable_id,
|
||||
.specific_id = self_specific_id});
|
||||
class_info.vtable_decl_id = AddInst<SemIR::VtableDecl>(
|
||||
context, node_id, {.type_id = vptr_type_id, .vtable_id = vtable_id});
|
||||
}
|
||||
|
||||
auto struct_type_id = GetStructType(
|
||||
|
||||
Reference in New Issue
Block a user