Switch AddInst struct init style. (#4012)

Trying to conform with #4009. Changes SemIR::LocIdAndInst construction
to root out struct init cases with AddInst and related functions. I'm
using templating of AddInst functions in order to avoid `AddInst(loc_id,
InstName{...})` and instead have `AddInst<InstName>(loc_id, {...})` with
I think similar readability results. There are a couple cases where inst
construction is templated and so designated initializers couldn't be
used, so this may be better for those in particular due to the extra
type enforcement.

This probably doesn't clean up every last case, but I was trying to get
the bulk at once without bleeding over into less related changes.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
Jon Ross-Perkins
2024-05-31 22:49:44 +00:00
committed by GitHub
co-authored by Richard Smith
parent 6e9d0b15c8
commit 5bb318cae6
32 changed files with 361 additions and 293 deletions
+74 -62
View File
@@ -100,9 +100,10 @@ static auto FinalizeTemporary(Context& context, SemIR::InstId init_id,
<< "initialized multiple times? Have "
<< sem_ir.insts().Get(return_slot_id);
auto init = sem_ir.insts().Get(init_id);
return context.AddInst(
{sem_ir.insts().GetLocId(init_id),
SemIR::Temporary{init.type_id(), return_slot_id, init_id}});
return context.AddInst<SemIR::Temporary>(sem_ir.insts().GetLocId(init_id),
{.type_id = init.type_id(),
.storage_id = return_slot_id,
.init_id = init_id});
}
if (discarded) {
@@ -117,10 +118,11 @@ static auto FinalizeTemporary(Context& context, SemIR::InstId init_id,
// instructions.
auto init = sem_ir.insts().Get(init_id);
auto loc_id = sem_ir.insts().GetLocId(init_id);
auto temporary_id =
context.AddInst({loc_id, SemIR::TemporaryStorage{init.type_id()}});
return context.AddInst(
{loc_id, SemIR::Temporary{init.type_id(), temporary_id, init_id}});
auto temporary_id = context.AddInst<SemIR::TemporaryStorage>(
loc_id, {.type_id = init.type_id()});
return context.AddInst<SemIR::Temporary>(loc_id, {.type_id = init.type_id(),
.storage_id = temporary_id,
.init_id = init_id});
}
// Materialize a temporary to hold the result of the given expression if it is
@@ -144,15 +146,14 @@ static auto MakeElementAccessInst(Context& context, SemIR::LocId loc_id,
// TODO: Add a new instruction kind for indexing an array at a constant
// index so that we don't need an integer literal instruction here, and
// remove this special case.
auto index_id = block.AddInst(
{loc_id,
SemIR::IntLiteral{context.GetBuiltinType(SemIR::BuiltinKind::IntType),
context.ints().Add(llvm::APInt(32, i))}});
return block.AddInst(
{loc_id, AccessInstT{elem_type_id, aggregate_id, index_id}});
auto index_id = block.template AddInst<SemIR::IntLiteral>(
loc_id, {.type_id = context.GetBuiltinType(SemIR::BuiltinKind::IntType),
.int_id = context.ints().Add(llvm::APInt(32, i))});
return block.template AddInst<AccessInstT>(
loc_id, {elem_type_id, aggregate_id, index_id});
} else {
return block.AddInst({loc_id, AccessInstT{elem_type_id, aggregate_id,
SemIR::ElementIndex(i)}});
return block.template AddInst<AccessInstT>(
loc_id, {elem_type_id, aggregate_id, SemIR::ElementIndex(i)});
}
}
@@ -250,8 +251,8 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type,
// destination for the array initialization if we weren't given one.
SemIR::InstId return_slot_id = target.init_id;
if (!target.init_id.is_valid()) {
return_slot_id = target_block->AddInst(
{value_loc_id, SemIR::TemporaryStorage{target.type_id}});
return_slot_id = target_block->AddInst<SemIR::TemporaryStorage>(
value_loc_id, {.type_id = target.type_id});
}
// Initialize each element of the array from the corresponding element of the
@@ -277,10 +278,10 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type,
// Flush the temporary here if we didn't insert it earlier, so we can add a
// reference to the return slot.
target_block->InsertHere();
return context.AddInst(
{value_loc_id,
SemIR::ArrayInit{target.type_id, sem_ir.inst_blocks().Add(inits),
return_slot_id}});
return context.AddInst<SemIR::ArrayInit>(
value_loc_id, {.type_id = target.type_id,
.inits_id = sem_ir.inst_blocks().Add(inits),
.dest_id = return_slot_id});
}
// Performs a conversion from a tuple to a tuple type. This function only
@@ -357,12 +358,14 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type,
if (is_init) {
target.init_block->InsertHere();
return context.AddInst(
{value_loc_id,
SemIR::TupleInit{target.type_id, new_block.id(), target.init_id}});
return context.AddInst<SemIR::TupleInit>(value_loc_id,
{.type_id = target.type_id,
.elements_id = new_block.id(),
.dest_id = target.init_id});
} else {
return context.AddInst(
{value_loc_id, SemIR::TupleValue{target.type_id, new_block.id()}});
return context.AddInst<SemIR::TupleValue>(
value_loc_id,
{.type_id = target.type_id, .elements_id = new_block.id()});
}
}
@@ -488,17 +491,20 @@ static auto ConvertStructToStructOrClass(Context& context,
target.init_block->InsertHere();
CARBON_CHECK(is_init)
<< "Converting directly to a class value is not supported";
return context.AddInst(
{value_loc_id,
SemIR::ClassInit{target.type_id, new_block.id(), target.init_id}});
return context.AddInst<SemIR::ClassInit>(value_loc_id,
{.type_id = target.type_id,
.elements_id = new_block.id(),
.dest_id = target.init_id});
} else if (is_init) {
target.init_block->InsertHere();
return context.AddInst(
{value_loc_id,
SemIR::StructInit{target.type_id, new_block.id(), target.init_id}});
return context.AddInst<SemIR::StructInit>(value_loc_id,
{.type_id = target.type_id,
.elements_id = new_block.id(),
.dest_id = target.init_id});
} else {
return context.AddInst(
{value_loc_id, SemIR::StructValue{target.type_id, new_block.id()}});
return context.AddInst<SemIR::StructValue>(
value_loc_id,
{.type_id = target.type_id, .elements_id = new_block.id()});
}
}
@@ -543,9 +549,8 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
if (need_temporary) {
target.kind = ConversionTarget::Initializer;
target.init_block = &target_block;
target.init_id =
target_block.AddInst({context.insts().GetLocId(value_id),
SemIR::TemporaryStorage{target.type_id}});
target.init_id = target_block.AddInst<SemIR::TemporaryStorage>(
context.insts().GetLocId(value_id), {.type_id = target.type_id});
}
auto result_id = ConvertStructToStructOrClass<SemIR::ClassElementAccess>(
@@ -553,9 +558,10 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
if (need_temporary) {
target_block.InsertHere();
result_id = context.AddInst(
{context.insts().GetLocId(value_id),
SemIR::Temporary{target.type_id, target.init_id, result_id}});
result_id = context.AddInst<SemIR::Temporary>(
context.insts().GetLocId(value_id), {.type_id = target.type_id,
.storage_id = target.init_id,
.init_id = result_id});
}
return result_id;
}
@@ -610,9 +616,10 @@ static auto ConvertDerivedToBase(Context& context, SemIR::LocId loc_id,
// Add a series of `.base` accesses.
for (auto base_id : path) {
auto base_decl = context.insts().GetAs<SemIR::BaseDecl>(base_id);
value_id = context.AddInst(
{loc_id, SemIR::ClassElementAccess{base_decl.base_type_id, value_id,
base_decl.index}});
value_id = context.AddInst<SemIR::ClassElementAccess>(
loc_id, {.type_id = base_decl.base_type_id,
.base_id = value_id,
.index = base_decl.index});
}
return value_id;
}
@@ -624,14 +631,15 @@ static auto ConvertDerivedPointerToBasePointer(
const InheritancePath& path) -> SemIR::InstId {
// Form `*p`.
ptr_id = ConvertToValueExpr(context, ptr_id);
auto ref_id =
context.AddInst({loc_id, SemIR::Deref{src_ptr_type.pointee_id, ptr_id}});
auto ref_id = context.AddInst<SemIR::Deref>(
loc_id, {.type_id = src_ptr_type.pointee_id, .pointer_id = ptr_id});
// Convert as a reference expression.
ref_id = ConvertDerivedToBase(context, loc_id, ref_id, path);
// Take the address.
return context.AddInst({loc_id, SemIR::AddrOf{dest_ptr_type_id, ref_id}});
return context.AddInst<SemIR::AddrOf>(
loc_id, {.type_id = dest_ptr_type_id, .lvalue_id = ref_id});
}
// Returns whether `category` is a valid expression category to produce as a
@@ -729,8 +737,8 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
// The initializer produces an object representation by copy, and the
// value representation is a copy of the object representation, so we
// already have a value of the right form.
return context.AddInst(
{loc_id, SemIR::ValueOfInitializer{value_type_id, value_id}});
return context.AddInst<SemIR::ValueOfInitializer>(
loc_id, {.type_id = value_type_id, .init_id = value_id});
}
}
}
@@ -750,8 +758,8 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
ConversionTarget{.kind = ConversionTarget::Value,
.type_id = value_type_id});
}
return context.AddInst(
{loc_id, SemIR::AsCompatible{target.type_id, value_id}});
return context.AddInst<SemIR::AsCompatible>(
loc_id, {.type_id = target.type_id, .source_id = value_id});
}
}
@@ -856,8 +864,8 @@ static auto PerformBuiltinConversion(Context& context, SemIR::LocId loc_id,
// TODO: Support converting tuple and struct values to facet types,
// combining the above conversions and this one in a single conversion.
if (sem_ir.types().Is<SemIR::InterfaceType>(value_type_id)) {
return context.AddInst(
{loc_id, SemIR::FacetTypeAccess{target.type_id, value_id}});
return context.AddInst<SemIR::FacetTypeAccess>(
loc_id, {.type_id = target.type_id, .facet_id = value_id});
}
}
@@ -967,8 +975,10 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
// Track that we performed a type conversion, if we did so.
if (orig_expr_id != expr_id) {
expr_id = context.AddInst(
{loc_id, SemIR::Converted{target.type_id, orig_expr_id, expr_id}});
expr_id =
context.AddInst<SemIR::Converted>(loc_id, {.type_id = target.type_id,
.original_id = orig_expr_id,
.result_id = expr_id});
}
// For `as`, don't perform any value category conversions. In particular, an
@@ -1018,8 +1028,9 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
// If we have a reference and don't want one, form a value binding.
// TODO: Support types with custom value representations.
expr_id = context.AddInst({context.insts().GetLocId(expr_id),
SemIR::BindValue{expr.type_id(), expr_id}});
expr_id = context.AddInst<SemIR::BindValue>(
context.insts().GetLocId(expr_id),
{.type_id = expr.type_id(), .value_id = expr_id});
// We now have a value expression.
[[fallthrough]];
@@ -1036,9 +1047,10 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id,
if (auto init_rep = SemIR::GetInitRepr(sem_ir, target.type_id);
init_rep.kind == SemIR::InitRepr::ByCopy) {
target.init_block->InsertHere();
expr_id = context.AddInst(
{loc_id,
SemIR::InitializeFrom{target.type_id, expr_id, target.init_id}});
expr_id = context.AddInst<SemIR::InitializeFrom>(
loc_id, {.type_id = target.type_id,
.src_id = expr_id,
.dest_id = target.init_id});
}
}
@@ -1143,9 +1155,9 @@ static auto ConvertSelf(Context& context, SemIR::LocId call_loc_id,
return SemIR::InstId::BuiltinError;
}
auto loc_id = context.insts().GetLocId(self_or_addr_id);
self_or_addr_id = context.AddInst(
{loc_id, SemIR::AddrOf{context.GetPointerType(self.type_id()),
self_or_addr_id}});
self_or_addr_id = context.AddInst<SemIR::AddrOf>(
loc_id, {.type_id = context.GetPointerType(self.type_id()),
.lvalue_id = self_or_addr_id});
}
return ConvertToValueOfType(context, call_loc_id, self_or_addr_id,