Refactor lower handlers to use overloads. (#4120)

Renames Lower::Handle* to Lower::LowerFunctionInst. This allows writing
a templated handler for instructions, moving code out of the macro
expansion and removing some of the redundancy in things like
`HandleAddrOf(..., SemIR::AddrOf inst)`
This commit is contained in:
Jon Ross-Perkins
2024-07-11 22:12:04 +00:00
committed by GitHub
parent bb27a4f97b
commit 6d2d1cf7ca
6 changed files with 126 additions and 124 deletions
+30 -28
View File
@@ -51,20 +51,33 @@ auto FunctionContext::LowerBlock(SemIR::InstBlockId block_id) -> void {
}
}
// Handles typed instructions for LowerInst. Many instructions lower using
// HandleInst, but others are unsupported or have trivial lowering.
//
// This only calls HandleInst for versions that should have implementations. A
// different approach would be to have the logic below implemented as HandleInst
// overloads. However, forward declarations of HandleInst exist for all `InstT`
// types, which would make getting the right overload resolution complex.
template <typename InstT>
static auto FatalErrorIfEncountered(InstT inst) -> void {
CARBON_FATAL()
<< "Encountered an instruction that isn't expected to lower. It's "
"possible that logic needs to be changed in order to stop "
"showing this instruction in lowered contexts. Instruction: "
<< inst;
}
// For instructions that are always of type `type`, produce the trivial runtime
// representation of type `type`.
static auto SetTrivialType(FunctionContext& context, SemIR::InstId inst_id)
-> void {
context.SetLocal(inst_id, context.GetTypeAsValue());
static auto LowerInstHelper(FunctionContext& context, SemIR::InstId inst_id,
InstT inst) {
if constexpr (!InstT::Kind.is_lowered()) {
CARBON_FATAL()
<< "Encountered an instruction that isn't expected to lower. It's "
"possible that logic needs to be changed in order to stop "
"showing this instruction in lowered contexts. Instruction: "
<< inst;
} else if constexpr (InstT::Kind.constant_kind() ==
SemIR::InstConstantKind::Always) {
CARBON_FATAL() << "Missing constant value for constant instruction "
<< inst;
} else if constexpr (InstT::Kind.is_type() == SemIR::InstIsType::Always) {
// For instructions that are always of type `type`, produce the trivial
// runtime representation of type `type`.
context.SetLocal(inst_id, context.GetTypeAsValue());
} else {
HandleInst(context, inst_id, inst);
}
}
// TODO: Consider renaming Handle##Name, instead relying on typed_inst overload
@@ -82,21 +95,10 @@ auto FunctionContext::LowerInst(SemIR::InstId inst_id) -> void {
builder_.getInserter().SetCurrentInstId(inst_id);
CARBON_KIND_SWITCH(inst) {
#define CARBON_SEM_IR_INST_KIND(Name) \
case CARBON_KIND(SemIR::Name typed_inst): { \
if constexpr (!SemIR::Name::Kind.is_lowered()) { \
FatalErrorIfEncountered(typed_inst); \
} else if constexpr (SemIR::Name::Kind.constant_kind() == \
SemIR::InstConstantKind::Always) { \
CARBON_FATAL() << "Missing constant value for constant instruction " \
<< inst; \
} else if constexpr (SemIR::Name::Kind.is_type() == \
SemIR::InstIsType::Always) { \
SetTrivialType(*this, inst_id); \
} else { \
Handle##Name(*this, inst_id, typed_inst); \
} \
break; \
#define CARBON_SEM_IR_INST_KIND(Name) \
case CARBON_KIND(SemIR::Name typed_inst): { \
LowerInstHelper(*this, inst_id, typed_inst); \
break; \
}
#include "toolchain/sem_ir/inst_kind.def"
}
+7 -5
View File
@@ -159,11 +159,13 @@ class FunctionContext {
Map<SemIR::InstId, llvm::Value*> locals_;
};
// Declare handlers for each SemIR::File instruction. Note that these aren't all
// defined.
#define CARBON_SEM_IR_INST_KIND(Name) \
auto Handle##Name(FunctionContext& context, SemIR::InstId inst_id, \
SemIR::Name inst) -> void;
// Provides handlers for instructions that occur in a FunctionContext. Although
// this is declared for all instructions, it should only be defined for
// instructions which are non-constant and not always typed. See
// `FunctionContext::LowerInst` for how this is used.
#define CARBON_SEM_IR_INST_KIND(Name) \
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, \
SemIR::Name inst) -> void;
#include "toolchain/sem_ir/inst_kind.def"
} // namespace Carbon::Lower
+52 -52
View File
@@ -18,18 +18,18 @@
namespace Carbon::Lower {
auto HandleAddrOf(FunctionContext& context, SemIR::InstId inst_id,
SemIR::AddrOf inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::AddrOf inst) -> void {
context.SetLocal(inst_id, context.GetValue(inst.lvalue_id));
}
auto HandleAddrPattern(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
SemIR::AddrPattern /*inst*/) -> void {
auto HandleInst(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
SemIR::AddrPattern /*inst*/) -> void {
CARBON_FATAL() << "`addr` should be lowered by `BuildFunctionDefinition`";
}
auto HandleArrayIndex(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ArrayIndex inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ArrayIndex inst) -> void {
auto* array_value = context.GetValue(inst.array_id);
auto* llvm_type =
context.GetType(context.sem_ir().insts().Get(inst.array_id).type_id());
@@ -41,25 +41,25 @@ auto HandleArrayIndex(FunctionContext& context, SemIR::InstId inst_id,
indexes, "array.index"));
}
auto HandleArrayInit(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ArrayInit inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ArrayInit inst) -> void {
// The result of initialization is the return slot of the initializer.
context.SetLocal(inst_id, context.GetValue(inst.dest_id));
}
auto HandleAsCompatible(FunctionContext& context, SemIR::InstId inst_id,
SemIR::AsCompatible inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::AsCompatible inst) -> void {
context.SetLocal(inst_id, context.GetValue(inst.source_id));
}
auto HandleAssign(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::Assign inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::Assign inst) -> void {
auto storage_type_id = context.sem_ir().insts().Get(inst.lhs_id).type_id();
context.FinishInit(storage_type_id, inst.lhs_id, inst.rhs_id);
}
auto HandleBindAlias(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BindAlias inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BindAlias inst) -> void {
auto type_inst_id = context.sem_ir().types().GetInstId(inst.type_id);
if (type_inst_id == SemIR::InstId::BuiltinNamespaceType) {
return;
@@ -68,8 +68,8 @@ auto HandleBindAlias(FunctionContext& context, SemIR::InstId inst_id,
context.SetLocal(inst_id, context.GetValue(inst.value_id));
}
auto HandleExportDecl(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ExportDecl inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ExportDecl inst) -> void {
auto type_inst_id = context.sem_ir().types().GetInstId(inst.type_id);
if (type_inst_id == SemIR::InstId::BuiltinNamespaceType) {
return;
@@ -78,30 +78,30 @@ auto HandleExportDecl(FunctionContext& context, SemIR::InstId inst_id,
context.SetLocal(inst_id, context.GetValue(inst.value_id));
}
auto HandleBindName(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BindName inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BindName inst) -> void {
context.SetLocal(inst_id, context.GetValue(inst.value_id));
}
auto HandleBindSymbolicName(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BindSymbolicName inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BindSymbolicName inst) -> void {
context.SetLocal(inst_id, context.GetValue(inst.value_id));
}
auto HandleBlockArg(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BlockArg inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BlockArg inst) -> void {
context.SetLocal(inst_id, context.GetBlockArg(inst.block_id, inst.type_id));
}
auto HandleBoundMethod(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BoundMethod inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BoundMethod inst) -> void {
// Propagate just the function; the object is separately provided to the
// enclosing call as an implicit argument.
context.SetLocal(inst_id, context.GetValue(inst.function_id));
}
auto HandleBranch(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::Branch inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::Branch inst) -> void {
// Opportunistically avoid creating a BasicBlock that contains just a branch.
// TODO: Don't do this if it would remove a loop preheader block.
llvm::BasicBlock* block = context.builder().GetInsertBlock();
@@ -114,8 +114,8 @@ auto HandleBranch(FunctionContext& context, SemIR::InstId /*inst_id*/,
context.builder().ClearInsertionPoint();
}
auto HandleBranchIf(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::BranchIf inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::BranchIf inst) -> void {
llvm::Value* cond = context.GetValue(inst.cond_id);
llvm::BasicBlock* then_block = context.GetBlock(inst.target_id);
llvm::BasicBlock* else_block = context.MakeSyntheticBlock();
@@ -123,8 +123,8 @@ auto HandleBranchIf(FunctionContext& context, SemIR::InstId /*inst_id*/,
context.builder().SetInsertPoint(else_block);
}
auto HandleBranchWithArg(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::BranchWithArg inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::BranchWithArg inst) -> void {
llvm::Value* arg = context.GetValue(inst.arg_id);
SemIR::TypeId arg_type_id =
context.sem_ir().insts().Get(inst.arg_id).type_id();
@@ -150,29 +150,29 @@ auto HandleBranchWithArg(FunctionContext& context, SemIR::InstId /*inst_id*/,
context.builder().ClearInsertionPoint();
}
auto HandleConverted(FunctionContext& context, SemIR::InstId inst_id,
SemIR::Converted inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::Converted inst) -> void {
context.SetLocal(inst_id, context.GetValue(inst.result_id));
}
auto HandleDeref(FunctionContext& context, SemIR::InstId inst_id,
SemIR::Deref inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::Deref inst) -> void {
context.SetLocal(inst_id, context.GetValue(inst.pointer_id));
}
auto HandleFacetTypeAccess(FunctionContext& context, SemIR::InstId inst_id,
SemIR::FacetTypeAccess /*inst*/) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::FacetTypeAccess /*inst*/) -> void {
context.SetLocal(inst_id, context.GetTypeAsValue());
}
auto HandleInitializeFrom(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::InitializeFrom inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::InitializeFrom inst) -> void {
auto storage_type_id = context.sem_ir().insts().Get(inst.dest_id).type_id();
context.FinishInit(storage_type_id, inst.dest_id, inst.src_id);
}
auto HandleNameRef(FunctionContext& context, SemIR::InstId inst_id,
SemIR::NameRef inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::NameRef inst) -> void {
auto type_inst_id = context.sem_ir().types().GetInstId(inst.type_id);
if (type_inst_id == SemIR::InstId::BuiltinNamespaceType) {
return;
@@ -181,18 +181,18 @@ auto HandleNameRef(FunctionContext& context, SemIR::InstId inst_id,
context.SetLocal(inst_id, context.GetValue(inst.value_id));
}
auto HandleParam(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
SemIR::Param /*inst*/) -> void {
auto HandleInst(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
SemIR::Param /*inst*/) -> void {
CARBON_FATAL() << "Parameters should be lowered by `BuildFunctionDefinition`";
}
auto HandleReturn(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::Return /*inst*/) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::Return /*inst*/) -> void {
context.builder().CreateRetVoid();
}
auto HandleReturnExpr(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::ReturnExpr inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId /*inst_id*/,
SemIR::ReturnExpr inst) -> void {
auto result_type_id = context.sem_ir().insts().Get(inst.expr_id).type_id();
switch (SemIR::GetInitRepr(context.sem_ir(), result_type_id).kind) {
case SemIR::InitRepr::None:
@@ -210,20 +210,20 @@ auto HandleReturnExpr(FunctionContext& context, SemIR::InstId /*inst_id*/,
}
}
auto HandleSpliceBlock(FunctionContext& context, SemIR::InstId inst_id,
SemIR::SpliceBlock inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::SpliceBlock inst) -> void {
context.LowerBlock(inst.block_id);
context.SetLocal(inst_id, context.GetValue(inst.result_id));
}
auto HandleUnaryOperatorNot(FunctionContext& context, SemIR::InstId inst_id,
SemIR::UnaryOperatorNot inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::UnaryOperatorNot inst) -> void {
context.SetLocal(
inst_id, context.builder().CreateNot(context.GetValue(inst.operand_id)));
}
auto HandleVarStorage(FunctionContext& context, SemIR::InstId inst_id,
SemIR::VarStorage inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::VarStorage inst) -> void {
context.SetLocal(inst_id,
context.builder().CreateAlloca(context.GetType(inst.type_id),
/*ArraySize=*/nullptr));
+26 -28
View File
@@ -13,8 +13,8 @@
namespace Carbon::Lower {
auto HandleClassDecl(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
SemIR::ClassDecl /*inst*/) -> void {
auto HandleInst(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
SemIR::ClassDecl /*inst*/) -> void {
// No action to perform.
}
@@ -100,8 +100,8 @@ static auto GetStructFieldName(FunctionContext& context,
return context.sem_ir().names().GetIRBaseName(field.name_id);
}
auto HandleClassElementAccess(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ClassElementAccess inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ClassElementAccess inst) -> void {
// Find the class that we're performing access into.
auto class_type_id = context.sem_ir().insts().Get(inst.base_id).type_id();
auto class_id =
@@ -142,15 +142,15 @@ static auto EmitAggregateInitializer(FunctionContext& context,
}
}
auto HandleClassInit(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ClassInit inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ClassInit inst) -> void {
context.SetLocal(
inst_id, EmitAggregateInitializer(context, inst.type_id, inst.elements_id,
"class.init"));
}
auto HandleStructAccess(FunctionContext& context, SemIR::InstId inst_id,
SemIR::StructAccess inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::StructAccess inst) -> void {
auto struct_type_id = context.sem_ir().insts().Get(inst.struct_id).type_id();
context.SetLocal(
inst_id, GetAggregateElement(
@@ -158,9 +158,8 @@ auto HandleStructAccess(FunctionContext& context, SemIR::InstId inst_id,
GetStructFieldName(context, struct_type_id, inst.index)));
}
auto HandleStructLiteral(FunctionContext& /*context*/,
SemIR::InstId /*inst_id*/,
SemIR::StructLiteral /*inst*/) -> void {
auto HandleInst(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
SemIR::StructLiteral /*inst*/) -> void {
// A StructLiteral should always be converted to a StructInit or StructValue
// if its value is needed.
}
@@ -212,15 +211,15 @@ static auto EmitAggregateValueRepr(FunctionContext& context,
}
}
auto HandleStructInit(FunctionContext& context, SemIR::InstId inst_id,
SemIR::StructInit inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::StructInit inst) -> void {
context.SetLocal(
inst_id, EmitAggregateInitializer(context, inst.type_id, inst.elements_id,
"struct.init"));
}
auto HandleStructValue(FunctionContext& context, SemIR::InstId inst_id,
SemIR::StructValue inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::StructValue inst) -> void {
if (auto fn_type = context.sem_ir().types().TryGetAs<SemIR::FunctionType>(
inst.type_id)) {
context.SetLocal(inst_id, context.GetFunction(fn_type->function_id));
@@ -231,21 +230,20 @@ auto HandleStructValue(FunctionContext& context, SemIR::InstId inst_id,
inst_id, EmitAggregateValueRepr(context, inst.type_id, inst.elements_id));
}
auto HandleStructTypeField(FunctionContext& /*context*/,
SemIR::InstId /*inst_id*/,
SemIR::StructTypeField /*inst*/) -> void {
auto HandleInst(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
SemIR::StructTypeField /*inst*/) -> void {
// No action to take.
}
auto HandleTupleAccess(FunctionContext& context, SemIR::InstId inst_id,
SemIR::TupleAccess inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::TupleAccess inst) -> void {
context.SetLocal(inst_id,
GetAggregateElement(context, inst.tuple_id, inst.index,
inst.type_id, "tuple.elem"));
}
auto HandleTupleIndex(FunctionContext& context, SemIR::InstId inst_id,
SemIR::TupleIndex inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::TupleIndex inst) -> void {
auto index_inst =
context.sem_ir().insts().GetAs<SemIR::IntLiteral>(inst.index_id);
auto index = context.sem_ir().ints().Get(index_inst.int_id).getZExtValue();
@@ -254,21 +252,21 @@ auto HandleTupleIndex(FunctionContext& context, SemIR::InstId inst_id,
inst.type_id, "tuple.index"));
}
auto HandleTupleLiteral(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
SemIR::TupleLiteral /*inst*/) -> void {
auto HandleInst(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/,
SemIR::TupleLiteral /*inst*/) -> void {
// A TupleLiteral should always be converted to a TupleInit or TupleValue if
// its value is needed.
}
auto HandleTupleInit(FunctionContext& context, SemIR::InstId inst_id,
SemIR::TupleInit inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::TupleInit inst) -> void {
context.SetLocal(
inst_id, EmitAggregateInitializer(context, inst.type_id, inst.elements_id,
"tuple.init"));
}
auto HandleTupleValue(FunctionContext& context, SemIR::InstId inst_id,
SemIR::TupleValue inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::TupleValue inst) -> void {
context.SetLocal(
inst_id, EmitAggregateValueRepr(context, inst.type_id, inst.elements_id));
}
+1 -1
View File
@@ -290,7 +290,7 @@ static auto HandleBuiltinCall(FunctionContext& context, SemIR::InstId inst_id,
CARBON_FATAL() << "Unsupported builtin call.";
}
auto HandleCall(FunctionContext& context, SemIR::InstId inst_id,
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::Call inst) -> void {
llvm::ArrayRef<SemIR::InstId> arg_ids =
context.sem_ir().inst_blocks().Get(inst.args_id);
+10 -10
View File
@@ -7,8 +7,8 @@
namespace Carbon::Lower {
auto HandleBindValue(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BindValue inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::BindValue inst) -> void {
switch (auto rep = SemIR::GetValueRepr(context.sem_ir(), inst.type_id);
rep.kind) {
case SemIR::ValueRepr::Unknown:
@@ -34,21 +34,21 @@ auto HandleBindValue(FunctionContext& context, SemIR::InstId inst_id,
}
}
auto HandleTemporary(FunctionContext& context, SemIR::InstId inst_id,
SemIR::Temporary inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::Temporary inst) -> void {
context.FinishInit(inst.type_id, inst.storage_id, inst.init_id);
context.SetLocal(inst_id, context.GetValue(inst.storage_id));
}
auto HandleTemporaryStorage(FunctionContext& context, SemIR::InstId inst_id,
SemIR::TemporaryStorage inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::TemporaryStorage inst) -> void {
context.SetLocal(inst_id,
context.builder().CreateAlloca(context.GetType(inst.type_id),
nullptr, "temp"));
}
auto HandleValueAsRef(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ValueAsRef inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ValueAsRef inst) -> void {
CARBON_CHECK(SemIR::GetExprCategory(context.sem_ir(), inst.value_id) ==
SemIR::ExprCategory::Value);
CARBON_CHECK(SemIR::GetValueRepr(context.sem_ir(), inst.type_id).kind ==
@@ -56,8 +56,8 @@ auto HandleValueAsRef(FunctionContext& context, SemIR::InstId inst_id,
context.SetLocal(inst_id, context.GetValue(inst.value_id));
}
auto HandleValueOfInitializer(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ValueOfInitializer inst) -> void {
auto HandleInst(FunctionContext& context, SemIR::InstId inst_id,
SemIR::ValueOfInitializer inst) -> void {
CARBON_CHECK(SemIR::GetExprCategory(context.sem_ir(), inst.init_id) ==
SemIR::ExprCategory::Initializing);
CARBON_CHECK(SemIR::GetValueRepr(context.sem_ir(), inst.type_id).kind ==