diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index 8d7d749076c5..03bd93bb9063 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -516,7 +516,7 @@ namespace { // // - An `AddNestedIncompleteTypes` step adds a task for all incomplete types // nested within a type to the work list. -// - A `BuildValueRepresentation` step computes the value representation for a +// - A `BuildValueRepr` step computes the value representation for a // type, once all of its nested types are complete, and marks the type as // complete. class TypeCompleter { @@ -570,31 +570,28 @@ class TypeCompleter { } CARBON_CHECK(work_list_.size() >= old_work_list_size) << "AddNestedIncompleteTypes should not remove work items"; - work_list_[old_work_list_size - 1].phase = - Phase::BuildValueRepresentation; + work_list_[old_work_list_size - 1].phase = Phase::BuildValueRepr; break; - case Phase::BuildValueRepresentation: { - auto value_rep = BuildValueRepresentation(type_id, inst); + case Phase::BuildValueRepr: { + auto value_rep = BuildValueRepr(type_id, inst); context_.sem_ir().CompleteType(type_id, value_rep); CARBON_CHECK(old_work_list_size == work_list_.size()) - << "BuildValueRepresentation should not change work items"; + << "BuildValueRepr should not change work items"; work_list_.pop_back(); // Also complete the value representation type, if necessary. This // should never fail: the value representation shouldn't require any // additional nested types to be complete. if (!context_.sem_ir().IsTypeComplete(value_rep.type_id)) { - work_list_.push_back( - {value_rep.type_id, Phase::BuildValueRepresentation}); + work_list_.push_back({value_rep.type_id, Phase::BuildValueRepr}); } // For a pointer representation, the pointee also needs to be complete. - if (value_rep.kind == SemIR::ValueRepresentation::Pointer) { + if (value_rep.kind == SemIR::ValueRepr::Pointer) { auto pointee_type_id = context_.sem_ir().GetPointeeType(value_rep.type_id); if (!context_.sem_ir().IsTypeComplete(pointee_type_id)) { - work_list_.push_back( - {pointee_type_id, Phase::BuildValueRepresentation}); + work_list_.push_back({pointee_type_id, Phase::BuildValueRepr}); } } break; @@ -639,7 +636,7 @@ class TypeCompleter { } return false; } - Push(class_info.object_representation_id); + Push(class_info.object_repr_id); break; } @@ -656,51 +653,47 @@ class TypeCompleter { // Makes an empty value representation, which is used for types that have no // state, such as empty structs and tuples. - auto MakeEmptyRepresentation(Parse::NodeId parse_node) const - -> SemIR::ValueRepresentation { - return {.kind = SemIR::ValueRepresentation::None, + auto MakeEmptyValueRepr(Parse::NodeId parse_node) const -> SemIR::ValueRepr { + return {.kind = SemIR::ValueRepr::None, .type_id = context_.CanonicalizeTupleType(parse_node, {})}; } // Makes a value representation that uses pass-by-copy, copying the given // type. - auto MakeCopyRepresentation( - SemIR::TypeId rep_id, - SemIR::ValueRepresentation::AggregateKind aggregate_kind = - SemIR::ValueRepresentation::NotAggregate) const - -> SemIR::ValueRepresentation { - return {.kind = SemIR::ValueRepresentation::Copy, + auto MakeCopyValueRepr(SemIR::TypeId rep_id, + SemIR::ValueRepr::AggregateKind aggregate_kind = + SemIR::ValueRepr::NotAggregate) const + -> SemIR::ValueRepr { + return {.kind = SemIR::ValueRepr::Copy, .aggregate_kind = aggregate_kind, .type_id = rep_id}; } // Makes a value representation that uses pass-by-address with the given // pointee type. - auto MakePointerRepresentation( - Parse::NodeId parse_node, SemIR::TypeId pointee_id, - SemIR::ValueRepresentation::AggregateKind aggregate_kind = - SemIR::ValueRepresentation::NotAggregate) const - -> SemIR::ValueRepresentation { + auto MakePointerValueRepr(Parse::NodeId parse_node, SemIR::TypeId pointee_id, + SemIR::ValueRepr::AggregateKind aggregate_kind = + SemIR::ValueRepr::NotAggregate) const + -> SemIR::ValueRepr { // TODO: Should we add `const` qualification to `pointee_id`? - return {.kind = SemIR::ValueRepresentation::Pointer, + return {.kind = SemIR::ValueRepr::Pointer, .aggregate_kind = aggregate_kind, .type_id = context_.GetPointerType(parse_node, pointee_id)}; } // Gets the value representation of a nested type, which should already be // complete. - auto GetNestedValueRepresentation(SemIR::TypeId nested_type_id) const { + auto GetNestedValueRepr(SemIR::TypeId nested_type_id) const { CARBON_CHECK(context_.sem_ir().IsTypeComplete(nested_type_id)) << "Nested type should already be complete"; - auto value_rep = context_.sem_ir().GetValueRepresentation(nested_type_id); - CARBON_CHECK(value_rep.kind != SemIR::ValueRepresentation::Unknown) + auto value_rep = context_.sem_ir().GetValueRepr(nested_type_id); + CARBON_CHECK(value_rep.kind != SemIR::ValueRepr::Unknown) << "Complete type should have a value representation"; return value_rep; }; - auto BuildCrossRefValueRepresentation(SemIR::TypeId type_id, - SemIR::CrossRef xref) const - -> SemIR::ValueRepresentation { + auto BuildCrossRefValueRepr(SemIR::TypeId type_id, SemIR::CrossRef xref) const + -> SemIR::ValueRepr { auto xref_inst = context_.cross_ref_irs().Get(xref.ir_id)->insts().Get(xref.inst_id); @@ -723,25 +716,25 @@ class TypeCompleter { case SemIR::BuiltinKind::NamespaceType: case SemIR::BuiltinKind::FunctionType: case SemIR::BuiltinKind::BoundMethodType: - return MakeCopyRepresentation(type_id); + return MakeCopyValueRepr(type_id); case SemIR::BuiltinKind::StringType: // TODO: Decide on string value semantics. This should probably be a // custom value representation carrying a pointer and size or // similar. - return MakePointerRepresentation(Parse::NodeId::Invalid, type_id); + return MakePointerValueRepr(Parse::NodeId::Invalid, type_id); } llvm_unreachable("All builtin kinds were handled above"); } - auto BuildStructOrTupleValueRepresentation(Parse::NodeId parse_node, - std::size_t num_elements, - SemIR::TypeId elementwise_rep, - bool same_as_object_rep) const - -> SemIR::ValueRepresentation { - SemIR::ValueRepresentation::AggregateKind aggregate_kind = - same_as_object_rep ? SemIR::ValueRepresentation::ValueAndObjectAggregate - : SemIR::ValueRepresentation::ValueAggregate; + auto BuildStructOrTupleValueRepr(Parse::NodeId parse_node, + std::size_t num_elements, + SemIR::TypeId elementwise_rep, + bool same_as_object_rep) const + -> SemIR::ValueRepr { + SemIR::ValueRepr::AggregateKind aggregate_kind = + same_as_object_rep ? SemIR::ValueRepr::ValueAndObjectAggregate + : SemIR::ValueRepr::ValueAggregate; if (num_elements == 1) { // The value representation for a struct or tuple with a single element @@ -749,21 +742,20 @@ class TypeCompleter { // element. // TODO: Consider doing the same whenever `elementwise_rep` is // sufficiently small. - return MakeCopyRepresentation(elementwise_rep, aggregate_kind); + return MakeCopyValueRepr(elementwise_rep, aggregate_kind); } // For a struct or tuple with multiple fields, we use a pointer // to the elementwise value representation. - return MakePointerRepresentation(parse_node, elementwise_rep, - aggregate_kind); + return MakePointerValueRepr(parse_node, elementwise_rep, aggregate_kind); } - auto BuildStructTypeValueRepresentation(SemIR::TypeId type_id, - SemIR::StructType struct_type) const - -> SemIR::ValueRepresentation { + auto BuildStructTypeValueRepr(SemIR::TypeId type_id, + SemIR::StructType struct_type) const + -> SemIR::ValueRepr { // TODO: Share more code with tuples. auto fields = context_.inst_blocks().Get(struct_type.fields_id); if (fields.empty()) { - return MakeEmptyRepresentation(struct_type.parse_node); + return MakeEmptyValueRepr(struct_type.parse_node); } // Find the value representation for each field, and construct a struct @@ -773,7 +765,7 @@ class TypeCompleter { bool same_as_object_rep = true; for (auto field_id : fields) { auto field = context_.insts().GetAs(field_id); - auto field_value_rep = GetNestedValueRepresentation(field.field_type_id); + auto field_value_rep = GetNestedValueRepr(field.field_type_id); if (field_value_rep.type_id != field.field_type_id) { same_as_object_rep = false; field.field_type_id = field_value_rep.type_id; @@ -787,17 +779,17 @@ class TypeCompleter { : context_.CanonicalizeStructType( struct_type.parse_node, context_.inst_blocks().Add(value_rep_fields)); - return BuildStructOrTupleValueRepresentation( - struct_type.parse_node, fields.size(), value_rep, same_as_object_rep); + return BuildStructOrTupleValueRepr(struct_type.parse_node, fields.size(), + value_rep, same_as_object_rep); } - auto BuildTupleTypeValueRepresentation(SemIR::TypeId type_id, - SemIR::TupleType tuple_type) const - -> SemIR::ValueRepresentation { + auto BuildTupleTypeValueRepr(SemIR::TypeId type_id, + SemIR::TupleType tuple_type) const + -> SemIR::ValueRepr { // TODO: Share more code with structs. auto elements = context_.type_blocks().Get(tuple_type.elements_id); if (elements.empty()) { - return MakeEmptyRepresentation(tuple_type.parse_node); + return MakeEmptyValueRepr(tuple_type.parse_node); } // Find the value representation for each element, and construct a tuple @@ -806,7 +798,7 @@ class TypeCompleter { value_rep_elements.reserve(elements.size()); bool same_as_object_rep = true; for (auto element_type_id : elements) { - auto element_value_rep = GetNestedValueRepresentation(element_type_id); + auto element_value_rep = GetNestedValueRepr(element_type_id); if (element_value_rep.type_id != element_type_id) { same_as_object_rep = false; } @@ -817,14 +809,14 @@ class TypeCompleter { ? type_id : context_.CanonicalizeTupleType(tuple_type.parse_node, value_rep_elements); - return BuildStructOrTupleValueRepresentation( - tuple_type.parse_node, elements.size(), value_rep, same_as_object_rep); + return BuildStructOrTupleValueRepr(tuple_type.parse_node, elements.size(), + value_rep, same_as_object_rep); } // Builds and returns the value representation for the given type. All nested // types, as found by AddNestedIncompleteTypes, are known to be complete. - auto BuildValueRepresentation(SemIR::TypeId type_id, SemIR::Inst inst) const - -> SemIR::ValueRepresentation { + auto BuildValueRepr(SemIR::TypeId type_id, SemIR::Inst inst) const + -> SemIR::ValueRepr { // TODO: This can emit new SemIR instructions. Consider emitting them into a // dedicated file-scope instruction block where possible, or somewhere else // that better reflects the definition of the type, rather than wherever the @@ -887,50 +879,45 @@ class TypeCompleter { CARBON_FATAL() << "Type refers to non-type inst " << inst; case SemIR::CrossRef::Kind: - return BuildCrossRefValueRepresentation(type_id, - inst.As()); + return BuildCrossRefValueRepr(type_id, inst.As()); case SemIR::ArrayType::Kind: { // For arrays, it's convenient to always use a pointer representation, // even when the array has zero or one element, in order to support // indexing. - return MakePointerRepresentation( - inst.parse_node(), type_id, - SemIR::ValueRepresentation::ObjectAggregate); + return MakePointerValueRepr(inst.parse_node(), type_id, + SemIR::ValueRepr::ObjectAggregate); } case SemIR::StructType::Kind: - return BuildStructTypeValueRepresentation(type_id, - inst.As()); + return BuildStructTypeValueRepr(type_id, inst.As()); case SemIR::TupleType::Kind: - return BuildTupleTypeValueRepresentation(type_id, - inst.As()); + return BuildTupleTypeValueRepr(type_id, inst.As()); case SemIR::ClassType::Kind: // The value representation for a class is a pointer to the object // representation. // TODO: Support customized value representations for classes. // TODO: Pick a better value representation when possible. - return MakePointerRepresentation( + return MakePointerValueRepr( inst.parse_node(), context_.classes() .Get(inst.As().class_id) - .object_representation_id, - SemIR::ValueRepresentation::ObjectAggregate); + .object_repr_id, + SemIR::ValueRepr::ObjectAggregate); case SemIR::Builtin::Kind: CARBON_FATAL() << "Builtins should be named as cross-references"; case SemIR::PointerType::Kind: case SemIR::UnboundElementType::Kind: - return MakeCopyRepresentation(type_id); + return MakeCopyValueRepr(type_id); case SemIR::ConstType::Kind: // The value representation of `const T` is the same as that of `T`. // Objects are not modifiable through their value representations. - return GetNestedValueRepresentation( - inst.As().inner_id); + return GetNestedValueRepr(inst.As().inner_id); } } @@ -938,7 +925,7 @@ class TypeCompleter { // The next step is to add nested types to the list of types to complete. AddNestedIncompleteTypes, // The next step is to build the value representation for the type. - BuildValueRepresentation, + BuildValueRepr, }; struct WorkItem { diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 18b2dd4b4e54..443cfd43a708 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -48,8 +48,7 @@ static auto FindReturnSlotForInitializer(SemIR::File& sem_ir, case SemIR::Call::Kind: { auto call = init.As(); - if (!SemIR::GetInitializingRepresentation(sem_ir, call.type_id) - .has_return_slot()) { + if (!SemIR::GetInitRepr(sem_ir, call.type_id).has_return_slot()) { return SemIR::InstId::Invalid; } return sem_ir.inst_blocks().Get(call.args_id).back(); @@ -353,8 +352,8 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type, bool is_init = target.is_initializer(); ConversionTarget::Kind inner_kind = !is_init ? ConversionTarget::Value - : SemIR::GetInitializingRepresentation(sem_ir, target.type_id).kind == - SemIR::InitializingRepresentation::InPlace + : SemIR::GetInitRepr(sem_ir, target.type_id).kind == + SemIR::InitRepr::InPlace ? ConversionTarget::FullInitializer : ConversionTarget::Initializer; @@ -444,8 +443,8 @@ static auto ConvertStructToStructOrClass(Context& context, bool is_init = target.is_initializer(); ConversionTarget::Kind inner_kind = !is_init ? ConversionTarget::Value - : SemIR::GetInitializingRepresentation(sem_ir, target.type_id).kind == - SemIR::InitializingRepresentation::InPlace + : SemIR::GetInitRepr(sem_ir, target.type_id).kind == + SemIR::InitRepr::InPlace ? ConversionTarget::FullInitializer : ConversionTarget::Initializer; @@ -548,8 +547,7 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type, return SemIR::InstId::BuiltinError; } auto dest_struct_type = context.insts().GetAs( - context.sem_ir().GetTypeAllowBuiltinTypes( - class_info.object_representation_id)); + context.sem_ir().GetTypeAllowBuiltinTypes(class_info.object_repr_id)); // If we're trying to create a class value, form a temporary for the value to // point to. @@ -645,10 +643,10 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node, if (value_cat == SemIR::ExprCategory::Initializing && IsValidExprCategoryForConversionTarget(SemIR::ExprCategory::Value, target.kind) && - SemIR::GetInitializingRepresentation(sem_ir, value_type_id).kind == - SemIR::InitializingRepresentation::ByCopy) { - auto value_rep = SemIR::GetValueRepresentation(sem_ir, value_type_id); - if (value_rep.kind == SemIR::ValueRepresentation::Copy && + SemIR::GetInitRepr(sem_ir, value_type_id).kind == + SemIR::InitRepr::ByCopy) { + auto value_rep = SemIR::GetValueRepr(sem_ir, value_type_id); + if (value_rep.kind == SemIR::ValueRepr::Copy && value_rep.type_id == value_type_id) { // The initializer produces an object representation by copy, and the // value representation is a copy of the object representation, so we @@ -747,9 +745,9 @@ static auto PerformCopy(Context& context, SemIR::InstId expr_id) // TODO: Directly track on the value representation whether it's a copy of // the object representation. - auto value_rep = SemIR::GetValueRepresentation(context.sem_ir(), type_id); - if (value_rep.kind == SemIR::ValueRepresentation::Copy && - value_rep.aggregate_kind == SemIR::ValueRepresentation::NotAggregate && + auto value_rep = SemIR::GetValueRepr(context.sem_ir(), type_id); + if (value_rep.kind == SemIR::ValueRepr::Copy && + value_rep.aggregate_kind == SemIR::ValueRepr::NotAggregate && value_rep.type_id == type_id) { // For by-value scalar types, no explicit action is required. Initializing // from a value expression is treated as copying the value. @@ -905,9 +903,8 @@ auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id, // Perform a final destination store, if necessary. if (target.kind == ConversionTarget::FullInitializer) { - if (auto init_rep = - SemIR::GetInitializingRepresentation(sem_ir, target.type_id); - init_rep.kind == SemIR::InitializingRepresentation::ByCopy) { + 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(SemIR::InitializeFrom{ parse_node, target.type_id, expr_id, target.init_id}); diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index e2d13589b37d..a4b0f3e6001b 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -280,7 +280,7 @@ auto HandleClassDefinition(Context& context, Parse::NodeId parse_node) -> bool { // The class type is now fully defined. auto& class_info = context.classes().Get(class_id); - class_info.object_representation_id = + class_info.object_repr_id = context.CanonicalizeStructType(parse_node, fields_id); return true; } diff --git a/toolchain/check/handle_function.cpp b/toolchain/check/handle_function.cpp index 415d60e73a95..0879d18f054e 100644 --- a/toolchain/check/handle_function.cpp +++ b/toolchain/check/handle_function.cpp @@ -71,8 +71,7 @@ static auto BuildFunctionDecl(Context& context, bool is_definition) context.sem_ir().StringifyType(return_type_id)); })) { return_type_id = SemIR::TypeId::Error; - } else if (!SemIR::GetInitializingRepresentation(context.sem_ir(), - return_type_id) + } else if (!SemIR::GetInitRepr(context.sem_ir(), return_type_id) .has_return_slot()) { // The function only has a return slot if it uses in-place initialization. } else { diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index a7b8ef0959f1..12300c929db0 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -81,12 +81,10 @@ auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id) sem_ir().inst_blocks().Get(function.implicit_param_refs_id); auto param_refs = sem_ir().inst_blocks().Get(function.param_refs_id); - SemIR::InitializingRepresentation return_rep = + SemIR::InitRepr return_rep = function.return_type_id.is_valid() - ? SemIR::GetInitializingRepresentation(sem_ir(), - function.return_type_id) - : SemIR::InitializingRepresentation{ - .kind = SemIR::InitializingRepresentation::None}; + ? SemIR::GetInitRepr(sem_ir(), function.return_type_id) + : SemIR::InitRepr{.kind = SemIR::InitRepr::None}; CARBON_CHECK(return_rep.has_return_slot() == has_return_slot); llvm::SmallVector param_types; @@ -106,17 +104,16 @@ auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id) for (auto param_ref_id : llvm::concat(implicit_param_refs, param_refs)) { auto param_type_id = sem_ir().insts().Get(param_ref_id).type_id(); - switch (auto value_rep = - SemIR::GetValueRepresentation(sem_ir(), param_type_id); + switch (auto value_rep = SemIR::GetValueRepr(sem_ir(), param_type_id); value_rep.kind) { - case SemIR::ValueRepresentation::Unknown: + case SemIR::ValueRepr::Unknown: CARBON_FATAL() << "Incomplete parameter type lowering function declaration"; - case SemIR::ValueRepresentation::None: + case SemIR::ValueRepr::None: break; - case SemIR::ValueRepresentation::Copy: - case SemIR::ValueRepresentation::Custom: - case SemIR::ValueRepresentation::Pointer: + case SemIR::ValueRepr::Copy: + case SemIR::ValueRepr::Custom: + case SemIR::ValueRepr::Pointer: param_types.push_back(GetType(value_rep.type_id)); param_inst_ids.push_back(param_ref_id); break; @@ -125,10 +122,9 @@ auto FileContext::BuildFunctionDecl(SemIR::FunctionId function_id) // If the initializing representation doesn't produce a value, set the return // type to void. - llvm::Type* return_type = - return_rep.kind == SemIR::InitializingRepresentation::ByCopy - ? GetType(function.return_type_id) - : llvm::Type::getVoidTy(llvm_context()); + llvm::Type* return_type = return_rep.kind == SemIR::InitRepr::ByCopy + ? GetType(function.return_type_id) + : llvm::Type::getVoidTy(llvm_context()); std::string mangled_name; if (SemIR::IsEntryPoint(sem_ir(), function_id)) { @@ -199,8 +195,8 @@ auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id) for (auto param_ref_id : llvm::concat(implicit_param_refs, param_refs)) { auto param_type_id = sem_ir().insts().Get(param_ref_id).type_id(); - if (SemIR::GetValueRepresentation(sem_ir(), param_type_id).kind == - SemIR::ValueRepresentation::None) { + if (SemIR::GetValueRepr(sem_ir(), param_type_id).kind == + SemIR::ValueRepr::None) { function_lowering.SetLocal( param_ref_id, llvm::PoisonValue::get(GetType(param_type_id))); } else { @@ -260,11 +256,10 @@ auto FileContext::BuildType(SemIR::InstId inst_id) -> llvm::Type* { sem_ir_->GetArrayBoundValue(array_type.bound_id)); } case SemIR::ClassType::Kind: { - auto object_representation_id = - sem_ir_->classes() - .Get(inst.As().class_id) - .object_representation_id; - return GetType(object_representation_id); + auto object_repr_id = sem_ir_->classes() + .Get(inst.As().class_id) + .object_repr_id; + return GetType(object_repr_id); } case SemIR::ConstType::Kind: return GetType(inst.As().inner_id); diff --git a/toolchain/lower/function_context.cpp b/toolchain/lower/function_context.cpp index 891e224c8f4a..7246d013eede 100644 --- a/toolchain/lower/function_context.cpp +++ b/toolchain/lower/function_context.cpp @@ -80,11 +80,11 @@ auto FunctionContext::CreateSyntheticBlock() -> llvm::BasicBlock* { auto FunctionContext::FinishInit(SemIR::TypeId type_id, SemIR::InstId dest_id, SemIR::InstId source_id) -> void { - switch (SemIR::GetInitializingRepresentation(sem_ir(), type_id).kind) { - case SemIR::InitializingRepresentation::None: - case SemIR::InitializingRepresentation::InPlace: + switch (SemIR::GetInitRepr(sem_ir(), type_id).kind) { + case SemIR::InitRepr::None: + case SemIR::InitRepr::InPlace: break; - case SemIR::InitializingRepresentation::ByCopy: + case SemIR::InitRepr::ByCopy: CopyValue(type_id, source_id, dest_id); break; } @@ -92,16 +92,15 @@ auto FunctionContext::FinishInit(SemIR::TypeId type_id, SemIR::InstId dest_id, auto FunctionContext::CopyValue(SemIR::TypeId type_id, SemIR::InstId source_id, SemIR::InstId dest_id) -> void { - switch (auto rep = SemIR::GetValueRepresentation(sem_ir(), type_id); - rep.kind) { - case SemIR::ValueRepresentation::Unknown: + switch (auto rep = SemIR::GetValueRepr(sem_ir(), type_id); rep.kind) { + case SemIR::ValueRepr::Unknown: CARBON_FATAL() << "Attempt to copy incomplete type"; - case SemIR::ValueRepresentation::None: + case SemIR::ValueRepr::None: break; - case SemIR::ValueRepresentation::Copy: + case SemIR::ValueRepr::Copy: builder().CreateStore(GetValue(source_id), GetValue(dest_id)); break; - case SemIR::ValueRepresentation::Pointer: { + case SemIR::ValueRepr::Pointer: { const auto& layout = llvm_module().getDataLayout(); auto* type = GetType(type_id); // TODO: Compute known alignment of the source and destination, which may @@ -114,7 +113,7 @@ auto FunctionContext::CopyValue(SemIR::TypeId type_id, SemIR::InstId source_id, align, layout.getTypeAllocSize(type)); break; } - case SemIR::ValueRepresentation::Custom: + case SemIR::ValueRepr::Custom: CARBON_FATAL() << "TODO: Add support for CopyValue with custom value rep"; } } diff --git a/toolchain/lower/handle.cpp b/toolchain/lower/handle.cpp index 12ed7e00837e..66ed94518f6e 100644 --- a/toolchain/lower/handle.cpp +++ b/toolchain/lower/handle.cpp @@ -144,16 +144,15 @@ auto HandleCall(FunctionContext& context, SemIR::InstId inst_id, llvm::ArrayRef arg_ids = context.sem_ir().inst_blocks().Get(inst.args_id); - if (SemIR::GetInitializingRepresentation(context.sem_ir(), inst.type_id) - .has_return_slot()) { + if (SemIR::GetInitRepr(context.sem_ir(), inst.type_id).has_return_slot()) { args.push_back(context.GetValue(arg_ids.back())); arg_ids = arg_ids.drop_back(); } for (auto arg_id : arg_ids) { auto arg_type_id = context.sem_ir().insts().Get(arg_id).type_id(); - if (SemIR::GetValueRepresentation(context.sem_ir(), arg_type_id).kind != - SemIR::ValueRepresentation::None) { + if (SemIR::GetValueRepr(context.sem_ir(), arg_type_id).kind != + SemIR::ValueRepr::None) { args.push_back(context.GetValue(arg_id)); } } @@ -256,16 +255,16 @@ auto HandleReturn(FunctionContext& context, SemIR::InstId /*inst_id*/, auto HandleReturnExpr(FunctionContext& context, SemIR::InstId /*inst_id*/, SemIR::ReturnExpr inst) -> void { - switch (SemIR::GetInitializingRepresentation( - context.sem_ir(), - context.sem_ir().insts().Get(inst.expr_id).type_id()) - .kind) { - case SemIR::InitializingRepresentation::None: - case SemIR::InitializingRepresentation::InPlace: + switch ( + SemIR::GetInitRepr(context.sem_ir(), + context.sem_ir().insts().Get(inst.expr_id).type_id()) + .kind) { + case SemIR::InitRepr::None: + case SemIR::InitRepr::InPlace: // Nothing to return. context.builder().CreateRetVoid(); return; - case SemIR::InitializingRepresentation::ByCopy: + case SemIR::InitRepr::ByCopy: // The expression produces the value representation for the type. context.builder().CreateRet(context.GetValue(inst.expr_id)); return; diff --git a/toolchain/lower/handle_aggregates.cpp b/toolchain/lower/handle_aggregates.cpp index d1d311082f4a..503e07fe4f97 100644 --- a/toolchain/lower/handle_aggregates.cpp +++ b/toolchain/lower/handle_aggregates.cpp @@ -37,20 +37,19 @@ static auto GetAggregateElement(FunctionContext& context, case SemIR::ExprCategory::Value: { auto value_rep = - SemIR::GetValueRepresentation(context.sem_ir(), aggr_inst.type_id()); - CARBON_CHECK(value_rep.aggregate_kind != - SemIR::ValueRepresentation::NotAggregate) + SemIR::GetValueRepr(context.sem_ir(), aggr_inst.type_id()); + CARBON_CHECK(value_rep.aggregate_kind != SemIR::ValueRepr::NotAggregate) << "aggregate type should have aggregate value representation"; switch (value_rep.kind) { - case SemIR::ValueRepresentation::Unknown: + case SemIR::ValueRepr::Unknown: CARBON_FATAL() << "Lowering access to incomplete aggregate type"; - case SemIR::ValueRepresentation::None: + case SemIR::ValueRepr::None: return aggr_value; - case SemIR::ValueRepresentation::Copy: + case SemIR::ValueRepr::Copy: // We are holding the values of the aggregate directly, elementwise. return context.builder().CreateExtractValue(aggr_value, idx.index, name); - case SemIR::ValueRepresentation::Pointer: { + case SemIR::ValueRepr::Pointer: { // The value representation is a pointer to an aggregate that we want // to index into. auto pointee_type_id = @@ -67,12 +66,11 @@ static auto GetAggregateElement(FunctionContext& context, // `elem_ptr` points to a value representation. Load it. auto result_value_type_id = - SemIR::GetValueRepresentation(context.sem_ir(), result_type_id) - .type_id; + SemIR::GetValueRepr(context.sem_ir(), result_type_id).type_id; return context.builder().CreateLoad( context.GetType(result_value_type_id), elem_ptr, name + ".load"); } - case SemIR::ValueRepresentation::Custom: + case SemIR::ValueRepr::Custom: CARBON_FATAL() << "Aggregate should never have custom value representation"; } @@ -120,8 +118,7 @@ auto HandleClassElementAccess(FunctionContext& context, SemIR::InstId inst_id, inst_id, GetAggregateElement( context, inst.base_id, inst.index, inst.type_id, - GetStructFieldName(context, class_info.object_representation_id, - inst.index))); + GetStructFieldName(context, class_info.object_repr_id, inst.index))); } static auto EmitAggregateInitializer(FunctionContext& context, @@ -130,14 +127,13 @@ static auto EmitAggregateInitializer(FunctionContext& context, llvm::Twine name) -> llvm::Value* { auto* llvm_type = context.GetType(type_id); - switch ( - SemIR::GetInitializingRepresentation(context.sem_ir(), type_id).kind) { - case SemIR::InitializingRepresentation::None: - case SemIR::InitializingRepresentation::InPlace: + switch (SemIR::GetInitRepr(context.sem_ir(), type_id).kind) { + case SemIR::InitRepr::None: + case SemIR::InitRepr::InPlace: // TODO: Add a helper to poison a value slot. return llvm::PoisonValue::get(llvm_type); - case SemIR::InitializingRepresentation::ByCopy: { + case SemIR::InitRepr::ByCopy: { auto refs = context.sem_ir().inst_blocks().Get(refs_id); CARBON_CHECK(refs.size() == 1) << "Unexpected size for aggregate with by-copy value representation"; @@ -185,20 +181,19 @@ auto HandleStructLiteral(FunctionContext& /*context*/, // Emits the value representation for a struct or tuple whose elements are the // contents of `refs_id`. -auto EmitAggregateValueRepresentation(FunctionContext& context, - SemIR::TypeId type_id, - SemIR::InstBlockId refs_id, - llvm::Twine name) -> llvm::Value* { - auto value_rep = SemIR::GetValueRepresentation(context.sem_ir(), type_id); +auto EmitAggregateValueRepr(FunctionContext& context, SemIR::TypeId type_id, + SemIR::InstBlockId refs_id, llvm::Twine name) + -> llvm::Value* { + auto value_rep = SemIR::GetValueRepr(context.sem_ir(), type_id); switch (value_rep.kind) { - case SemIR::ValueRepresentation::Unknown: + case SemIR::ValueRepr::Unknown: CARBON_FATAL() << "Incomplete aggregate type in lowering"; - case SemIR::ValueRepresentation::None: + case SemIR::ValueRepr::None: // TODO: Add a helper to get a "no value representation" value. return llvm::PoisonValue::get(context.GetType(value_rep.type_id)); - case SemIR::ValueRepresentation::Copy: { + case SemIR::ValueRepr::Copy: { auto refs = context.sem_ir().inst_blocks().Get(refs_id); CARBON_CHECK(refs.size() == 1) << "Unexpected size for aggregate with by-copy value representation"; @@ -209,7 +204,7 @@ auto EmitAggregateValueRepresentation(FunctionContext& context, context.GetValue(refs[0]), {0}); } - case SemIR::ValueRepresentation::Pointer: { + case SemIR::ValueRepr::Pointer: { auto pointee_type_id = context.sem_ir().GetPointeeType(value_rep.type_id); auto* llvm_value_rep_type = context.GetType(pointee_type_id); @@ -227,7 +222,7 @@ auto EmitAggregateValueRepresentation(FunctionContext& context, return alloca; } - case SemIR::ValueRepresentation::Custom: + case SemIR::ValueRepr::Custom: CARBON_FATAL() << "Aggregate should never have custom value representation"; } @@ -242,9 +237,8 @@ auto HandleStructInit(FunctionContext& context, SemIR::InstId inst_id, auto HandleStructValue(FunctionContext& context, SemIR::InstId inst_id, SemIR::StructValue inst) -> void { - context.SetLocal( - inst_id, EmitAggregateValueRepresentation(context, inst.type_id, - inst.elements_id, "struct")); + context.SetLocal(inst_id, EmitAggregateValueRepr(context, inst.type_id, + inst.elements_id, "struct")); } auto HandleStructTypeField(FunctionContext& /*context*/, @@ -285,9 +279,8 @@ auto HandleTupleInit(FunctionContext& context, SemIR::InstId inst_id, auto HandleTupleValue(FunctionContext& context, SemIR::InstId inst_id, SemIR::TupleValue inst) -> void { - context.SetLocal(inst_id, - EmitAggregateValueRepresentation(context, inst.type_id, - inst.elements_id, "tuple")); + context.SetLocal(inst_id, EmitAggregateValueRepr(context, inst.type_id, + inst.elements_id, "tuple")); } } // namespace Carbon::Lower diff --git a/toolchain/lower/handle_expr_category.cpp b/toolchain/lower/handle_expr_category.cpp index b023cabc498c..eacb4cfcfc85 100644 --- a/toolchain/lower/handle_expr_category.cpp +++ b/toolchain/lower/handle_expr_category.cpp @@ -9,28 +9,27 @@ namespace Carbon::Lower { auto HandleBindValue(FunctionContext& context, SemIR::InstId inst_id, SemIR::BindValue inst) -> void { - switch (auto rep = - SemIR::GetValueRepresentation(context.sem_ir(), inst.type_id); + switch (auto rep = SemIR::GetValueRepr(context.sem_ir(), inst.type_id); rep.kind) { - case SemIR::ValueRepresentation::Unknown: + case SemIR::ValueRepr::Unknown: CARBON_FATAL() << "Value binding for type with incomplete value representation"; - case SemIR::ValueRepresentation::None: + case SemIR::ValueRepr::None: // Nothing should use this value, but StubRef needs a value to // propagate. // TODO: Remove this now the StubRefs are gone. context.SetLocal(inst_id, llvm::PoisonValue::get(context.GetType(inst.type_id))); break; - case SemIR::ValueRepresentation::Copy: + case SemIR::ValueRepr::Copy: context.SetLocal(inst_id, context.builder().CreateLoad( context.GetType(inst.type_id), context.GetValue(inst.value_id))); break; - case SemIR::ValueRepresentation::Pointer: + case SemIR::ValueRepr::Pointer: context.SetLocal(inst_id, context.GetValue(inst.value_id)); break; - case SemIR::ValueRepresentation::Custom: + case SemIR::ValueRepr::Custom: CARBON_FATAL() << "TODO: Add support for BindValue with custom value rep"; } } @@ -52,9 +51,8 @@ auto HandleValueAsRef(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::GetValueRepresentation(context.sem_ir(), inst.type_id).kind == - SemIR::ValueRepresentation::Pointer); + CARBON_CHECK(SemIR::GetValueRepr(context.sem_ir(), inst.type_id).kind == + SemIR::ValueRepr::Pointer); context.SetLocal(inst_id, context.GetValue(inst.value_id)); } @@ -62,12 +60,10 @@ auto HandleValueOfInitializer(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::GetValueRepresentation(context.sem_ir(), inst.type_id).kind == - SemIR::ValueRepresentation::Copy); - CARBON_CHECK( - SemIR::GetInitializingRepresentation(context.sem_ir(), inst.type_id) - .kind == SemIR::InitializingRepresentation::ByCopy); + CARBON_CHECK(SemIR::GetValueRepr(context.sem_ir(), inst.type_id).kind == + SemIR::ValueRepr::Copy); + CARBON_CHECK(SemIR::GetInitRepr(context.sem_ir(), inst.type_id).kind == + SemIR::InitRepr::ByCopy); context.SetLocal(inst_id, context.GetValue(inst.init_id)); } diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index 10aed08c2015..6fcee8fc27b9 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -16,7 +16,7 @@ namespace Carbon::SemIR { -auto ValueRepresentation::Print(llvm::raw_ostream& out) const -> void { +auto ValueRepr::Print(llvm::raw_ostream& out) const -> void { out << "{kind: "; switch (kind) { case Unknown: @@ -39,7 +39,7 @@ auto ValueRepresentation::Print(llvm::raw_ostream& out) const -> void { } auto TypeInfo::Print(llvm::raw_ostream& out) const -> void { - out << "{inst: " << inst_id << ", value_rep: " << value_representation << "}"; + out << "{inst: " << inst_id << ", value_rep: " << value_repr << "}"; } File::File(SharedValueStores& value_stores) @@ -585,23 +585,22 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory { } } -auto GetInitializingRepresentation(const File& file, TypeId type_id) - -> InitializingRepresentation { - auto value_rep = GetValueRepresentation(file, type_id); +auto GetInitRepr(const File& file, TypeId type_id) -> InitRepr { + auto value_rep = GetValueRepr(file, type_id); switch (value_rep.kind) { - case ValueRepresentation::None: - return {.kind = InitializingRepresentation::None}; + case ValueRepr::None: + return {.kind = InitRepr::None}; - case ValueRepresentation::Copy: + case ValueRepr::Copy: // TODO: Use in-place initialization for types that have non-trivial // destructive move. - return {.kind = InitializingRepresentation::ByCopy}; + return {.kind = InitRepr::ByCopy}; - case ValueRepresentation::Pointer: - case ValueRepresentation::Custom: - return {.kind = InitializingRepresentation::InPlace}; + case ValueRepr::Pointer: + case ValueRepr::Custom: + return {.kind = InitRepr::InPlace}; - case ValueRepresentation::Unknown: + case ValueRepr::Unknown: CARBON_FATAL() << "Attempting to perform initialization of incomplete type"; } diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index 2baa2f2badde..4f9e644d9565 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -78,9 +78,7 @@ struct Class : public Printable { // Determines whether this class has been fully defined. This is false until // we reach the `}` of the class definition. - auto is_defined() const -> bool { - return object_representation_id.is_valid(); - } + auto is_defined() const -> bool { return object_repr_id.is_valid(); } // The following members always have values, and do not change throughout the // lifetime of the class. @@ -115,11 +113,11 @@ struct Class : public Printable { // The object representation type to use for this class. This is valid once // the class is defined. - TypeId object_representation_id = TypeId::Invalid; + TypeId object_repr_id = TypeId::Invalid; }; // The value representation to use when passing by value. -struct ValueRepresentation : public Printable { +struct ValueRepr : public Printable { auto Print(llvm::raw_ostream& out) const -> void; enum Kind : int8_t { @@ -178,7 +176,7 @@ struct TypeInfo : public Printable { InstId inst_id; // The value representation for this type. Will be `Unknown` if the type is // not complete. - ValueRepresentation value_representation = ValueRepresentation(); + ValueRepr value_repr = ValueRepr(); }; // Provides semantic analysis on a Parse::Tree. @@ -213,16 +211,15 @@ class File : public Printable { } // Marks a type as complete, and sets its value representation. - auto CompleteType(TypeId object_type_id, - ValueRepresentation value_representation) -> void { + auto CompleteType(TypeId object_type_id, ValueRepr value_repr) -> void { if (object_type_id.index < 0) { // We already know our builtin types are complete. return; } - CARBON_CHECK(types().Get(object_type_id).value_representation.kind == - ValueRepresentation::Unknown) + CARBON_CHECK(types().Get(object_type_id).value_repr.kind == + ValueRepr::Unknown) << "Type " << object_type_id << " completed more than once"; - types().Get(object_type_id).value_representation = value_representation; + types().Get(object_type_id).value_repr = value_repr; complete_types_.push_back(object_type_id); } @@ -240,18 +237,18 @@ class File : public Printable { // Gets the value representation to use for a type. This returns an // invalid type if the given type is not complete. - auto GetValueRepresentation(TypeId type_id) const -> ValueRepresentation { + auto GetValueRepr(TypeId type_id) const -> ValueRepr { if (type_id.index < 0) { // TypeType and InvalidType are their own value representation. - return {.kind = ValueRepresentation::Copy, .type_id = type_id}; + return {.kind = ValueRepr::Copy, .type_id = type_id}; } - return types().Get(type_id).value_representation; + return types().Get(type_id).value_repr; } // Determines whether the given type is known to be complete. This does not // determine whether the type could be completed, only whether it has been. auto IsTypeComplete(TypeId type_id) const -> bool { - return GetValueRepresentation(type_id).kind != ValueRepresentation::Unknown; + return GetValueRepr(type_id).kind != ValueRepr::Unknown; } // Gets the pointee type of the given type, which must be a pointer type. @@ -420,13 +417,12 @@ enum class ExprCategory : int8_t { auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory; // Returns information about the value representation to use for a type. -inline auto GetValueRepresentation(const File& file, TypeId type_id) - -> ValueRepresentation { - return file.GetValueRepresentation(type_id); +inline auto GetValueRepr(const File& file, TypeId type_id) -> ValueRepr { + return file.GetValueRepr(type_id); } // The initializing representation to use when returning by value. -struct InitializingRepresentation { +struct InitRepr { enum Kind : int8_t { // The type has no initializing representation. This is used for empty // types, where no initialization is necessary. @@ -449,8 +445,7 @@ struct InitializingRepresentation { }; // Returns information about the initializing representation to use for a type. -auto GetInitializingRepresentation(const File& file, TypeId type_id) - -> InitializingRepresentation; +auto GetInitRepr(const File& file, TypeId type_id) -> InitRepr; } // namespace Carbon::SemIR diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index 38f053fe4f12..ada8f847461c 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -789,8 +789,7 @@ class Formatter { llvm::ArrayRef args = sem_ir_.inst_blocks().Get(inst.args_id); - bool has_return_slot = - GetInitializingRepresentation(sem_ir_, inst.type_id).has_return_slot(); + bool has_return_slot = GetInitRepr(sem_ir_, inst.type_id).has_return_slot(); InstId return_slot_id = InstId::Invalid; if (has_return_slot) { return_slot_id = args.back();