فهرست منبع

Finish removing BuiltinInstKind (#4637)

Jon Ross-Perkins 1 سال پیش
والد
کامیت
1cba3328f7

+ 2 - 3
toolchain/check/call.cpp

@@ -11,7 +11,6 @@
 #include "toolchain/check/function.h"
 #include "toolchain/diagnostics/format_providers.h"
 #include "toolchain/sem_ir/builtin_function_kind.h"
-#include "toolchain/sem_ir/builtin_inst_kind.h"
 #include "toolchain/sem_ir/entity_with_params_base.h"
 #include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/inst.h"
@@ -162,8 +161,8 @@ auto PerformCall(Context& context, SemIR::LocId loc_id, SemIR::InstId callee_id,
     callee_id = context.GetOrAddInst(
         context.insts().GetLocId(callee_id),
         SemIR::SpecificFunction{
-            .type_id = context.GetBuiltinType(
-                SemIR::BuiltinInstKind::SpecificFunctionType),
+            .type_id = context.GetSingletonType(
+                SemIR::SpecificFunctionType::SingletonInstId),
             .callee_id = callee_id,
             .specific_id = *callee_specific_id});
     context.definitions_required().push_back(callee_id);

+ 1 - 1
toolchain/check/check.cpp

@@ -319,7 +319,7 @@ static auto InitPackageScopeAndImports(Context& context, UnitInfo& unit_info,
 
   // Importing makes many namespaces, so only canonicalize the type once.
   auto namespace_type_id =
-      context.GetBuiltinType(SemIR::BuiltinInstKind::NamespaceType);
+      context.GetSingletonType(SemIR::NamespaceType::SingletonInstId);
 
   // Define the package scope, with an instruction for `package` expressions to
   // reference.

+ 3 - 3
toolchain/check/context.cpp

@@ -25,7 +25,6 @@
 #include "toolchain/lex/tokenized_buffer.h"
 #include "toolchain/parse/node_ids.h"
 #include "toolchain/parse/node_kind.h"
-#include "toolchain/sem_ir/builtin_inst_kind.h"
 #include "toolchain/sem_ir/file.h"
 #include "toolchain/sem_ir/formatter.h"
 #include "toolchain/sem_ir/generic.h"
@@ -1353,8 +1352,9 @@ auto Context::GetAssociatedEntityType(SemIR::TypeId interface_type_id,
                                                   entity_type_id);
 }
 
-auto Context::GetBuiltinType(SemIR::BuiltinInstKind kind) -> SemIR::TypeId {
-  auto type_id = GetTypeIdForTypeInst(SemIR::InstId::ForBuiltin(kind));
+auto Context::GetSingletonType(SemIR::InstId singleton_id) -> SemIR::TypeId {
+  CARBON_CHECK(SemIR::IsSingletonInstId(singleton_id));
+  auto type_id = GetTypeIdForTypeInst(singleton_id);
   // To keep client code simpler, complete builtin types before returning them.
   bool complete = TryToCompleteType(type_id);
   CARBON_CHECK(complete, "Failed to complete builtin type");

+ 3 - 2
toolchain/check/context.h

@@ -383,8 +383,9 @@ class Context {
   auto GetAssociatedEntityType(SemIR::TypeId interface_type_id,
                                SemIR::TypeId entity_type_id) -> SemIR::TypeId;
 
-  // Gets a builtin type. The returned type will be complete.
-  auto GetBuiltinType(SemIR::BuiltinInstKind kind) -> SemIR::TypeId;
+  // Gets a singleton type. The returned type will be complete. Requires that
+  // `singleton_id` is already validated to be a singleton.
+  auto GetSingletonType(SemIR::InstId singleton_id) -> SemIR::TypeId;
 
   // Gets a function type. The returned type will be complete.
   auto GetFunctionType(SemIR::FunctionId fn_id, SemIR::SpecificId specific_id)

+ 3 - 3
toolchain/check/convert.cpp

@@ -153,8 +153,8 @@ static auto MakeElementAccessInst(Context& context, SemIR::LocId loc_id,
     // index so that we don't need an integer literal instruction here, and
     // remove this special case.
     auto index_id = block.template AddInst<SemIR::IntValue>(
-        loc_id, {.type_id = context.GetBuiltinType(
-                     SemIR::BuiltinInstKind::IntLiteralType),
+        loc_id, {.type_id = context.GetSingletonType(
+                     SemIR::IntLiteralType::SingletonInstId),
                  .int_id = context.ints().Add(static_cast<int64_t>(i))});
     return block.template AddInst<AccessInstT>(
         loc_id, {elem_type_id, aggregate_id, index_id});
@@ -1157,7 +1157,7 @@ auto ConvertToBoolValue(Context& context, SemIR::LocId loc_id,
                         SemIR::InstId value_id) -> SemIR::InstId {
   return ConvertToValueOfType(
       context, loc_id, value_id,
-      context.GetBuiltinType(SemIR::BuiltinInstKind::BoolType));
+      context.GetSingletonType(SemIR::BoolType::SingletonInstId));
 }
 
 auto ConvertForExplicitAs(Context& context, Parse::NodeId as_node,

+ 1 - 1
toolchain/check/eval.cpp

@@ -667,7 +667,7 @@ static auto MakeIntTypeResult(Context& context, SemIRLoc loc,
                               SemIR::IntKind int_kind, SemIR::InstId width_id,
                               Phase phase) -> SemIR::ConstantId {
   auto result = SemIR::IntType{
-      .type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::TypeType),
+      .type_id = context.GetSingletonType(SemIR::TypeType::SingletonInstId),
       .int_kind = int_kind,
       .bit_width_id = width_id};
   if (!ValidateIntType(context, loc, result)) {

+ 1 - 1
toolchain/check/handle_alias.cpp

@@ -46,7 +46,7 @@ auto HandleParseNode(Context& context, Parse::AliasId /*node_id*/) -> bool {
 
   auto alias_type_id = SemIR::TypeId::Invalid;
   auto alias_value_id = SemIR::InstId::Invalid;
-  if (expr_id.is_builtin()) {
+  if (SemIR::IsSingletonInstId(expr_id)) {
     // Type (`bool`) and value (`false`) literals provided by the builtin
     // structure should be turned into name references.
     // TODO: Look into handling `false`, this doesn't do it right now because it

+ 1 - 2
toolchain/check/handle_array.cpp

@@ -6,7 +6,6 @@
 #include "toolchain/check/convert.h"
 #include "toolchain/check/handle.h"
 #include "toolchain/parse/node_kind.h"
-#include "toolchain/sem_ir/builtin_inst_kind.h"
 
 namespace Carbon::Check {
 
@@ -52,7 +51,7 @@ auto HandleParseNode(Context& context, Parse::ArrayExprId node_id) -> bool {
 
   bound_inst_id = ConvertToValueOfType(
       context, context.insts().GetLocId(bound_inst_id), bound_inst_id,
-      context.GetBuiltinType(SemIR::BuiltinInstKind::IntLiteralType));
+      context.GetSingletonType(SemIR::IntLiteralType::SingletonInstId));
   context.AddInstAndPush<SemIR::ArrayType>(
       node_id, {.type_id = SemIR::TypeType::SingletonTypeId,
                 .bound_id = bound_inst_id,

+ 3 - 3
toolchain/check/handle_class.cpp

@@ -619,7 +619,7 @@ static auto CheckCompleteAdapterClassType(Context& context,
 
   return context.AddInst<SemIR::CompleteTypeWitness>(
       node_id,
-      {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType),
+      {.type_id = context.GetSingletonType(SemIR::WitnessType::SingletonInstId),
        .object_repr_id = object_repr_id});
 }
 
@@ -679,7 +679,7 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id,
     struct_type_fields.push_back(
         {.name_id = SemIR::NameId::Vptr,
          .type_id = context.GetPointerType(
-             context.GetBuiltinType(SemIR::BuiltinInstKind::VtableType))});
+             context.GetSingletonType(SemIR::VtableType::SingletonInstId))});
   }
   if (base_type_id.is_valid()) {
     auto base_decl = context.insts().GetAs<SemIR::BaseDecl>(class_info.base_id);
@@ -692,7 +692,7 @@ static auto CheckCompleteClassType(Context& context, Parse::NodeId node_id,
 
   return context.AddInst<SemIR::CompleteTypeWitness>(
       node_id,
-      {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType),
+      {.type_id = context.GetSingletonType(SemIR::WitnessType::SingletonInstId),
        .object_repr_id = context.GetStructType(
            AddStructTypeFields(context, struct_type_fields))});
 }

+ 1 - 2
toolchain/check/handle_function.cpp

@@ -467,8 +467,7 @@ static auto LookupBuiltinFunctionKind(Context& context,
   return kind;
 }
 
-// Returns whether `function` is a valid declaration of the builtin
-// `builtin_inst_kind`.
+// Returns whether `function` is a valid declaration of `builtin_kind`.
 static auto IsValidBuiltinDeclaration(Context& context,
                                       const SemIR::Function& function,
                                       SemIR::BuiltinFunctionKind builtin_kind)

+ 0 - 1
toolchain/check/handle_if_expr.cpp

@@ -6,7 +6,6 @@
 #include "toolchain/check/convert.h"
 #include "toolchain/check/handle.h"
 #include "toolchain/check/literal.h"
-#include "toolchain/sem_ir/builtin_inst_kind.h"
 
 namespace Carbon::Check {
 

+ 0 - 1
toolchain/check/handle_index.cpp

@@ -11,7 +11,6 @@
 #include "toolchain/check/literal.h"
 #include "toolchain/check/operator.h"
 #include "toolchain/diagnostics/diagnostic.h"
-#include "toolchain/sem_ir/builtin_inst_kind.h"
 #include "toolchain/sem_ir/inst.h"
 #include "toolchain/sem_ir/typed_insts.h"
 

+ 5 - 5
toolchain/check/handle_literal.cpp

@@ -15,7 +15,7 @@ auto HandleParseNode(Context& context, Parse::BoolLiteralFalseId node_id)
     -> bool {
   context.AddInstAndPush<SemIR::BoolLiteral>(
       node_id,
-      {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::BoolType),
+      {.type_id = context.GetSingletonType(SemIR::BoolType::SingletonInstId),
        .value = SemIR::BoolValue::False});
   return true;
 }
@@ -24,7 +24,7 @@ auto HandleParseNode(Context& context, Parse::BoolLiteralTrueId node_id)
     -> bool {
   context.AddInstAndPush<SemIR::BoolLiteral>(
       node_id,
-      {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::BoolType),
+      {.type_id = context.GetSingletonType(SemIR::BoolType::SingletonInstId),
        .value = SemIR::BoolValue::True});
   return true;
 }
@@ -75,8 +75,8 @@ auto HandleParseNode(Context& context, Parse::RealLiteralId node_id) -> bool {
 
   auto float_id = context.sem_ir().floats().Add(llvm::APFloat(double_val));
   context.AddInstAndPush<SemIR::FloatLiteral>(
-      node_id, {.type_id = context.GetBuiltinType(
-                    SemIR::BuiltinInstKind::LegacyFloatType),
+      node_id, {.type_id = context.GetSingletonType(
+                    SemIR::LegacyFloatType::SingletonInstId),
                 .float_id = float_id});
   return true;
 }
@@ -84,7 +84,7 @@ auto HandleParseNode(Context& context, Parse::RealLiteralId node_id) -> bool {
 auto HandleParseNode(Context& context, Parse::StringLiteralId node_id) -> bool {
   context.AddInstAndPush<SemIR::StringLiteral>(
       node_id,
-      {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::StringType),
+      {.type_id = context.GetSingletonType(SemIR::StringType::SingletonInstId),
        .string_literal_id = context.tokens().GetStringLiteralValue(
            context.parse_tree().node_token(node_id))});
   return true;

+ 4 - 4
toolchain/check/handle_name.cpp

@@ -222,10 +222,10 @@ auto HandleParseNode(Context& context, Parse::DesignatorExprId node_id)
 
 auto HandleParseNode(Context& context, Parse::PackageExprId node_id) -> bool {
   context.AddInstAndPush<SemIR::NameRef>(
-      node_id,
-      {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::NamespaceType),
-       .name_id = SemIR::NameId::PackageNamespace,
-       .value_id = SemIR::Namespace::PackageInstId});
+      node_id, {.type_id = context.GetSingletonType(
+                    SemIR::NamespaceType::SingletonInstId),
+                .name_id = SemIR::NameId::PackageNamespace,
+                .value_id = SemIR::Namespace::PackageInstId});
   return true;
 }
 

+ 1 - 1
toolchain/check/handle_namespace.cpp

@@ -35,7 +35,7 @@ auto HandleParseNode(Context& context, Parse::NamespaceId node_id) -> bool {
   LimitModifiersOnDecl(context, introducer, KeywordModifierSet::None);
 
   auto namespace_inst = SemIR::Namespace{
-      context.GetBuiltinType(SemIR::BuiltinInstKind::NamespaceType),
+      context.GetSingletonType(SemIR::NamespaceType::SingletonInstId),
       SemIR::NameScopeId::Invalid, SemIR::InstId::Invalid};
   auto namespace_id =
       context.AddPlaceholderInst(SemIR::LocIdAndInst(node_id, namespace_inst));

+ 1 - 1
toolchain/check/impl.cpp

@@ -219,7 +219,7 @@ static auto BuildInterfaceWitness(
   auto table_id = context.inst_blocks().Add(table);
   return context.AddInst<SemIR::InterfaceWitness>(
       context.insts().GetLocId(impl.definition_id),
-      {.type_id = context.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType),
+      {.type_id = context.GetSingletonType(SemIR::WitnessType::SingletonInstId),
        .elements_id = table_id});
 }
 

+ 1 - 1
toolchain/check/import.cpp

@@ -507,7 +507,7 @@ static auto AddNamespaceFromOtherPackage(Context& context,
                                          SemIR::NameId name_id)
     -> SemIR::InstId {
   auto namespace_type_id =
-      context.GetBuiltinType(SemIR::BuiltinInstKind::NamespaceType);
+      context.GetSingletonType(SemIR::NamespaceType::SingletonInstId);
   NamespaceResult result = CopySingleNameScopeFromImportIR(
       context, namespace_type_id, /*copied_namespaces=*/nullptr, import_ir_id,
       import_inst_id, import_ns.name_scope_id, parent_scope_id, name_id);

+ 11 - 12
toolchain/check/import_ref.cpp

@@ -496,10 +496,9 @@ class ImportRefResolver : public ImportContext {
 
     if (auto import_type_inst_id =
             import_ir().constant_values().GetInstId(import_type_const_id);
-        import_type_inst_id.is_builtin()) {
+        SemIR::IsSingletonInstId(import_type_inst_id)) {
       // Builtins don't require constant resolution; we can use them directly.
-      return local_context().GetBuiltinType(
-          import_type_inst_id.builtin_inst_kind());
+      return local_context().GetSingletonType(import_type_inst_id);
     } else {
       return local_context().GetTypeIdForTypeConstant(
           ResolveConstant(import_type_id.AsConstantId()));
@@ -1569,8 +1568,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
   if (import_class.is_defined()) {
     auto complete_type_witness_id = AddLoadedImportRef(
         resolver,
-        resolver.local_context().GetBuiltinType(
-            SemIR::BuiltinInstKind::WitnessType),
+        resolver.local_context().GetSingletonType(
+            SemIR::WitnessType::SingletonInstId),
         import_class.complete_type_witness_id, complete_type_witness_const_id);
     AddClassDefinition(resolver, import_class, new_class,
                        complete_type_witness_id, base_id, adapt_id);
@@ -1622,8 +1621,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
   auto object_repr_id =
       resolver.local_context().GetTypeIdForTypeConstant(object_repr_const_id);
   return ResolveAs<SemIR::CompleteTypeWitness>(
-      resolver, {.type_id = resolver.local_context().GetBuiltinType(
-                     SemIR::BuiltinInstKind::WitnessType),
+      resolver, {.type_id = resolver.local_context().GetSingletonType(
+                     SemIR::WitnessType::SingletonInstId),
                  .object_repr_id = object_repr_id});
 }
 
@@ -2129,8 +2128,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
   }
 
   return ResolveAs<SemIR::FacetAccessWitness>(
-      resolver, {.type_id = resolver.local_context().GetBuiltinType(
-                     SemIR::BuiltinInstKind::WitnessType),
+      resolver, {.type_id = resolver.local_context().GetSingletonType(
+                     SemIR::WitnessType::SingletonInstId),
                  .facet_value_inst_id = facet_value_inst_id});
 }
 
@@ -2226,8 +2225,8 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
   auto elements_id =
       GetLocalCanonicalInstBlockId(resolver, inst.elements_id, elements);
   return ResolveAs<SemIR::InterfaceWitness>(
-      resolver, {.type_id = resolver.local_context().GetBuiltinType(
-                     SemIR::BuiltinInstKind::WitnessType),
+      resolver, {.type_id = resolver.local_context().GetSingletonType(
+                     SemIR::WitnessType::SingletonInstId),
                  .elements_id = elements_id});
 }
 
@@ -2427,7 +2426,7 @@ static auto TryResolveInstCanonical(ImportRefResolver& resolver,
                                     SemIR::InstId inst_id,
                                     SemIR::ConstantId const_id)
     -> ResolveResult {
-  if (inst_id.is_builtin()) {
+  if (SemIR::IsSingletonInstId(inst_id)) {
     CARBON_CHECK(!const_id.is_valid());
     // Constants for builtins can be directly copied.
     return ResolveResult::Done(resolver.local_constant_values().Get(inst_id));

+ 2 - 2
toolchain/check/literal.cpp

@@ -13,8 +13,8 @@ namespace Carbon::Check {
 auto MakeIntLiteral(Context& context, Parse::NodeId node_id, IntId int_id)
     -> SemIR::InstId {
   return context.AddInst<SemIR::IntValue>(
-      node_id, {.type_id = context.GetBuiltinType(
-                    SemIR::BuiltinInstKind::IntLiteralType),
+      node_id, {.type_id = context.GetSingletonType(
+                    SemIR::IntLiteralType::SingletonInstId),
                 .int_id = int_id});
 }
 

+ 5 - 5
toolchain/check/member_access.cpp

@@ -293,8 +293,8 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id,
           // Get the witness that `T` implements `base_type_id`.
           if (base_interface == *assoc_interface) {
             witness_inst_id = context.GetOrAddInst<SemIR::FacetAccessWitness>(
-                loc_id, {.type_id = context.GetBuiltinType(
-                             SemIR::BuiltinInstKind::WitnessType),
+                loc_id, {.type_id = context.GetSingletonType(
+                             SemIR::WitnessType::SingletonInstId),
                          .facet_value_inst_id = base_id});
             // TODO: Result will eventually be a facet type witness instead of
             // an interface witness. Will need to use the index
@@ -375,8 +375,8 @@ static auto PerformInstanceBinding(Context& context, SemIR::LocId loc_id,
     case CARBON_KIND(SemIR::FunctionType fn_type): {
       if (IsInstanceMethod(context.sem_ir(), fn_type.function_id)) {
         return context.GetOrAddInst<SemIR::BoundMethod>(
-            loc_id, {.type_id = context.GetBuiltinType(
-                         SemIR::BuiltinInstKind::BoundMethodType),
+            loc_id, {.type_id = context.GetSingletonType(
+                         SemIR::BoundMethodType::SingletonInstId),
                      .object_id = base_id,
                      .function_id = member_id});
       }
@@ -560,7 +560,7 @@ auto PerformTupleAccess(Context& context, SemIR::LocId loc_id,
   auto index_node_id = context.insts().GetLocId(index_inst_id);
   index_inst_id = ConvertToValueOfType(
       context, index_node_id, index_inst_id,
-      context.GetBuiltinType(SemIR::BuiltinInstKind::IntLiteralType));
+      context.GetSingletonType(SemIR::IntLiteralType::SingletonInstId));
   auto index_const_id = context.constant_values().Get(index_inst_id);
   if (index_const_id == SemIR::ErrorInst::SingletonConstantId) {
     return SemIR::ErrorInst::SingletonInstId;

+ 2 - 2
toolchain/docs/adding_features.md

@@ -297,11 +297,11 @@ If the resulting SemIR needs a new instruction:
         constructed as a special-case in
         [`File` construction](/toolchain/sem_ir/file.cpp). To get a type id for
         one of these builtin types, use something like
-        `context.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType)`, as in:
+        `context.GetSingletonType(SemIR::WitnessType::SingletonInstId)`, as in:
 
         ```
         SemIR::TypeId witness_type_id =
-            context.GetBuiltinType(SemIR::BuiltinInstKind::WitnessType);
+            context.GetSingletonType(SemIR::WitnessType::SingletonInstId);
         SemIR::InstId inst_id = context.AddInst<SemIR::NewInstKindName>(
             node_id, {.type_id = witness_type_id, ...});
         ```

+ 2 - 6
toolchain/docs/idioms.md

@@ -384,12 +384,8 @@ class Foo {
 The parameters of the variable template can be chosen to allow reuse of the same
 variable template for multiple static data members.
 
-Examples:
-
--   `NodeStack::IdKindTable` in
-    [check/node_stack.h](/toolchain/check/node_stack.h)
--   `BuiltinKind::ValidCount` in
-    [sem_ir/builtin_inst_kind.h](/toolchain/sem_ir/builtin_inst_kind.h)
+For example, see `NodeStack::IdKindTable` in
+[check/node_stack.h](/toolchain/check/node_stack.h).
 
 A global constant may use a single definition without a separate declaration:
 

+ 1 - 1
toolchain/lower/function_context.h

@@ -46,7 +46,7 @@ class FunctionContext {
   // Returns a value for the given instruction.
   auto GetValue(SemIR::InstId inst_id) -> llvm::Value* {
     // All builtins are types, with the same empty lowered value.
-    if (inst_id.is_builtin()) {
+    if (SemIR::IsSingletonInstId(inst_id)) {
       return GetTypeAsValue();
     }
 

+ 0 - 2
toolchain/sem_ir/BUILD

@@ -21,12 +21,10 @@ cc_library(
 cc_library(
     name = "typed_insts",
     srcs = [
-        "builtin_inst_kind.cpp",
         "ids.cpp",
         "inst_kind.cpp",
     ],
     hdrs = [
-        "builtin_inst_kind.h",
         "id_kind.h",
         "ids.h",
         "inst_kind.h",

+ 0 - 15
toolchain/sem_ir/builtin_inst_kind.cpp

@@ -1,15 +0,0 @@
-// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
-// Exceptions. See /LICENSE for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-#include "toolchain/sem_ir/builtin_inst_kind.h"
-
-namespace Carbon::SemIR {
-
-CARBON_DEFINE_ENUM_CLASS_NAMES(BuiltinInstKind) = {
-#define CARBON_SEM_IR_BUILTIN_INST_KIND(Name) \
-  CARBON_ENUM_CLASS_NAME_STRING(Name)
-#include "toolchain/sem_ir/inst_kind.def"
-};
-
-}  // namespace Carbon::SemIR

+ 0 - 50
toolchain/sem_ir/builtin_inst_kind.h

@@ -1,50 +0,0 @@
-// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
-// Exceptions. See /LICENSE for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-
-#ifndef CARBON_TOOLCHAIN_SEM_IR_BUILTIN_INST_KIND_H_
-#define CARBON_TOOLCHAIN_SEM_IR_BUILTIN_INST_KIND_H_
-
-#include <cstdint>
-
-#include "common/enum_base.h"
-
-namespace Carbon::SemIR {
-
-CARBON_DEFINE_RAW_ENUM_CLASS(BuiltinInstKind, uint8_t) {
-#define CARBON_SEM_IR_BUILTIN_INST_KIND(Name) CARBON_RAW_ENUM_ENUMERATOR(Name)
-#include "toolchain/sem_ir/inst_kind.def"
-};
-
-class BuiltinInstKind : public CARBON_ENUM_BASE(BuiltinInstKind) {
- public:
-#define CARBON_SEM_IR_BUILTIN_INST_KIND(Name) CARBON_ENUM_CONSTANT_DECL(Name)
-#include "toolchain/sem_ir/inst_kind.def"
-
-  // The count of enum values excluding Invalid.
-  static constexpr uint8_t ValidCount = 0
-#define CARBON_SEM_IR_BUILTIN_INST_KIND(Name) +1
-#include "toolchain/sem_ir/inst_kind.def"
-      ;
-
-  // Support conversion to and from an int32_t for SemIR instruction storage.
-  using EnumBase::AsInt;
-  using EnumBase::FromInt;
-};
-
-#define CARBON_SEM_IR_BUILTIN_INST_KIND(Name) \
-  CARBON_ENUM_CONSTANT_DEFINITION(BuiltinInstKind, Name)
-#include "toolchain/sem_ir/inst_kind.def"
-
-static_assert(
-    BuiltinInstKind::ValidCount != 0,
-    "The above `constexpr` definition of `ValidCount` makes it available in "
-    "a `constexpr` context despite being declared as merely `const`. We use it "
-    "in a static assert here to ensure that.");
-
-// We expect the builtin kind to fit compactly into 8 bits.
-static_assert(sizeof(BuiltinInstKind) == 1, "Kind objects include padding!");
-
-}  // namespace Carbon::SemIR
-
-#endif  // CARBON_TOOLCHAIN_SEM_IR_BUILTIN_INST_KIND_H_

+ 2 - 2
toolchain/sem_ir/ids.cpp

@@ -15,8 +15,8 @@ auto InstId::Print(llvm::raw_ostream& out) const -> void {
     return;
   }
   out << Label;
-  if (is_builtin()) {
-    out << "(" << builtin_inst_kind() << ")";
+  if (index < static_cast<int>(SingletonInstKinds.size())) {
+    out << "(" << SingletonInstKinds[index] << ")";
   } else {
     // Use the `+` as a small reminder that this is a delta, rather than an
     // absolute index.

+ 0 - 19
toolchain/sem_ir/ids.h

@@ -11,7 +11,6 @@
 #include "toolchain/base/value_ids.h"
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 #include "toolchain/parse/node_ids.h"
-#include "toolchain/sem_ir/builtin_inst_kind.h"
 
 namespace Carbon::SemIR {
 
@@ -40,26 +39,8 @@ struct InstId : public IdBase<InstId> {
   // An explicitly invalid ID.
   static const InstId Invalid;
 
-  // Returns the instruction ID for a builtin. This relies on File guarantees
-  // for builtin placement.
-  static constexpr auto ForBuiltin(BuiltinInstKind kind) -> InstId {
-    return InstId(kind.AsInt());
-  }
-
   using IdBase::IdBase;
 
-  // Returns true if the instruction is a builtin. Requires is_valid.
-  auto is_builtin() const -> bool {
-    CARBON_CHECK(is_valid());
-    return index < BuiltinInstKind::ValidCount;
-  }
-
-  // Returns the BuiltinInstKind. Requires is_builtin.
-  auto builtin_inst_kind() const -> BuiltinInstKind {
-    CARBON_CHECK(is_builtin());
-    return BuiltinInstKind::FromInt(index);
-  }
-
   auto Print(llvm::raw_ostream& out) const -> void;
 };
 

+ 19 - 41
toolchain/sem_ir/inst_kind.def

@@ -10,45 +10,11 @@
 // This macro should be defined before including this header:
 // - CARBON_SEM_IR_INST_KIND(Name)
 //   Invoked for each kind of semantic instruction.
-//
-// Temporarily, we have CARBON_SEM_IR_BUILTIN_INST_KIND too:
-//
-// - CARBON_SEM_IR_BUILTIN_INST_KIND(Name)
-//   Defines a non-Invalid builtin type. Falls back to CARBON_SEM_IR_INST_KIND
-//   if not defined.
-//
-// TODO: Merge builtin instructions into the standard CARBON_SEM_IR_INST_KIND,
-// tracking the "builtin" annotation separately. This approach is used for
-// legacy compatibility.
-
-// If CARBON_SEM_IR_BUILTIN_INST_KIND is missing, default to
-// CARBON_SEM_IR_INST_KIND. However, if it's provided, make
-// CARBON_SEM_IR_INST_KIND optional. Per the above TODO, this is temporary.
-#ifndef CARBON_SEM_IR_BUILTIN_INST_KIND
-#define CARBON_SEM_IR_BUILTIN_INST_KIND(Name) CARBON_SEM_IR_INST_KIND(Name)
-#else
-#ifndef CARBON_SEM_IR_INST_KIND
-#define CARBON_SEM_IR_INST_KIND(Name)
-#endif
-#endif
 
 #ifndef CARBON_SEM_IR_INST_KIND
 #error "Must define the x-macro to use this file."
 #endif
 
-CARBON_SEM_IR_BUILTIN_INST_KIND(TypeType)
-CARBON_SEM_IR_BUILTIN_INST_KIND(AutoType)
-CARBON_SEM_IR_BUILTIN_INST_KIND(BoolType)
-CARBON_SEM_IR_BUILTIN_INST_KIND(BoundMethodType)
-CARBON_SEM_IR_BUILTIN_INST_KIND(ErrorInst)
-CARBON_SEM_IR_BUILTIN_INST_KIND(IntLiteralType)
-CARBON_SEM_IR_BUILTIN_INST_KIND(LegacyFloatType)
-CARBON_SEM_IR_BUILTIN_INST_KIND(NamespaceType)
-CARBON_SEM_IR_BUILTIN_INST_KIND(SpecificFunctionType)
-CARBON_SEM_IR_BUILTIN_INST_KIND(StringType)
-CARBON_SEM_IR_BUILTIN_INST_KIND(VtableType)
-CARBON_SEM_IR_BUILTIN_INST_KIND(WitnessType)
-
 // For each instruction kind declared here there is a matching definition in
 // `typed_insts.h`.
 CARBON_SEM_IR_INST_KIND(AdaptDecl)
@@ -62,16 +28,18 @@ CARBON_SEM_IR_INST_KIND(Assign)
 CARBON_SEM_IR_INST_KIND(AssociatedConstantDecl)
 CARBON_SEM_IR_INST_KIND(AssociatedEntity)
 CARBON_SEM_IR_INST_KIND(AssociatedEntityType)
+CARBON_SEM_IR_INST_KIND(AutoType)
 CARBON_SEM_IR_INST_KIND(BaseDecl)
 CARBON_SEM_IR_INST_KIND(BindAlias)
-CARBON_SEM_IR_INST_KIND(ExportDecl)
-CARBON_SEM_IR_INST_KIND(BindingPattern)
 CARBON_SEM_IR_INST_KIND(BindName)
 CARBON_SEM_IR_INST_KIND(BindSymbolicName)
 CARBON_SEM_IR_INST_KIND(BindValue)
+CARBON_SEM_IR_INST_KIND(BindingPattern)
 CARBON_SEM_IR_INST_KIND(BlockArg)
 CARBON_SEM_IR_INST_KIND(BoolLiteral)
+CARBON_SEM_IR_INST_KIND(BoolType)
 CARBON_SEM_IR_INST_KIND(BoundMethod)
+CARBON_SEM_IR_INST_KIND(BoundMethodType)
 CARBON_SEM_IR_INST_KIND(Branch)
 CARBON_SEM_IR_INST_KIND(BranchIf)
 CARBON_SEM_IR_INST_KIND(BranchWithArg)
@@ -84,6 +52,8 @@ CARBON_SEM_IR_INST_KIND(CompleteTypeWitness)
 CARBON_SEM_IR_INST_KIND(ConstType)
 CARBON_SEM_IR_INST_KIND(Converted)
 CARBON_SEM_IR_INST_KIND(Deref)
+CARBON_SEM_IR_INST_KIND(ErrorInst)
+CARBON_SEM_IR_INST_KIND(ExportDecl)
 CARBON_SEM_IR_INST_KIND(FacetAccessType)
 CARBON_SEM_IR_INST_KIND(FacetAccessWitness)
 CARBON_SEM_IR_INST_KIND(FacetType)
@@ -97,43 +67,49 @@ CARBON_SEM_IR_INST_KIND(GenericClassType)
 CARBON_SEM_IR_INST_KIND(GenericInterfaceType)
 CARBON_SEM_IR_INST_KIND(ImplDecl)
 CARBON_SEM_IR_INST_KIND(ImportDecl)
-CARBON_SEM_IR_INST_KIND(ImportRefUnloaded)
 CARBON_SEM_IR_INST_KIND(ImportRefLoaded)
+CARBON_SEM_IR_INST_KIND(ImportRefUnloaded)
 CARBON_SEM_IR_INST_KIND(InitializeFrom)
+CARBON_SEM_IR_INST_KIND(IntLiteralType)
+CARBON_SEM_IR_INST_KIND(IntType)
+CARBON_SEM_IR_INST_KIND(IntValue)
 CARBON_SEM_IR_INST_KIND(InterfaceDecl)
 CARBON_SEM_IR_INST_KIND(InterfaceWitness)
 CARBON_SEM_IR_INST_KIND(InterfaceWitnessAccess)
-CARBON_SEM_IR_INST_KIND(IntValue)
-CARBON_SEM_IR_INST_KIND(IntType)
+CARBON_SEM_IR_INST_KIND(LegacyFloatType)
 CARBON_SEM_IR_INST_KIND(NameRef)
 CARBON_SEM_IR_INST_KIND(Namespace)
+CARBON_SEM_IR_INST_KIND(NamespaceType)
 CARBON_SEM_IR_INST_KIND(OutParam)
 CARBON_SEM_IR_INST_KIND(OutParamPattern)
 CARBON_SEM_IR_INST_KIND(PointerType)
-CARBON_SEM_IR_INST_KIND(RequirementRewrite)
 CARBON_SEM_IR_INST_KIND(RequirementEquivalent)
 CARBON_SEM_IR_INST_KIND(RequirementImpls)
+CARBON_SEM_IR_INST_KIND(RequirementRewrite)
 CARBON_SEM_IR_INST_KIND(Return)
 CARBON_SEM_IR_INST_KIND(ReturnExpr)
 CARBON_SEM_IR_INST_KIND(ReturnSlot)
 CARBON_SEM_IR_INST_KIND(ReturnSlotPattern)
 CARBON_SEM_IR_INST_KIND(SpecificConstant)
 CARBON_SEM_IR_INST_KIND(SpecificFunction)
+CARBON_SEM_IR_INST_KIND(SpecificFunctionType)
 CARBON_SEM_IR_INST_KIND(SpliceBlock)
 CARBON_SEM_IR_INST_KIND(StringLiteral)
+CARBON_SEM_IR_INST_KIND(StringType)
 CARBON_SEM_IR_INST_KIND(StructAccess)
 CARBON_SEM_IR_INST_KIND(StructInit)
 CARBON_SEM_IR_INST_KIND(StructLiteral)
 CARBON_SEM_IR_INST_KIND(StructType)
 CARBON_SEM_IR_INST_KIND(StructValue)
 CARBON_SEM_IR_INST_KIND(SymbolicBindingPattern)
-CARBON_SEM_IR_INST_KIND(TemporaryStorage)
 CARBON_SEM_IR_INST_KIND(Temporary)
+CARBON_SEM_IR_INST_KIND(TemporaryStorage)
 CARBON_SEM_IR_INST_KIND(TupleAccess)
 CARBON_SEM_IR_INST_KIND(TupleInit)
 CARBON_SEM_IR_INST_KIND(TupleLiteral)
 CARBON_SEM_IR_INST_KIND(TupleType)
 CARBON_SEM_IR_INST_KIND(TupleValue)
+CARBON_SEM_IR_INST_KIND(TypeType)
 CARBON_SEM_IR_INST_KIND(UnaryOperatorNot)
 CARBON_SEM_IR_INST_KIND(UnboundElementType)
 CARBON_SEM_IR_INST_KIND(ValueAsRef)
@@ -141,7 +117,9 @@ CARBON_SEM_IR_INST_KIND(ValueOfInitializer)
 CARBON_SEM_IR_INST_KIND(ValueParam)
 CARBON_SEM_IR_INST_KIND(ValueParamPattern)
 CARBON_SEM_IR_INST_KIND(VarStorage)
+CARBON_SEM_IR_INST_KIND(VtableType)
 CARBON_SEM_IR_INST_KIND(WhereExpr)
+CARBON_SEM_IR_INST_KIND(WitnessType)
 
 #undef CARBON_SEM_IR_INST_KIND
 #undef CARBON_SEM_IR_BUILTIN_INST_KIND

+ 1 - 1
toolchain/sem_ir/inst_namer.cpp

@@ -139,7 +139,7 @@ auto InstNamer::GetNameFor(ScopeId scope_id, InstId inst_id) const
   }
 
   // Check for a builtin.
-  if (inst_id.is_builtin()) {
+  if (SemIR::IsSingletonInstId(inst_id)) {
     return sem_ir_.insts().Get(inst_id).kind().ir_name().str();
   }
 

+ 6 - 0
toolchain/sem_ir/singleton_insts.h

@@ -36,6 +36,12 @@ template <InstKind::RawEnumType Kind>
   requires(IsSingletonInstKind(InstKind::Make(Kind)))
 inline constexpr auto MakeSingletonInstId() -> InstId;
 
+// Returns true if the InstId corresponds to a singleton inst.
+inline constexpr auto IsSingletonInstId(InstId id) -> bool {
+  return id.index >= 0 &&
+         id.index < static_cast<int32_t>(SingletonInstKinds.size());
+}
+
 // Only implementation details are below.
 
 namespace Internal {

+ 1 - 1
toolchain/sem_ir/stringify_type.cpp

@@ -149,7 +149,7 @@ auto StringifyTypeExpr(const SemIR::File& sem_ir, InstId outer_inst_id)
       case SemIR::TypeType::Kind:
       case SemIR::VtableType::Kind:
       case SemIR::WitnessType::Kind: {
-        // Builtin instructions use their IR name as a label.
+        // Singleton instructions use their IR name as a label.
         out << untyped_inst.kind().ir_name();
         break;
       }

+ 1 - 1
toolchain/sem_ir/type.h

@@ -108,7 +108,7 @@ class TypeStore : public Yaml::Printable<TypeStore> {
 
   // Returns integer type information from a type ID that is known to represent
   // an integer type. Abstracts away the difference between an `IntType`
-  // instruction defined type, a builtin instruction defined type, and a class
+  // instruction defined type, a singleton instruction defined type, and a class
   // adapting such a type. Uses IntId::Invalid for types that have a
   // non-constant width and for IntLiteral.
   auto GetIntTypeInfo(TypeId int_type_id) const -> IntTypeInfo;

+ 0 - 1
toolchain/sem_ir/typed_insts.h

@@ -7,7 +7,6 @@
 
 #include "toolchain/base/int.h"
 #include "toolchain/parse/node_ids.h"
-#include "toolchain/sem_ir/builtin_inst_kind.h"
 #include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/inst_kind.h"
 #include "toolchain/sem_ir/singleton_insts.h"