mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Convert StructTypeField to a specific type. (#4492)
This converts `StructTypeField` from an instruction to a dedicated type, with its own store. This had originated from discussing how `.GetAs<SemIR::StructTypeField>` was more prevalent than for other instructions, but is probably more interesting for the storage savings (16 bytes StructTypeField + 4 byte LocId + 4 byte InstId -> 8 byte StructTypeField). Due to the different structure, these now have their own stack during construction, reducing (but not eliminating) `args_type_info_stack_` use-cases. The test changes of different InstIds is expected because structs and classes generate fewer instructions now. Other than that, results should remain the same. I'm generally trying to avoid unrelated cleanup here due to the PR size, though I did scrutinize the `VerifyOnFinish` calls, adding one and commenting others (putting them in member order because that's how I was checking what was verified and what wasn't).
This commit is contained in:
@@ -1233,7 +1233,7 @@ class ImportRefResolver {
|
||||
return TryResolveTypedInst(inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::StructType inst): {
|
||||
return TryResolveTypedInst(inst, inst_id);
|
||||
return TryResolveTypedInst(inst);
|
||||
}
|
||||
case CARBON_KIND(SemIR::StructValue inst): {
|
||||
return TryResolveTypedInst(inst);
|
||||
@@ -2147,38 +2147,31 @@ class ImportRefResolver {
|
||||
.specific_id = specific_id});
|
||||
}
|
||||
|
||||
auto TryResolveTypedInst(SemIR::StructType inst, SemIR::InstId import_inst_id)
|
||||
-> ResolveResult {
|
||||
auto TryResolveTypedInst(SemIR::StructType inst) -> ResolveResult {
|
||||
CARBON_CHECK(inst.type_id == SemIR::TypeId::TypeType);
|
||||
auto orig_fields = import_ir_.inst_blocks().Get(inst.fields_id);
|
||||
auto orig_fields = import_ir_.struct_type_fields().Get(inst.fields_id);
|
||||
llvm::SmallVector<SemIR::ConstantId> field_const_ids;
|
||||
field_const_ids.reserve(orig_fields.size());
|
||||
for (auto field_id : orig_fields) {
|
||||
auto field = import_ir_.insts().GetAs<SemIR::StructTypeField>(field_id);
|
||||
field_const_ids.push_back(GetLocalConstantId(field.field_type_id));
|
||||
for (auto field : orig_fields) {
|
||||
field_const_ids.push_back(GetLocalConstantId(field.type_id));
|
||||
}
|
||||
if (HasNewWork()) {
|
||||
return Retry();
|
||||
}
|
||||
|
||||
// Prepare a vector of fields for GetStructType.
|
||||
// TODO: Should we have field constants so that we can deduplicate fields
|
||||
// without creating instructions here?
|
||||
llvm::SmallVector<SemIR::InstId> fields;
|
||||
fields.reserve(orig_fields.size());
|
||||
for (auto [field_id, field_const_id] :
|
||||
llvm::SmallVector<SemIR::StructTypeField> new_fields;
|
||||
new_fields.reserve(orig_fields.size());
|
||||
for (auto [orig_field, field_const_id] :
|
||||
llvm::zip(orig_fields, field_const_ids)) {
|
||||
auto field = import_ir_.insts().GetAs<SemIR::StructTypeField>(field_id);
|
||||
auto name_id = GetLocalNameId(field.name_id);
|
||||
auto name_id = GetLocalNameId(orig_field.name_id);
|
||||
auto field_type_id = context_.GetTypeIdForTypeConstant(field_const_id);
|
||||
fields.push_back(context_.AddInstInNoBlock<SemIR::StructTypeField>(
|
||||
AddImportIRInst(import_inst_id),
|
||||
{.name_id = name_id, .field_type_id = field_type_id}));
|
||||
new_fields.push_back({.name_id = name_id, .type_id = field_type_id});
|
||||
}
|
||||
|
||||
return ResolveAs<SemIR::StructType>(
|
||||
{.type_id = SemIR::TypeId::TypeType,
|
||||
.fields_id = context_.inst_blocks().AddCanonical(fields)});
|
||||
.fields_id = context_.struct_type_fields().AddCanonical(new_fields)});
|
||||
}
|
||||
|
||||
auto TryResolveTypedInst(SemIR::StructValue inst) -> ResolveResult {
|
||||
|
||||
Reference in New Issue
Block a user