diff --git a/toolchain/check/BUILD b/toolchain/check/BUILD index be0cd40a1e21..aae82a2a81b2 100644 --- a/toolchain/check/BUILD +++ b/toolchain/check/BUILD @@ -23,7 +23,7 @@ cc_library( "//common:vlog", "//toolchain/parse:node_kind", "//toolchain/parse:tree", - "//toolchain/sem_ir:node", + "//toolchain/sem_ir:inst", "@llvm-project//llvm:Support", ], ) @@ -35,7 +35,7 @@ cc_library( "context.cpp", "convert.cpp", "declaration_name_stack.cpp", - "node_block_stack.cpp", + "inst_block_stack.cpp", ] + # Glob handler files to avoid missing any. glob([ @@ -66,8 +66,8 @@ cc_library( "//toolchain/sem_ir:builtin_kind", "//toolchain/sem_ir:entry_point", "//toolchain/sem_ir:file", - "//toolchain/sem_ir:node", - "//toolchain/sem_ir:node_kind", + "//toolchain/sem_ir:inst", + "//toolchain/sem_ir:inst_kind", "@llvm-project//llvm:Support", ], ) diff --git a/toolchain/check/check.cpp b/toolchain/check/check.cpp index 432658542016..0337417406e5 100644 --- a/toolchain/check/check.cpp +++ b/toolchain/check/check.cpp @@ -27,7 +27,7 @@ auto CheckParseTree(SharedValueStores& value_stores, [&](llvm::raw_ostream& output) { context.PrintForStackDump(output); }); // Add a block for the Parse::Tree. - context.node_block_stack().Push(); + context.inst_block_stack().Push(); context.PushScope(); // Loops over all nodes in the tree. On some errors, this may return early, @@ -51,7 +51,7 @@ auto CheckParseTree(SharedValueStores& value_stores, } // Pop information for the file-level scope. - sem_ir.set_top_node_block_id(context.node_block_stack().Pop()); + sem_ir.set_top_inst_block_id(context.inst_block_stack().Pop()); context.PopScope(); context.VerifyOnFinish(); diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index 4448a1d9b1f4..7ff07f2c3091 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -15,7 +15,7 @@ #include "toolchain/lex/tokenized_buffer.h" #include "toolchain/parse/node_kind.h" #include "toolchain/sem_ir/file.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/node_kind.h" namespace Carbon::Check { @@ -29,15 +29,15 @@ Context::Context(const Lex::TokenizedBuffer& tokens, DiagnosticEmitter& emitter, sem_ir_(&sem_ir), vlog_stream_(vlog_stream), node_stack_(parse_tree, vlog_stream), - node_block_stack_("node_block_stack_", sem_ir, vlog_stream), + inst_block_stack_("inst_block_stack_", sem_ir, vlog_stream), params_or_args_stack_("params_or_args_stack_", sem_ir, vlog_stream), args_type_info_stack_("args_type_info_stack_", sem_ir, vlog_stream), declaration_name_stack_(this) { // Inserts the "Error" and "Type" types as "used types" so that // canonicalization can skip them. We don't emit either for lowering. - canonical_types_.insert({SemIR::NodeId::BuiltinError, SemIR::TypeId::Error}); + canonical_types_.insert({SemIR::InstId::BuiltinError, SemIR::TypeId::Error}); canonical_types_.insert( - {SemIR::NodeId::BuiltinTypeType, SemIR::TypeId::TypeType}); + {SemIR::InstId::BuiltinTypeType, SemIR::TypeId::TypeType}); } auto Context::TODO(Parse::Node parse_node, std::string label) -> bool { @@ -54,28 +54,28 @@ auto Context::VerifyOnFinish() -> void { // node_stack_ will still contain top-level entities. CARBON_CHECK(name_lookup_.empty()) << name_lookup_.size(); CARBON_CHECK(scope_stack_.empty()) << scope_stack_.size(); - CARBON_CHECK(node_block_stack_.empty()) << node_block_stack_.size(); + CARBON_CHECK(inst_block_stack_.empty()) << inst_block_stack_.size(); CARBON_CHECK(params_or_args_stack_.empty()) << params_or_args_stack_.size(); } -auto Context::AddNode(SemIR::Node node) -> SemIR::NodeId { - auto node_id = node_block_stack_.AddNode(node); - CARBON_VLOG() << "AddNode: " << node << "\n"; - return node_id; +auto Context::AddInst(SemIR::Inst inst) -> SemIR::InstId { + auto inst_id = inst_block_stack_.AddInst(inst); + CARBON_VLOG() << "AddInst: " << inst << "\n"; + return inst_id; } -auto Context::AddNodeAndPush(Parse::Node parse_node, SemIR::Node node) -> void { - auto node_id = AddNode(node); - node_stack_.Push(parse_node, node_id); +auto Context::AddInstAndPush(Parse::Node parse_node, SemIR::Inst inst) -> void { + auto inst_id = AddInst(inst); + node_stack_.Push(parse_node, inst_id); } auto Context::DiagnoseDuplicateName(Parse::Node parse_node, - SemIR::NodeId prev_def_id) -> void { + SemIR::InstId prev_def_id) -> void { CARBON_DIAGNOSTIC(NameDeclarationDuplicate, Error, "Duplicate name being declared in the same scope."); CARBON_DIAGNOSTIC(NameDeclarationPrevious, Note, "Name is previously declared here."); - auto prev_def = nodes().Get(prev_def_id); + auto prev_def = insts().Get(prev_def_id); emitter_->Build(parse_node, NameDeclarationDuplicate) .Note(prev_def.parse_node(), NameDeclarationPrevious) .Emit(); @@ -97,16 +97,16 @@ auto Context::NoteIncompleteClass(SemIR::ClassId class_id, const auto& class_info = classes().Get(class_id); CARBON_CHECK(!class_info.is_defined()) << "Class is not incomplete"; if (class_info.definition_id.is_valid()) { - builder.Note(nodes().Get(class_info.definition_id).parse_node(), + builder.Note(insts().Get(class_info.definition_id).parse_node(), ClassIncompleteWithinDefinition); } else { - builder.Note(nodes().Get(class_info.declaration_id).parse_node(), + builder.Note(insts().Get(class_info.declaration_id).parse_node(), ClassForwardDeclaredHere); } } auto Context::AddNameToLookup(Parse::Node name_node, StringId name_id, - SemIR::NodeId target_id) -> void { + SemIR::InstId target_id) -> void { if (current_scope().names.insert(name_id).second) { name_lookup_[name_id].push_back(target_id); } else { @@ -116,14 +116,14 @@ auto Context::AddNameToLookup(Parse::Node name_node, StringId name_id, auto Context::LookupName(Parse::Node parse_node, StringId name_id, SemIR::NameScopeId scope_id, bool print_diagnostics) - -> SemIR::NodeId { + -> SemIR::InstId { if (scope_id == SemIR::NameScopeId::Invalid) { auto it = name_lookup_.find(name_id); if (it == name_lookup_.end()) { if (print_diagnostics) { DiagnoseNameNotFound(parse_node, name_id); } - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } CARBON_CHECK(!it->second.empty()) << "Should have been erased: " << strings().Get(name_id); @@ -137,17 +137,17 @@ auto Context::LookupName(Parse::Node parse_node, StringId name_id, if (print_diagnostics) { DiagnoseNameNotFound(parse_node, name_id); } - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } return it->second; } } -auto Context::PushScope(SemIR::NodeId scope_node_id, +auto Context::PushScope(SemIR::InstId scope_inst_id, SemIR::NameScopeId scope_id) -> void { scope_stack_.push_back( - {.scope_node_id = scope_node_id, .scope_id = scope_id}); + {.scope_inst_id = scope_inst_id, .scope_id = scope_id}); } auto Context::PopScope() -> void { @@ -163,34 +163,34 @@ auto Context::PopScope() -> void { } } -auto Context::FollowNameReferences(SemIR::NodeId node_id) -> SemIR::NodeId { - while (auto name_ref = nodes().Get(node_id).TryAs()) { - node_id = name_ref->value_id; +auto Context::FollowNameReferences(SemIR::InstId inst_id) -> SemIR::InstId { + while (auto name_ref = insts().Get(inst_id).TryAs()) { + inst_id = name_ref->value_id; } - return node_id; + return inst_id; } -auto Context::GetConstantValue(SemIR::NodeId node_id) -> SemIR::NodeId { - // TODO: The constant value of a node should be computed as we build the - // node, or at least cached once computed. +auto Context::GetConstantValue(SemIR::InstId inst_id) -> SemIR::InstId { + // TODO: The constant value of an instruction should be computed as we build + // the instruction, or at least cached once computed. while (true) { - auto node = nodes().Get(node_id); - switch (node.kind()) { + auto inst = insts().Get(inst_id); + switch (inst.kind()) { case SemIR::NameReference::Kind: - node_id = node.As().value_id; + inst_id = inst.As().value_id; break; case SemIR::BindName::Kind: - node_id = node.As().value_id; + inst_id = inst.As().value_id; break; case SemIR::Field::Kind: case SemIR::FunctionDeclaration::Kind: - return node_id; + return inst_id; default: // TODO: Handle the remaining cases. - return SemIR::NodeId::Invalid; + return SemIR::InstId::Invalid; } } } @@ -198,30 +198,30 @@ auto Context::GetConstantValue(SemIR::NodeId node_id) -> SemIR::NodeId { template static auto AddDominatedBlockAndBranchImpl(Context& context, Parse::Node parse_node, Args... args) - -> SemIR::NodeBlockId { - if (!context.node_block_stack().is_current_block_reachable()) { - return SemIR::NodeBlockId::Unreachable; + -> SemIR::InstBlockId { + if (!context.inst_block_stack().is_current_block_reachable()) { + return SemIR::InstBlockId::Unreachable; } - auto block_id = context.node_blocks().AddDefaultValue(); - context.AddNode(BranchNode{parse_node, block_id, args...}); + auto block_id = context.inst_blocks().AddDefaultValue(); + context.AddInst(BranchNode{parse_node, block_id, args...}); return block_id; } auto Context::AddDominatedBlockAndBranch(Parse::Node parse_node) - -> SemIR::NodeBlockId { + -> SemIR::InstBlockId { return AddDominatedBlockAndBranchImpl(*this, parse_node); } auto Context::AddDominatedBlockAndBranchWithArg(Parse::Node parse_node, - SemIR::NodeId arg_id) - -> SemIR::NodeBlockId { + SemIR::InstId arg_id) + -> SemIR::InstBlockId { return AddDominatedBlockAndBranchImpl(*this, parse_node, arg_id); } auto Context::AddDominatedBlockAndBranchIf(Parse::Node parse_node, - SemIR::NodeId cond_id) - -> SemIR::NodeBlockId { + SemIR::InstId cond_id) + -> SemIR::InstBlockId { return AddDominatedBlockAndBranchImpl(*this, parse_node, cond_id); } @@ -230,73 +230,73 @@ auto Context::AddConvergenceBlockAndPush(Parse::Node parse_node, int num_blocks) -> void { CARBON_CHECK(num_blocks >= 2) << "no convergence"; - SemIR::NodeBlockId new_block_id = SemIR::NodeBlockId::Unreachable; + SemIR::InstBlockId new_block_id = SemIR::InstBlockId::Unreachable; for ([[maybe_unused]] auto _ : llvm::seq(num_blocks)) { - if (node_block_stack().is_current_block_reachable()) { - if (new_block_id == SemIR::NodeBlockId::Unreachable) { - new_block_id = node_blocks().AddDefaultValue(); + if (inst_block_stack().is_current_block_reachable()) { + if (new_block_id == SemIR::InstBlockId::Unreachable) { + new_block_id = inst_blocks().AddDefaultValue(); } - AddNode(SemIR::Branch{parse_node, new_block_id}); + AddInst(SemIR::Branch{parse_node, new_block_id}); } - node_block_stack().Pop(); + inst_block_stack().Pop(); } - node_block_stack().Push(new_block_id); + inst_block_stack().Push(new_block_id); } auto Context::AddConvergenceBlockWithArgAndPush( - Parse::Node parse_node, std::initializer_list block_args) - -> SemIR::NodeId { + Parse::Node parse_node, std::initializer_list block_args) + -> SemIR::InstId { CARBON_CHECK(block_args.size() >= 2) << "no convergence"; - SemIR::NodeBlockId new_block_id = SemIR::NodeBlockId::Unreachable; + SemIR::InstBlockId new_block_id = SemIR::InstBlockId::Unreachable; for (auto arg_id : block_args) { - if (node_block_stack().is_current_block_reachable()) { - if (new_block_id == SemIR::NodeBlockId::Unreachable) { - new_block_id = node_blocks().AddDefaultValue(); + if (inst_block_stack().is_current_block_reachable()) { + if (new_block_id == SemIR::InstBlockId::Unreachable) { + new_block_id = inst_blocks().AddDefaultValue(); } - AddNode(SemIR::BranchWithArg{parse_node, new_block_id, arg_id}); + AddInst(SemIR::BranchWithArg{parse_node, new_block_id, arg_id}); } - node_block_stack().Pop(); + inst_block_stack().Pop(); } - node_block_stack().Push(new_block_id); + inst_block_stack().Push(new_block_id); // Acquire the result value. - SemIR::TypeId result_type_id = nodes().Get(*block_args.begin()).type_id(); - return AddNode(SemIR::BlockArg{parse_node, result_type_id, new_block_id}); + SemIR::TypeId result_type_id = insts().Get(*block_args.begin()).type_id(); + return AddInst(SemIR::BlockArg{parse_node, result_type_id, new_block_id}); } // Add the current code block to the enclosing function. auto Context::AddCurrentCodeBlockToFunction() -> void { - CARBON_CHECK(!node_block_stack().empty()) << "no current code block"; + CARBON_CHECK(!inst_block_stack().empty()) << "no current code block"; CARBON_CHECK(!return_scope_stack().empty()) << "no current function"; - if (!node_block_stack().is_current_block_reachable()) { + if (!inst_block_stack().is_current_block_reachable()) { // Don't include unreachable blocks in the function. return; } auto function_id = - nodes() + insts() .GetAs(return_scope_stack().back()) .function_id; functions() .Get(function_id) - .body_block_ids.push_back(node_block_stack().PeekOrAdd()); + .body_block_ids.push_back(inst_block_stack().PeekOrAdd()); } auto Context::is_current_position_reachable() -> bool { - if (!node_block_stack().is_current_block_reachable()) { + if (!inst_block_stack().is_current_block_reachable()) { return false; } // Our current position is at the end of a reachable block. That position is // reachable unless the previous instruction is a terminator instruction. - auto block_contents = node_block_stack().PeekCurrentBlockContents(); + auto block_contents = inst_block_stack().PeekCurrentBlockContents(); if (block_contents.empty()) { return true; } - const auto& last_node = nodes().Get(block_contents.back()); - return last_node.kind().terminator_kind() != + const auto& last_inst = insts().Get(block_contents.back()); + return last_inst.kind().terminator_kind() != SemIR::TerminatorKind::Terminator; } @@ -312,11 +312,11 @@ auto Context::ParamOrArgEndNoPop(Parse::NodeKind start_kind) -> void { } } -auto Context::ParamOrArgPop() -> SemIR::NodeBlockId { +auto Context::ParamOrArgPop() -> SemIR::InstBlockId { return params_or_args_stack_.Pop(); } -auto Context::ParamOrArgEnd(Parse::NodeKind start_kind) -> SemIR::NodeBlockId { +auto Context::ParamOrArgEnd(Parse::NodeKind start_kind) -> SemIR::InstBlockId { ParamOrArgEndNoPop(start_kind); return ParamOrArgPop(); } @@ -373,14 +373,14 @@ class TypeCompleter { return true; } - auto node_id = context_.sem_ir().GetTypeAllowBuiltinTypes(type_id); - auto node = context_.nodes().Get(node_id); + auto inst_id = context_.sem_ir().GetTypeAllowBuiltinTypes(type_id); + auto inst = context_.insts().Get(inst_id); auto old_work_list_size = work_list_.size(); switch (phase) { case Phase::AddNestedIncompleteTypes: - if (!AddNestedIncompleteTypes(node)) { + if (!AddNestedIncompleteTypes(inst)) { return false; } CARBON_CHECK(work_list_.size() >= old_work_list_size) @@ -390,7 +390,7 @@ class TypeCompleter { break; case Phase::BuildValueRepresentation: { - auto value_rep = BuildValueRepresentation(type_id, node); + auto value_rep = BuildValueRepresentation(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"; @@ -419,18 +419,18 @@ class TypeCompleter { return true; } - // Adds any types nested within `type_node` that need to be complete for - // `type_node` to be complete to our work list. - auto AddNestedIncompleteTypes(SemIR::Node type_node) -> bool { - switch (type_node.kind()) { + // Adds any types nested within `type_inst` that need to be complete for + // `type_inst` to be complete to our work list. + auto AddNestedIncompleteTypes(SemIR::Inst type_inst) -> bool { + switch (type_inst.kind()) { case SemIR::ArrayType::Kind: - Push(type_node.As().element_type_id); + Push(type_inst.As().element_type_id); break; case SemIR::StructType::Kind: - for (auto field_id : context_.node_blocks().Get( - type_node.As().fields_id)) { - Push(context_.nodes() + for (auto field_id : context_.inst_blocks().Get( + type_inst.As().fields_id)) { + Push(context_.insts() .GetAs(field_id) .field_type_id); } @@ -438,13 +438,13 @@ class TypeCompleter { case SemIR::TupleType::Kind: for (auto element_type_id : context_.type_blocks().Get( - type_node.As().elements_id)) { + type_inst.As().elements_id)) { Push(element_type_id); } break; case SemIR::ClassType::Kind: { - auto class_type = type_node.As(); + auto class_type = type_inst.As(); auto& class_info = context_.classes().Get(class_type.class_id); if (!class_info.is_defined()) { if (diagnoser_) { @@ -459,7 +459,7 @@ class TypeCompleter { } case SemIR::ConstType::Kind: - Push(type_node.As().inner_id); + Push(type_inst.As().inner_id); break; default: @@ -516,21 +516,21 @@ class TypeCompleter { auto BuildCrossReferenceValueRepresentation(SemIR::TypeId type_id, SemIR::CrossReference xref) const -> SemIR::ValueRepresentation { - auto xref_node = context_.sem_ir() + auto xref_inst = context_.sem_ir() .GetCrossReferenceIR(xref.ir_id) - .nodes() - .Get(xref.node_id); + .insts() + .Get(xref.inst_id); // The canonical description of a type should only have cross-references // for entities owned by another File, such as builtins, which are owned // by the prelude, and named entities like classes and interfaces, which // we don't support yet. - CARBON_CHECK(xref_node.kind() == SemIR::Builtin::Kind) - << "TODO: Handle other kinds of node cross-references"; + CARBON_CHECK(xref_inst.kind() == SemIR::Builtin::Kind) + << "TODO: Handle other kinds of inst cross-references"; // clang warns on unhandled enum values; clang-tidy is incorrect here. // NOLINTNEXTLINE(bugprone-switch-missing-default-case) - switch (xref_node.As().builtin_kind) { + switch (xref_inst.As().builtin_kind) { case SemIR::BuiltinKind::TypeType: case SemIR::BuiltinKind::Error: case SemIR::BuiltinKind::Invalid: @@ -578,23 +578,23 @@ class TypeCompleter { SemIR::StructType struct_type) const -> SemIR::ValueRepresentation { // TODO: Share more code with tuples. - auto fields = context_.node_blocks().Get(struct_type.fields_id); + auto fields = context_.inst_blocks().Get(struct_type.fields_id); if (fields.empty()) { return MakeEmptyRepresentation(struct_type.parse_node); } // Find the value representation for each field, and construct a struct // of value representations. - llvm::SmallVector value_rep_fields; + llvm::SmallVector value_rep_fields; value_rep_fields.reserve(fields.size()); bool same_as_object_rep = true; for (auto field_id : fields) { - auto field = context_.nodes().GetAs(field_id); + auto field = context_.insts().GetAs(field_id); auto field_value_rep = GetNestedValueRepresentation(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; - field_id = context_.AddNode(field); + field_id = context_.AddInst(field); } value_rep_fields.push_back(field_id); } @@ -603,7 +603,7 @@ class TypeCompleter { ? type_id : context_.CanonicalizeStructType( struct_type.parse_node, - context_.node_blocks().Add(value_rep_fields)); + context_.inst_blocks().Add(value_rep_fields)); return BuildStructOrTupleValueRepresentation( struct_type.parse_node, fields.size(), value_rep, same_as_object_rep); } @@ -640,16 +640,16 @@ class TypeCompleter { // 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::Node node) const + auto BuildValueRepresentation(SemIR::TypeId type_id, SemIR::Inst inst) const -> SemIR::ValueRepresentation { - // TODO: This can emit new SemIR nodes. Consider emitting them into a - // dedicated file-scope node block where possible, or somewhere else that - // better reflects the definition of the type, rather than wherever the + // 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 // type happens to first be required to be complete. // clang warns on unhandled enum values; clang-tidy is incorrect here. // NOLINTNEXTLINE(bugprone-switch-missing-default-case) - switch (node.kind()) { + switch (inst.kind()) { case SemIR::AddressOf::Kind: case SemIR::ArrayIndex::Kind: case SemIR::ArrayInit::Kind: @@ -697,28 +697,28 @@ class TypeCompleter { case SemIR::ValueAsReference::Kind: case SemIR::ValueOfInitializer::Kind: case SemIR::VarStorage::Kind: - CARBON_FATAL() << "Type refers to non-type node " << node; + CARBON_FATAL() << "Type refers to non-type inst " << inst; case SemIR::CrossReference::Kind: return BuildCrossReferenceValueRepresentation( - type_id, node.As()); + 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( - node.parse_node(), type_id, + inst.parse_node(), type_id, SemIR::ValueRepresentation::ObjectAggregate); } case SemIR::StructType::Kind: return BuildStructTypeValueRepresentation(type_id, - node.As()); + inst.As()); case SemIR::TupleType::Kind: return BuildTupleTypeValueRepresentation(type_id, - node.As()); + inst.As()); case SemIR::ClassType::Kind: // The value representation for a class is a pointer to the object @@ -726,9 +726,9 @@ class TypeCompleter { // TODO: Support customized value representations for classes. // TODO: Pick a better value representation when possible. return MakePointerRepresentation( - node.parse_node(), + inst.parse_node(), context_.classes() - .Get(node.As().class_id) + .Get(inst.As().class_id) .object_representation_id, SemIR::ValueRepresentation::ObjectAggregate); @@ -743,7 +743,7 @@ class TypeCompleter { // The value representation of `const T` is the same as that of `T`. // Objects are not modifiable through their value representations. return GetNestedValueRepresentation( - node.As().inner_id); + inst.As().inner_id); } } @@ -774,9 +774,9 @@ auto Context::TryToCompleteType( } auto Context::CanonicalizeTypeImpl( - SemIR::NodeKind kind, + SemIR::InstKind kind, llvm::function_ref profile_type, - llvm::function_ref make_node) -> SemIR::TypeId { + llvm::function_ref make_inst) -> SemIR::TypeId { llvm::FoldingSetNodeID canonical_id; kind.Profile(canonical_id); profile_type(canonical_id); @@ -788,14 +788,14 @@ auto Context::CanonicalizeTypeImpl( return node->type_id(); } - auto node_id = make_node(); - auto type_id = types().Add({.node_id = node_id}); - CARBON_CHECK(canonical_types_.insert({node_id, type_id}).second); + auto inst_id = make_inst(); + auto type_id = types().Add({.inst_id = inst_id}); + CARBON_CHECK(canonical_types_.insert({inst_id, type_id}).second); type_node_storage_.push_back( std::make_unique(canonical_id, type_id)); // In a debug build, check that our insertion position is still valid. It - // could have been invalidated by a misbehaving `make_node`. + // could have been invalidated by a misbehaving `make_inst`. CARBON_DCHECK([&] { void* check_insert_pos; auto* check_node = canonical_type_nodes_.FindNodeOrInsertPos( @@ -816,45 +816,45 @@ static auto ProfileTupleType(llvm::ArrayRef type_ids, } // Compute a fingerprint for a type, for use as a key in a folding set. -static auto ProfileType(Context& semantics_context, SemIR::Node node, +static auto ProfileType(Context& semantics_context, SemIR::Inst inst, llvm::FoldingSetNodeID& canonical_id) -> void { - switch (node.kind()) { + switch (inst.kind()) { case SemIR::ArrayType::Kind: { - auto array_type = node.As(); + auto array_type = inst.As(); canonical_id.AddInteger( semantics_context.sem_ir().GetArrayBoundValue(array_type.bound_id)); canonical_id.AddInteger(array_type.element_type_id.index); break; } case SemIR::Builtin::Kind: - canonical_id.AddInteger(node.As().builtin_kind.AsInt()); + canonical_id.AddInteger(inst.As().builtin_kind.AsInt()); break; case SemIR::ClassType::Kind: - canonical_id.AddInteger(node.As().class_id.index); + canonical_id.AddInteger(inst.As().class_id.index); break; case SemIR::CrossReference::Kind: { // TODO: Cross-references should be canonicalized by looking at their // target rather than treating them as new unique types. - auto xref = node.As(); + auto xref = inst.As(); canonical_id.AddInteger(xref.ir_id.index); - canonical_id.AddInteger(xref.node_id.index); + canonical_id.AddInteger(xref.inst_id.index); break; } case SemIR::ConstType::Kind: canonical_id.AddInteger( semantics_context - .GetUnqualifiedType(node.As().inner_id) + .GetUnqualifiedType(inst.As().inner_id) .index); break; case SemIR::PointerType::Kind: - canonical_id.AddInteger(node.As().pointee_id.index); + canonical_id.AddInteger(inst.As().pointee_id.index); break; case SemIR::StructType::Kind: { - auto fields = semantics_context.node_blocks().Get( - node.As().fields_id); + auto fields = semantics_context.inst_blocks().Get( + inst.As().fields_id); for (const auto& field_id : fields) { auto field = - semantics_context.nodes().GetAs(field_id); + semantics_context.insts().GetAs(field_id); canonical_id.AddInteger(field.name_id.index); canonical_id.AddInteger(field.field_type_id.index); } @@ -862,49 +862,49 @@ static auto ProfileType(Context& semantics_context, SemIR::Node node, } case SemIR::TupleType::Kind: ProfileTupleType(semantics_context.type_blocks().Get( - node.As().elements_id), + inst.As().elements_id), canonical_id); break; case SemIR::UnboundFieldType::Kind: { - auto unbound_field_type = node.As(); + auto unbound_field_type = inst.As(); canonical_id.AddInteger(unbound_field_type.class_type_id.index); canonical_id.AddInteger(unbound_field_type.field_type_id.index); break; } default: - CARBON_FATAL() << "Unexpected type node " << node; + CARBON_FATAL() << "Unexpected type inst " << inst; } } -auto Context::CanonicalizeTypeAndAddNodeIfNew(SemIR::Node node) +auto Context::CanonicalizeTypeAndAddInstIfNew(SemIR::Inst inst) -> SemIR::TypeId { auto profile_node = [&](llvm::FoldingSetNodeID& canonical_id) { - ProfileType(*this, node, canonical_id); + ProfileType(*this, inst, canonical_id); }; - auto make_node = [&] { return AddNode(node); }; - return CanonicalizeTypeImpl(node.kind(), profile_node, make_node); + auto make_inst = [&] { return AddInst(inst); }; + return CanonicalizeTypeImpl(inst.kind(), profile_node, make_inst); } -auto Context::CanonicalizeType(SemIR::NodeId node_id) -> SemIR::TypeId { - node_id = FollowNameReferences(node_id); +auto Context::CanonicalizeType(SemIR::InstId inst_id) -> SemIR::TypeId { + inst_id = FollowNameReferences(inst_id); - auto it = canonical_types_.find(node_id); + auto it = canonical_types_.find(inst_id); if (it != canonical_types_.end()) { return it->second; } - auto node = nodes().Get(node_id); + auto inst = insts().Get(inst_id); auto profile_node = [&](llvm::FoldingSetNodeID& canonical_id) { - ProfileType(*this, node, canonical_id); + ProfileType(*this, inst, canonical_id); }; - auto make_node = [&] { return node_id; }; - return CanonicalizeTypeImpl(node.kind(), profile_node, make_node); + auto make_inst = [&] { return inst_id; }; + return CanonicalizeTypeImpl(inst.kind(), profile_node, make_inst); } auto Context::CanonicalizeStructType(Parse::Node parse_node, - SemIR::NodeBlockId refs_id) + SemIR::InstBlockId refs_id) -> SemIR::TypeId { - return CanonicalizeTypeAndAddNodeIfNew( + return CanonicalizeTypeAndAddInstIfNew( SemIR::StructType{parse_node, SemIR::TypeId::TypeType, refs_id}); } @@ -915,17 +915,17 @@ auto Context::CanonicalizeTupleType(Parse::Node parse_node, auto profile_tuple = [&](llvm::FoldingSetNodeID& canonical_id) { ProfileTupleType(type_ids, canonical_id); }; - auto make_tuple_node = [&] { - return AddNode(SemIR::TupleType{parse_node, SemIR::TypeId::TypeType, + auto make_tuple_inst = [&] { + return AddInst(SemIR::TupleType{parse_node, SemIR::TypeId::TypeType, type_blocks().Add(type_ids)}); }; return CanonicalizeTypeImpl(SemIR::TupleType::Kind, profile_tuple, - make_tuple_node); + make_tuple_inst); } auto Context::GetBuiltinType(SemIR::BuiltinKind kind) -> SemIR::TypeId { CARBON_CHECK(kind != SemIR::BuiltinKind::Invalid); - auto type_id = CanonicalizeType(SemIR::NodeId::ForBuiltin(kind)); + auto type_id = CanonicalizeType(SemIR::InstId::ForBuiltin(kind)); // To keep client code simpler, complete builtin types before returning them. bool complete = TryToCompleteType(type_id); CARBON_CHECK(complete) << "Failed to complete builtin type"; @@ -934,14 +934,14 @@ auto Context::GetBuiltinType(SemIR::BuiltinKind kind) -> SemIR::TypeId { auto Context::GetPointerType(Parse::Node parse_node, SemIR::TypeId pointee_type_id) -> SemIR::TypeId { - return CanonicalizeTypeAndAddNodeIfNew( + return CanonicalizeTypeAndAddInstIfNew( SemIR::PointerType{parse_node, SemIR::TypeId::TypeType, pointee_type_id}); } auto Context::GetUnqualifiedType(SemIR::TypeId type_id) -> SemIR::TypeId { - SemIR::Node type_node = - nodes().Get(sem_ir_->GetTypeAllowBuiltinTypes(type_id)); - if (auto const_type = type_node.TryAs()) { + SemIR::Inst type_inst = + insts().Get(sem_ir_->GetTypeAllowBuiltinTypes(type_id)); + if (auto const_type = type_inst.TryAs()) { return const_type->inner_id; } return type_id; @@ -949,7 +949,7 @@ auto Context::GetUnqualifiedType(SemIR::TypeId type_id) -> SemIR::TypeId { auto Context::PrintForStackDump(llvm::raw_ostream& output) const -> void { node_stack_.PrintForStackDump(output); - node_block_stack_.PrintForStackDump(output); + inst_block_stack_.PrintForStackDump(output); params_or_args_stack_.PrintForStackDump(output); args_type_info_stack_.PrintForStackDump(output); } diff --git a/toolchain/check/context.h b/toolchain/check/context.h index 46bc905a0a55..68245a3c4667 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -14,7 +14,7 @@ #include "toolchain/check/node_stack.h" #include "toolchain/parse/tree.h" #include "toolchain/sem_ir/file.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { @@ -26,8 +26,8 @@ class Context { // A scope in which `break` and `continue` can be used. struct BreakContinueScope { - SemIR::NodeBlockId break_target; - SemIR::NodeBlockId continue_target; + SemIR::InstBlockId break_target; + SemIR::InstBlockId continue_target; }; // Stores references for work. @@ -41,25 +41,25 @@ class Context { // Runs verification that the processing cleanly finished. auto VerifyOnFinish() -> void; - // Adds a node to the current block, returning the produced ID. - auto AddNode(SemIR::Node node) -> SemIR::NodeId; + // Adds an instruction to the current block, returning the produced ID. + auto AddInst(SemIR::Inst inst) -> SemIR::InstId; - // Pushes a parse tree node onto the stack, storing the SemIR::Node as the + // Pushes a parse tree node onto the stack, storing the SemIR::Inst as the // result. - auto AddNodeAndPush(Parse::Node parse_node, SemIR::Node node) -> void; + auto AddInstAndPush(Parse::Node parse_node, SemIR::Inst inst) -> void; // Adds a name to name lookup. Prints a diagnostic for name conflicts. auto AddNameToLookup(Parse::Node name_node, StringId name_id, - SemIR::NodeId target_id) -> void; + SemIR::InstId target_id) -> void; - // Performs name lookup in a specified scope, returning the referenced node. - // If scope_id is invalid, uses the current contextual scope. + // Performs name lookup in a specified scope, returning the referenced + // instruction. If scope_id is invalid, uses the current contextual scope. auto LookupName(Parse::Node parse_node, StringId name_id, SemIR::NameScopeId scope_id, bool print_diagnostics) - -> SemIR::NodeId; + -> SemIR::InstId; // Prints a diagnostic for a duplicate name. - auto DiagnoseDuplicateName(Parse::Node parse_node, SemIR::NodeId prev_def_id) + auto DiagnoseDuplicateName(Parse::Node parse_node, SemIR::InstId prev_def_id) -> void; // Prints a diagnostic for a missing name. @@ -70,7 +70,7 @@ class Context { -> void; // Pushes a new scope onto scope_stack_. - auto PushScope(SemIR::NodeId scope_node_id = SemIR::NodeId::Invalid, + auto PushScope(SemIR::InstId scope_inst_id = SemIR::InstId::Invalid, SemIR::NameScopeId scope_id = SemIR::NameScopeId::Invalid) -> void; @@ -84,55 +84,56 @@ class Context { // Returns the current scope, if it is of the specified kind. Otherwise, // returns nullopt. - template - auto GetCurrentScopeAs() -> std::optional { - auto current_scope_node_id = current_scope().scope_node_id; - if (!current_scope_node_id.is_valid()) { + template + auto GetCurrentScopeAs() -> std::optional { + auto current_scope_inst_id = current_scope().scope_inst_id; + if (!current_scope_inst_id.is_valid()) { return std::nullopt; } - return nodes().Get(current_scope_node_id).TryAs(); + return insts().Get(current_scope_inst_id).TryAs(); } - // Follows NameReference nodes to find the value named by a given node. - auto FollowNameReferences(SemIR::NodeId node_id) -> SemIR::NodeId; + // Follows NameReference instructions to find the value named by a given + // instruction. + auto FollowNameReferences(SemIR::InstId inst_id) -> SemIR::InstId; - // Gets the constant value of the given node, if it has one. - auto GetConstantValue(SemIR::NodeId node_id) -> SemIR::NodeId; + // Gets the constant value of the given instruction, if it has one. + auto GetConstantValue(SemIR::InstId inst_id) -> SemIR::InstId; - // Adds a `Branch` node branching to a new node block, and returns the ID of - // the new block. All paths to the branch target must go through the current - // block, though not necessarily through this branch. - auto AddDominatedBlockAndBranch(Parse::Node parse_node) -> SemIR::NodeBlockId; + // Adds a `Branch` instruction branching to a new instruction block, and + // returns the ID of the new block. All paths to the branch target must go + // through the current block, though not necessarily through this branch. + auto AddDominatedBlockAndBranch(Parse::Node parse_node) -> SemIR::InstBlockId; - // Adds a `Branch` node branching to a new node block with a value, and + // Adds a `Branch` instruction branching to a new instruction block with a + // value, and returns the ID of the new block. All paths to the branch target + // must go through the current block. + auto AddDominatedBlockAndBranchWithArg(Parse::Node parse_node, + SemIR::InstId arg_id) + -> SemIR::InstBlockId; + + // Adds a `BranchIf` instruction branching to a new instruction block, and // returns the ID of the new block. All paths to the branch target must go // through the current block. - auto AddDominatedBlockAndBranchWithArg(Parse::Node parse_node, - SemIR::NodeId arg_id) - -> SemIR::NodeBlockId; - - // Adds a `BranchIf` node branching to a new node block, and returns the ID - // of the new block. All paths to the branch target must go through the - // current block. auto AddDominatedBlockAndBranchIf(Parse::Node parse_node, - SemIR::NodeId cond_id) - -> SemIR::NodeBlockId; + SemIR::InstId cond_id) + -> SemIR::InstBlockId; // Handles recovergence of control flow. Adds branches from the top - // `num_blocks` on the node block stack to a new block, pops the existing - // blocks, and pushes the new block onto the node block stack. + // `num_blocks` on the instruction block stack to a new block, pops the + // existing blocks, and pushes the new block onto the instruction block stack. auto AddConvergenceBlockAndPush(Parse::Node parse_node, int num_blocks) -> void; // Handles recovergence of control flow with a result value. Adds branches - // from the top few blocks on the node block stack to a new block, pops the - // existing blocks, and pushes the new block onto the node block stack. The - // number of blocks popped is the size of `block_args`, and the corresponding - // result values are the elements of `block_args`. Returns a node referring - // to the result value. + // from the top few blocks on the instruction block stack to a new block, pops + // the existing blocks, and pushes the new block onto the instruction block + // stack. The number of blocks popped is the size of `block_args`, and the + // corresponding result values are the elements of `block_args`. Returns an + // instruction referring to the result value. auto AddConvergenceBlockWithArgAndPush( Parse::Node parse_node, - std::initializer_list blocks_and_args) -> SemIR::NodeId; + std::initializer_list blocks_and_args) -> SemIR::InstId; // Add the current code block to the enclosing function. auto AddCurrentCodeBlockToFunction() -> void; @@ -140,8 +141,8 @@ class Context { // Returns whether the current position in the current block is reachable. auto is_current_position_reachable() -> bool; - // Canonicalizes a type which is tracked as a single node. - auto CanonicalizeType(SemIR::NodeId node_id) -> SemIR::TypeId; + // Canonicalizes a type which is tracked as a single instruction. + auto CanonicalizeType(SemIR::InstId inst_id) -> SemIR::TypeId; // Handles canonicalization of struct types. This may create a new struct type // when it has a new structure, or reference an existing struct type when it @@ -151,7 +152,7 @@ class Context { // name conflicts or other diagnostics during creation, which can use the // parse node. auto CanonicalizeStructType(Parse::Node parse_node, - SemIR::NodeBlockId refs_id) -> SemIR::TypeId; + SemIR::InstBlockId refs_id) -> SemIR::TypeId; // Handles canonicalization of tuple types. This may create a new tuple type // if the `type_ids` doesn't match an existing tuple type. @@ -197,16 +198,16 @@ class Context { // Pops the current parameter or argument list. Should only be called after // `ParamOrArgEndNoPop`. - auto ParamOrArgPop() -> SemIR::NodeBlockId; + auto ParamOrArgPop() -> SemIR::InstBlockId; // Detects whether there's an entry to push. Pops and returns the argument // list. This is the same as `ParamOrArgEndNoPop` followed by `ParamOrArgPop`. - auto ParamOrArgEnd(Parse::NodeKind start_kind) -> SemIR::NodeBlockId; + auto ParamOrArgEnd(Parse::NodeKind start_kind) -> SemIR::InstBlockId; // Saves a parameter from the top block in node_stack_ to the top block in // params_or_args_stack_. - auto ParamOrArgSave(SemIR::NodeId node_id) -> void { - params_or_args_stack_.AddNodeId(node_id); + auto ParamOrArgSave(SemIR::InstId inst_id) -> void { + params_or_args_stack_.AddInstId(inst_id); } // Prints information for a stack dump. @@ -222,17 +223,17 @@ class Context { auto node_stack() -> NodeStack& { return node_stack_; } - auto node_block_stack() -> NodeBlockStack& { return node_block_stack_; } + auto inst_block_stack() -> InstBlockStack& { return inst_block_stack_; } - auto params_or_args_stack() -> NodeBlockStack& { + auto params_or_args_stack() -> InstBlockStack& { return params_or_args_stack_; } - auto args_type_info_stack() -> NodeBlockStack& { + auto args_type_info_stack() -> InstBlockStack& { return args_type_info_stack_; } - auto return_scope_stack() -> llvm::SmallVector& { + auto return_scope_stack() -> llvm::SmallVector& { return return_scope_stack_; } @@ -264,9 +265,9 @@ class Context { -> SemIR::BlockValueStore& { return sem_ir().type_blocks(); } - auto nodes() -> SemIR::NodeStore& { return sem_ir().nodes(); } - auto node_blocks() -> SemIR::NodeBlockStore& { - return sem_ir().node_blocks(); + auto insts() -> SemIR::InstStore& { return sem_ir().insts(); } + auto inst_blocks() -> SemIR::InstBlockStore& { + return sem_ir().inst_blocks(); } private: @@ -285,13 +286,13 @@ class Context { // An entry in scope_stack_. struct ScopeStackEntry { - // The node associated with this entry, if any. This can be one of: + // The instruction associated with this entry, if any. This can be one of: // // - A `ClassDeclaration`, for a class definition scope. // - A `FunctionDeclaration`, for the outermost scope in a function // definition. // - Invalid, for any other scope. - SemIR::NodeId scope_node_id; + SemIR::InstId scope_inst_id; // The name scope associated with this entry, if any. SemIR::NameScopeId scope_id; @@ -310,19 +311,19 @@ class Context { // type. The ID should be distinct for all distinct type values with the same // `kind`. // - // `make_node()` is called to obtain a `SemIR::NodeId` that describes the + // `make_inst()` is called to obtain a `SemIR::InstId` that describes the // type. It is only called if the type does not already exist, so can be used - // to lazily build the `SemIR::Node`. `make_node()` is not permitted to + // to lazily build the `SemIR::Inst`. `make_inst()` is not permitted to // directly or indirectly canonicalize any types. auto CanonicalizeTypeImpl( - SemIR::NodeKind kind, + SemIR::InstKind kind, llvm::function_ref profile_type, - llvm::function_ref make_node) -> SemIR::TypeId; + llvm::function_ref make_inst) -> SemIR::TypeId; - // Forms a canonical type ID for a type. If the type is new, adds the node to - // the current block. - auto CanonicalizeTypeAndAddNodeIfNew(SemIR::Node node) -> SemIR::TypeId; + // Forms a canonical type ID for a type. If the type is new, adds the + // instruction to the current block. + auto CanonicalizeTypeAndAddInstIfNew(SemIR::Inst inst) -> SemIR::TypeId; auto current_scope() -> ScopeStackEntry& { return scope_stack_.back(); } auto current_scope() const -> const ScopeStackEntry& { @@ -347,24 +348,24 @@ class Context { // The stack during Build. Will contain file-level parse nodes on return. NodeStack node_stack_; - // The stack of node blocks being used for general IR generation. - NodeBlockStack node_block_stack_; + // The stack of instruction blocks being used for general IR generation. + InstBlockStack inst_block_stack_; - // The stack of node blocks being used for per-element tracking of nodes in - // parameter and argument node blocks. Versus node_block_stack_, an element - // will have 1 or more nodes in blocks in node_block_stack_, but only ever 1 - // node in blocks here. - NodeBlockStack params_or_args_stack_; + // The stack of instruction blocks being used for per-element tracking of + // instructions in parameter and argument instruction blocks. Versus + // inst_block_stack_, an element will have 1 or more instructions in blocks in + // inst_block_stack_, but only ever 1 instruction in blocks here. + InstBlockStack params_or_args_stack_; - // The stack of node blocks being used for type information while processing - // arguments. This is used in parallel with params_or_args_stack_. It's - // currently only used for struct literals, where we need to track names + // The stack of instruction blocks being used for type information while + // processing arguments. This is used in parallel with params_or_args_stack_. + // It's currently only used for struct literals, where we need to track names // for a type separate from the literal arguments. - NodeBlockStack args_type_info_stack_; + InstBlockStack args_type_info_stack_; // A stack of return scopes; i.e., targets for `return`. Inside a function, // this will be a FunctionDeclaration. - llvm::SmallVector return_scope_stack_; + llvm::SmallVector return_scope_stack_; // A stack of `break` and `continue` targets. llvm::SmallVector break_continue_stack_; @@ -381,11 +382,11 @@ class Context { // reference. // // Names which no longer have lookup results are erased. - llvm::DenseMap> name_lookup_; + llvm::DenseMap> name_lookup_; - // Cache of the mapping from nodes to types, to avoid recomputing the folding - // set ID. - llvm::DenseMap canonical_types_; + // Cache of the mapping from instructions to types, to avoid recomputing the + // folding set ID. + llvm::DenseMap canonical_types_; // Tracks the canonical representation of types that have been defined. llvm::FoldingSet canonical_type_nodes_; diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 61ad6c6c1a46..c41c5b201ed1 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -13,7 +13,7 @@ #include "toolchain/diagnostics/diagnostic_kind.h" #include "toolchain/parse/node_kind.h" #include "toolchain/sem_ir/file.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/node_kind.h" namespace Carbon::Check { @@ -22,12 +22,12 @@ namespace Carbon::Check { // there is no return slot, because the initialization is not performed in // place. static auto FindReturnSlotForInitializer(SemIR::File& sem_ir, - SemIR::NodeId init_id) - -> SemIR::NodeId { - SemIR::Node init = sem_ir.nodes().Get(init_id); + SemIR::InstId init_id) + -> SemIR::InstId { + SemIR::Inst init = sem_ir.insts().Get(init_id); switch (init.kind()) { default: - CARBON_FATAL() << "Initialization from unexpected node " << init; + CARBON_FATAL() << "Initialization from unexpected inst " << init; case SemIR::StructInit::Kind: case SemIR::TupleInit::Kind: @@ -44,13 +44,13 @@ static auto FindReturnSlotForInitializer(SemIR::File& sem_ir, auto call = init.As(); if (!SemIR::GetInitializingRepresentation(sem_ir, call.type_id) .has_return_slot()) { - return SemIR::NodeId::Invalid; + return SemIR::InstId::Invalid; } - return sem_ir.node_blocks().Get(call.args_id).back(); + return sem_ir.inst_blocks().Get(call.args_id).back(); } case SemIR::ArrayInit::Kind: { - return sem_ir.node_blocks() + return sem_ir.inst_blocks() .Get(init.As().inits_and_return_slot_id) .back(); } @@ -58,17 +58,17 @@ static auto FindReturnSlotForInitializer(SemIR::File& sem_ir, } // Marks the initializer `init_id` as initializing `target_id`. -static auto MarkInitializerFor(SemIR::File& sem_ir, SemIR::NodeId init_id, - SemIR::NodeId target_id, +static auto MarkInitializerFor(SemIR::File& sem_ir, SemIR::InstId init_id, + SemIR::InstId target_id, PendingBlock& target_block) -> void { auto return_slot_id = FindReturnSlotForInitializer(sem_ir, init_id); if (return_slot_id.is_valid()) { // Replace the temporary in the return slot with a reference to our target. - CARBON_CHECK(sem_ir.nodes().Get(return_slot_id).kind() == + CARBON_CHECK(sem_ir.insts().Get(return_slot_id).kind() == SemIR::TemporaryStorage::Kind) << "Return slot for initializer does not contain a temporary; " << "initialized multiple times? Have " - << sem_ir.nodes().Get(return_slot_id); + << sem_ir.insts().Get(return_slot_id); target_block.MergeReplacing(return_slot_id, target_id); } } @@ -77,44 +77,44 @@ static auto MarkInitializerFor(SemIR::File& sem_ir, SemIR::NodeId init_id, // expression described by `init_id`, and returns the location of the // temporary. If `discarded` is `true`, the result is discarded, and no // temporary will be created if possible; if no temporary is created, the -// return value will be `SemIR::NodeId::Invalid`. -static auto FinalizeTemporary(Context& context, SemIR::NodeId init_id, - bool discarded) -> SemIR::NodeId { +// return value will be `SemIR::InstId::Invalid`. +static auto FinalizeTemporary(Context& context, SemIR::InstId init_id, + bool discarded) -> SemIR::InstId { auto& sem_ir = context.sem_ir(); auto return_slot_id = FindReturnSlotForInitializer(sem_ir, init_id); if (return_slot_id.is_valid()) { // The return slot should already have a materialized temporary in it. - CARBON_CHECK(sem_ir.nodes().Get(return_slot_id).kind() == + CARBON_CHECK(sem_ir.insts().Get(return_slot_id).kind() == SemIR::TemporaryStorage::Kind) << "Return slot for initializer does not contain a temporary; " << "initialized multiple times? Have " - << sem_ir.nodes().Get(return_slot_id); - auto init = sem_ir.nodes().Get(init_id); - return context.AddNode(SemIR::Temporary{init.parse_node(), init.type_id(), + << sem_ir.insts().Get(return_slot_id); + auto init = sem_ir.insts().Get(init_id); + return context.AddInst(SemIR::Temporary{init.parse_node(), init.type_id(), return_slot_id, init_id}); } if (discarded) { // Don't invent a temporary that we're going to discard. - return SemIR::NodeId::Invalid; + return SemIR::InstId::Invalid; } // The initializer has no return slot, but we want to produce a temporary // object. Materialize one now. // TODO: Consider using an invalid ID to mean that we immediately // materialize and initialize a temporary, rather than two separate - // nodes. - auto init = sem_ir.nodes().Get(init_id); - auto temporary_id = context.AddNode( + // instructions. + auto init = sem_ir.insts().Get(init_id); + auto temporary_id = context.AddInst( SemIR::TemporaryStorage{init.parse_node(), init.type_id()}); - return context.AddNode(SemIR::Temporary{init.parse_node(), init.type_id(), + return context.AddInst(SemIR::Temporary{init.parse_node(), init.type_id(), temporary_id, init_id}); } // Materialize a temporary to hold the result of the given expression if it is // an initializing expression. -static auto MaterializeIfInitializing(Context& context, SemIR::NodeId expr_id) - -> SemIR::NodeId { +static auto MaterializeIfInitializing(Context& context, SemIR::InstId expr_id) + -> SemIR::InstId { if (GetExpressionCategory(context.sem_ir(), expr_id) == SemIR::ExpressionCategory::Initializing) { return FinalizeTemporary(context, expr_id, /*discarded=*/false); @@ -122,23 +122,23 @@ static auto MaterializeIfInitializing(Context& context, SemIR::NodeId expr_id) return expr_id; } -// Creates and adds a node to perform element access into an aggregate. -template -static auto MakeElemAccessNode(Context& context, Parse::Node parse_node, - SemIR::NodeId aggregate_id, - SemIR::TypeId elem_type_id, NodeBlockT& block, +// Creates and adds an instruction to perform element access into an aggregate. +template +static auto MakeElemAccessInst(Context& context, Parse::Node parse_node, + SemIR::InstId aggregate_id, + SemIR::TypeId elem_type_id, InstBlockT& block, std::size_t i) { - if constexpr (std::is_same_v) { - // TODO: Add a new node kind for indexing an array at a constant index - // so that we don't need an integer literal node here, and remove this - // special case. - auto index_id = block.AddNode(SemIR::IntegerLiteral{ + if constexpr (std::is_same_v) { + // TODO: Add a new instruction kind for indexing an array at a constant + // index so that we don't need an integer literal instruction here, and + // remove this special case. + auto index_id = block.AddInst(SemIR::IntegerLiteral{ parse_node, context.GetBuiltinType(SemIR::BuiltinKind::IntegerType), context.sem_ir().integers().Add(llvm::APInt(32, i))}); - return block.AddNode( - AccessNodeT{parse_node, elem_type_id, aggregate_id, index_id}); + return block.AddInst( + AccessInstT{parse_node, elem_type_id, aggregate_id, index_id}); } else { - return block.AddNode(AccessNodeT{parse_node, elem_type_id, aggregate_id, + return block.AddInst(AccessInstT{parse_node, elem_type_id, aggregate_id, SemIR::MemberIndex(i)}); } } @@ -147,29 +147,29 @@ static auto MakeElemAccessNode(Context& context, Parse::Node parse_node, // another aggregate. // // For the source: `src_id` is the source aggregate, `src_elem_type` is the -// element type, `i` is the index, and `SourceAccessNodeT` is the kind of node -// used to access the source element. +// element type, `i` is the index, and `SourceAccessInstT` is the kind of +// instruction used to access the source element. // // For the target: `kind` is the kind of conversion or initialization, // `target_elem_type` is the element type. For initialization, `target_id` is // the destination, `target_block` is a pending block for target location // calculations that will be spliced as the return slot of the initializer if -// necessary, `i` is the index, and `TargetAccessNodeT` is the kind of node -// used to access the destination element. -template +// necessary, `i` is the index, and `TargetAccessInstT` is the kind of +// instruction used to access the destination element. +template static auto ConvertAggregateElement( - Context& context, Parse::Node parse_node, SemIR::NodeId src_id, + Context& context, Parse::Node parse_node, SemIR::InstId src_id, SemIR::TypeId src_elem_type, - llvm::ArrayRef src_literal_elems, - ConversionTarget::Kind kind, SemIR::NodeId target_id, + llvm::ArrayRef src_literal_elems, + ConversionTarget::Kind kind, SemIR::InstId target_id, SemIR::TypeId target_elem_type, PendingBlock* target_block, std::size_t i) { // Compute the location of the source element. This goes into the current code // block, not into the target block. - // TODO: Ideally we would discard this node if it's unused. + // TODO: Ideally we would discard this instruction if it's unused. auto src_elem_id = !src_literal_elems.empty() ? src_literal_elems[i] - : MakeElemAccessNode(context, parse_node, src_id, + : MakeElemAccessInst(context, parse_node, src_id, src_elem_type, context, i); // If we're performing a conversion rather than an initialization, we won't @@ -180,9 +180,9 @@ static auto ConvertAggregateElement( } // Compute the location of the target element and initialize it. - PendingBlock::DiscardUnusedNodesScope scope(target_block); + PendingBlock::DiscardUnusedInstsScope scope(target_block); target.init_block = target_block; - target.init_id = MakeElemAccessNode( + target.init_id = MakeElemAccessInst( context, parse_node, target_id, target_elem_type, *target_block, i); return Convert(context, parse_node, src_elem_id, target); } @@ -202,29 +202,29 @@ class CopyOnWriteBlock { // Constructs the block. If `source_id` is valid, it is used as the initial // value of the block. Otherwise, uninitialized storage for `size` elements // is allocated. - CopyOnWriteBlock(SemIR::File& file, SemIR::NodeBlockId source_id, size_t size) + CopyOnWriteBlock(SemIR::File& file, SemIR::InstBlockId source_id, size_t size) : file_(file), source_id_(source_id) { if (!source_id_.is_valid()) { - id_ = file_.node_blocks().AddUninitialized(size); + id_ = file_.inst_blocks().AddUninitialized(size); } } - auto id() -> SemIR::NodeBlockId const { return id_; } + auto id() -> SemIR::InstBlockId const { return id_; } - auto Set(int i, SemIR::NodeId value) -> void { - if (source_id_.is_valid() && file_.node_blocks().Get(id_)[i] == value) { + auto Set(int i, SemIR::InstId value) -> void { + if (source_id_.is_valid() && file_.inst_blocks().Get(id_)[i] == value) { return; } if (id_ == source_id_) { - id_ = file_.node_blocks().Add(file_.node_blocks().Get(source_id_)); + id_ = file_.inst_blocks().Add(file_.inst_blocks().Get(source_id_)); } - file_.node_blocks().Get(id_)[i] = value; + file_.inst_blocks().Get(id_)[i] = value; } private: SemIR::File& file_; - SemIR::NodeBlockId source_id_; - SemIR::NodeBlockId id_ = source_id_; + SemIR::InstBlockId source_id_; + SemIR::InstBlockId id_ = source_id_; }; } // namespace @@ -232,19 +232,19 @@ class CopyOnWriteBlock { // final conversion to the requested expression category. static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type, SemIR::ArrayType array_type, - SemIR::NodeId value_id, ConversionTarget target) - -> SemIR::NodeId { + SemIR::InstId value_id, ConversionTarget target) + -> SemIR::InstId { auto& sem_ir = context.sem_ir(); auto tuple_elem_types = sem_ir.type_blocks().Get(tuple_type.elements_id); - auto value = sem_ir.nodes().Get(value_id); + auto value = sem_ir.insts().Get(value_id); // If we're initializing from a tuple literal, we will use its elements // directly. Otherwise, materialize a temporary if needed and index into the // result. - llvm::ArrayRef literal_elems; + llvm::ArrayRef literal_elems; if (auto tuple_literal = value.TryAs()) { - literal_elems = sem_ir.node_blocks().Get(tuple_literal->elements_id); + literal_elems = sem_ir.inst_blocks().Get(tuple_literal->elements_id); } else { value_id = MaterializeIfInitializing(context, value_id); } @@ -265,7 +265,7 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type, ? ArrayInitFromExpressionArgCountMismatch : ArrayInitFromLiteralArgCountMismatch, array_bound, tuple_elem_types.size()); - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } PendingBlock target_block_storage(context); @@ -274,9 +274,9 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type, // Arrays are always initialized in-place. Allocate a temporary as the // destination for the array initialization if we weren't given one. - SemIR::NodeId return_slot_id = target.init_id; + SemIR::InstId return_slot_id = target.init_id; if (!target.init_id.is_valid()) { - return_slot_id = target_block->AddNode( + return_slot_id = target_block->AddInst( SemIR::TemporaryStorage{value.parse_node(), target.type_id}); } @@ -284,7 +284,7 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type, // tuple. // TODO: Annotate diagnostics coming from here with the array element index, // if initializing from a tuple literal. - llvm::SmallVector inits; + llvm::SmallVector inits; inits.reserve(array_bound + 1); for (auto [i, src_type_id] : llvm::enumerate(tuple_elem_types)) { // TODO: This call recurses back into conversion. Switch to an iterative @@ -294,8 +294,8 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type, context, value.parse_node(), value_id, src_type_id, literal_elems, ConversionTarget::FullInitializer, return_slot_id, array_type.element_type_id, target_block, i); - if (init_id == SemIR::NodeId::BuiltinError) { - return SemIR::NodeId::BuiltinError; + if (init_id == SemIR::InstId::BuiltinError) { + return SemIR::InstId::BuiltinError; } inits.push_back(init_id); } @@ -305,31 +305,31 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type, target_block->InsertHere(); inits.push_back(return_slot_id); - return context.AddNode(SemIR::ArrayInit{value.parse_node(), target.type_id, + return context.AddInst(SemIR::ArrayInit{value.parse_node(), target.type_id, value_id, - sem_ir.node_blocks().Add(inits)}); + sem_ir.inst_blocks().Add(inits)}); } // Performs a conversion from a tuple to a tuple type. Does not perform a // final conversion to the requested expression category. static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type, SemIR::TupleType dest_type, - SemIR::NodeId value_id, ConversionTarget target) - -> SemIR::NodeId { + SemIR::InstId value_id, ConversionTarget target) + -> SemIR::InstId { auto& sem_ir = context.sem_ir(); auto src_elem_types = sem_ir.type_blocks().Get(src_type.elements_id); auto dest_elem_types = sem_ir.type_blocks().Get(dest_type.elements_id); - auto value = sem_ir.nodes().Get(value_id); + auto value = sem_ir.insts().Get(value_id); // If we're initializing from a tuple literal, we will use its elements // directly. Otherwise, materialize a temporary if needed and index into the // result. - llvm::ArrayRef literal_elems; - auto literal_elems_id = SemIR::NodeBlockId::Invalid; + llvm::ArrayRef literal_elems; + auto literal_elems_id = SemIR::InstBlockId::Invalid; if (auto tuple_literal = value.TryAs()) { literal_elems_id = tuple_literal->elements_id; - literal_elems = sem_ir.node_blocks().Get(literal_elems_id); + literal_elems = sem_ir.inst_blocks().Get(literal_elems_id); } else { value_id = MaterializeIfInitializing(context, value_id); } @@ -342,7 +342,7 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type, size_t, size_t); context.emitter().Emit(value.parse_node(), TupleInitElementCountMismatch, dest_elem_types.size(), src_elem_types.size()); - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } // If we're forming an initializer, then we want an initializer for each @@ -369,16 +369,16 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type, ConvertAggregateElement( context, value.parse_node(), value_id, src_type_id, literal_elems, inner_kind, target.init_id, dest_type_id, target.init_block, i); - if (init_id == SemIR::NodeId::BuiltinError) { - return SemIR::NodeId::BuiltinError; + if (init_id == SemIR::InstId::BuiltinError) { + return SemIR::InstId::BuiltinError; } new_block.Set(i, init_id); } - return is_init ? context.AddNode(SemIR::TupleInit{value.parse_node(), + return is_init ? context.AddInst(SemIR::TupleInit{value.parse_node(), target.type_id, value_id, new_block.id()}) - : context.AddNode(SemIR::TupleValue{value.parse_node(), + : context.AddInst(SemIR::TupleValue{value.parse_node(), target.type_id, value_id, new_block.id()}); } @@ -387,22 +387,22 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type, // final conversion to the requested expression category. static auto ConvertStructToStruct(Context& context, SemIR::StructType src_type, SemIR::StructType dest_type, - SemIR::NodeId value_id, - ConversionTarget target) -> SemIR::NodeId { + SemIR::InstId value_id, + ConversionTarget target) -> SemIR::InstId { auto& sem_ir = context.sem_ir(); - auto src_elem_fields = sem_ir.node_blocks().Get(src_type.fields_id); - auto dest_elem_fields = sem_ir.node_blocks().Get(dest_type.fields_id); + auto src_elem_fields = sem_ir.inst_blocks().Get(src_type.fields_id); + auto dest_elem_fields = sem_ir.inst_blocks().Get(dest_type.fields_id); - auto value = sem_ir.nodes().Get(value_id); + auto value = sem_ir.insts().Get(value_id); // If we're initializing from a struct literal, we will use its elements // directly. Otherwise, materialize a temporary if needed and index into the // result. - llvm::ArrayRef literal_elems; - auto literal_elems_id = SemIR::NodeBlockId::Invalid; + llvm::ArrayRef literal_elems; + auto literal_elems_id = SemIR::InstBlockId::Invalid; if (auto struct_literal = value.TryAs()) { literal_elems_id = struct_literal->elements_id; - literal_elems = sem_ir.node_blocks().Get(literal_elems_id); + literal_elems = sem_ir.inst_blocks().Get(literal_elems_id); } else { value_id = MaterializeIfInitializing(context, value_id); } @@ -417,7 +417,7 @@ static auto ConvertStructToStruct(Context& context, SemIR::StructType src_type, size_t, size_t); context.emitter().Emit(value.parse_node(), StructInitElementCountMismatch, dest_elem_fields.size(), src_elem_fields.size()); - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } // Prepare to look up fields in the source by index. @@ -425,7 +425,7 @@ static auto ConvertStructToStruct(Context& context, SemIR::StructType src_type, if (src_type.fields_id != dest_type.fields_id) { for (auto [i, field_id] : llvm::enumerate(src_elem_fields)) { auto [it, added] = src_field_indexes.insert( - {context.nodes().GetAs(field_id).name_id, i}); + {context.insts().GetAs(field_id).name_id, i}); CARBON_CHECK(added) << "Duplicate field in source structure"; } } @@ -448,7 +448,7 @@ static auto ConvertStructToStruct(Context& context, SemIR::StructType src_type, CopyOnWriteBlock new_block(sem_ir, literal_elems_id, src_elem_fields.size()); for (auto [i, dest_field_id] : llvm::enumerate(dest_elem_fields)) { auto dest_field = - sem_ir.nodes().GetAs(dest_field_id); + sem_ir.insts().GetAs(dest_field_id); // Find the matching source field. auto src_field_index = i; @@ -474,11 +474,11 @@ static auto ConvertStructToStruct(Context& context, SemIR::StructType src_type, sem_ir.StringifyType(target.type_id), sem_ir.strings().Get(dest_field.name_id)); } - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } src_field_index = src_field_it->second; } - auto src_field = sem_ir.nodes().GetAs( + auto src_field = sem_ir.insts().GetAs( src_elem_fields[src_field_index]); // TODO: This call recurses back into conversion. Switch to an iterative @@ -488,16 +488,16 @@ static auto ConvertStructToStruct(Context& context, SemIR::StructType src_type, context, value.parse_node(), value_id, src_field.field_type_id, literal_elems, inner_kind, target.init_id, dest_field.field_type_id, target.init_block, src_field_index); - if (init_id == SemIR::NodeId::BuiltinError) { - return SemIR::NodeId::BuiltinError; + if (init_id == SemIR::InstId::BuiltinError) { + return SemIR::InstId::BuiltinError; } new_block.Set(i, init_id); } - return is_init ? context.AddNode(SemIR::StructInit{value.parse_node(), + return is_init ? context.AddInst(SemIR::StructInit{value.parse_node(), target.type_id, value_id, new_block.id()}) - : context.AddNode(SemIR::StructValue{value.parse_node(), + : context.AddInst(SemIR::StructValue{value.parse_node(), target.type_id, value_id, new_block.id()}); } @@ -525,13 +525,13 @@ static bool IsValidExpressionCategoryForConversionTarget( } static auto PerformBuiltinConversion(Context& context, Parse::Node parse_node, - SemIR::NodeId value_id, - ConversionTarget target) -> SemIR::NodeId { + SemIR::InstId value_id, + ConversionTarget target) -> SemIR::InstId { auto& sem_ir = context.sem_ir(); - auto value = sem_ir.nodes().Get(value_id); + auto value = sem_ir.insts().Get(value_id); auto value_type_id = value.type_id(); - auto target_type_node = - sem_ir.nodes().Get(sem_ir.GetTypeAllowBuiltinTypes(target.type_id)); + auto target_type_inst = + sem_ir.insts().Get(sem_ir.GetTypeAllowBuiltinTypes(target.type_id)); // Various forms of implicit conversion are supported as builtin conversions, // either in addition to or instead of `impl`s of `ImplicitAs` in the Carbon @@ -582,7 +582,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::Node parse_node, // The initializer produces an object representation by copy, and the // value representation is a copy of the object representation, so we // already have a value of the right form. - return context.AddNode( + return context.AddInst( SemIR::ValueOfInitializer{parse_node, value_type_id, value_id}); } } @@ -590,10 +590,10 @@ static auto PerformBuiltinConversion(Context& context, Parse::Node parse_node, // A tuple (T1, T2, ..., Tn) converts to (U1, U2, ..., Un) if each Ti // converts to Ui. - if (auto target_tuple_type = target_type_node.TryAs()) { - auto value_type_node = - sem_ir.nodes().Get(sem_ir.GetTypeAllowBuiltinTypes(value_type_id)); - if (auto src_tuple_type = value_type_node.TryAs()) { + if (auto target_tuple_type = target_type_inst.TryAs()) { + auto value_type_inst = + sem_ir.insts().Get(sem_ir.GetTypeAllowBuiltinTypes(value_type_id)); + if (auto src_tuple_type = value_type_inst.TryAs()) { return ConvertTupleToTuple(context, *src_tuple_type, *target_tuple_type, value_id, target); } @@ -603,20 +603,20 @@ static auto PerformBuiltinConversion(Context& context, Parse::Node parse_node, // {.f_p(1): U_p(1), .f_p(2): U_p(2), ..., .f_p(n): U_p(n)} if // (p(1), ..., p(n)) is a permutation of (1, ..., n) and each Ti converts // to Ui. - if (auto target_struct_type = target_type_node.TryAs()) { - auto value_type_node = - sem_ir.nodes().Get(sem_ir.GetTypeAllowBuiltinTypes(value_type_id)); - if (auto src_struct_type = value_type_node.TryAs()) { + if (auto target_struct_type = target_type_inst.TryAs()) { + auto value_type_inst = + sem_ir.insts().Get(sem_ir.GetTypeAllowBuiltinTypes(value_type_id)); + if (auto src_struct_type = value_type_inst.TryAs()) { return ConvertStructToStruct(context, *src_struct_type, *target_struct_type, value_id, target); } } // A tuple (T1, T2, ..., Tn) converts to [T; n] if each Ti converts to T. - if (auto target_array_type = target_type_node.TryAs()) { - auto value_type_node = - sem_ir.nodes().Get(sem_ir.GetTypeAllowBuiltinTypes(value_type_id)); - if (auto src_tuple_type = value_type_node.TryAs()) { + if (auto target_array_type = target_type_inst.TryAs()) { + auto value_type_inst = + sem_ir.insts().Get(sem_ir.GetTypeAllowBuiltinTypes(value_type_id)); + if (auto src_tuple_type = value_type_inst.TryAs()) { return ConvertTupleToArray(context, *src_tuple_type, *target_array_type, value_id, target); } @@ -627,12 +627,12 @@ static auto PerformBuiltinConversion(Context& context, Parse::Node parse_node, // TODO: This should apply even for non-literal tuples. if (auto tuple_literal = value.TryAs()) { llvm::SmallVector type_ids; - for (auto tuple_node_id : - sem_ir.node_blocks().Get(tuple_literal->elements_id)) { + for (auto tuple_inst_id : + sem_ir.inst_blocks().Get(tuple_literal->elements_id)) { // TODO: This call recurses back into conversion. Switch to an // iterative approach. type_ids.push_back( - ExpressionAsType(context, parse_node, tuple_node_id)); + ExpressionAsType(context, parse_node, tuple_inst_id)); } auto tuple_type_id = context.CanonicalizeTupleType(parse_node, std::move(type_ids)); @@ -644,7 +644,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::Node parse_node, // of type `{}`. if (auto struct_literal = value.TryAs(); struct_literal && - struct_literal->elements_id == SemIR::NodeBlockId::Empty) { + struct_literal->elements_id == SemIR::InstBlockId::Empty) { value_id = sem_ir.GetTypeAllowBuiltinTypes(value_type_id); } } @@ -655,12 +655,12 @@ static auto PerformBuiltinConversion(Context& context, Parse::Node parse_node, // Given a value expression, form a corresponding initializer that copies from // that value, if it is possible to do so. -static auto PerformCopy(Context& context, SemIR::NodeId expr_id) - -> SemIR::NodeId { - auto expr = context.nodes().Get(expr_id); +static auto PerformCopy(Context& context, SemIR::InstId expr_id) + -> SemIR::InstId { + auto expr = context.insts().Get(expr_id); auto type_id = expr.type_id(); if (type_id == SemIR::TypeId::Error) { - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } // TODO: Directly track on the value representation whether it's a copy of @@ -680,19 +680,19 @@ static auto PerformCopy(Context& context, SemIR::NodeId expr_id) "Cannot copy value of type `{0}`.", std::string); context.emitter().Emit(expr.parse_node(), CopyOfUncopyableType, context.sem_ir().StringifyType(type_id)); - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } -auto Convert(Context& context, Parse::Node parse_node, SemIR::NodeId expr_id, - ConversionTarget target) -> SemIR::NodeId { +auto Convert(Context& context, Parse::Node parse_node, SemIR::InstId expr_id, + ConversionTarget target) -> SemIR::InstId { auto& sem_ir = context.sem_ir(); auto orig_expr_id = expr_id; // Start by making sure both sides are valid. If any part is invalid, the // result is invalid and we shouldn't error. - if (sem_ir.nodes().Get(expr_id).type_id() == SemIR::TypeId::Error || + if (sem_ir.insts().Get(expr_id).type_id() == SemIR::TypeId::Error || target.type_id == SemIR::TypeId::Error) { - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } if (SemIR::GetExpressionCategory(sem_ir, expr_id) == @@ -702,9 +702,9 @@ auto Convert(Context& context, Parse::Node parse_node, SemIR::NodeId expr_id, // namespace names, and allow use of functions as values. CARBON_DIAGNOSTIC(UseOfNonExpressionAsValue, Error, "Expression cannot be used as a value."); - context.emitter().Emit(sem_ir.nodes().Get(expr_id).parse_node(), + context.emitter().Emit(sem_ir.insts().Get(expr_id).parse_node(), UseOfNonExpressionAsValue); - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } // We can only perform initialization for complete types. @@ -725,19 +725,19 @@ auto Convert(Context& context, Parse::Node parse_node, SemIR::NodeId expr_id, : IncompleteTypeInConversion, context.sem_ir().StringifyType(target.type_id, true)); })) { - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } // Check whether any builtin conversion applies. expr_id = PerformBuiltinConversion(context, parse_node, expr_id, target); - if (expr_id == SemIR::NodeId::BuiltinError) { + if (expr_id == SemIR::InstId::BuiltinError) { return expr_id; } // If the types don't match at this point, we can't perform the conversion. // TODO: Look for an `ImplicitAs` impl, or an `As` impl in the case where // `target.kind == ConversionTarget::ExplicitAs`. - SemIR::Node expr = sem_ir.nodes().Get(expr_id); + SemIR::Inst expr = sem_ir.insts().Get(expr_id); if (expr.type_id() != target.type_id) { CARBON_DIAGNOSTIC(ImplicitAsConversionFailure, Error, "Cannot implicitly convert from `{0}` to `{1}`.", @@ -753,7 +753,7 @@ auto Convert(Context& context, Parse::Node parse_node, SemIR::NodeId expr_id, sem_ir.StringifyType(expr.type_id()), sem_ir.StringifyType(target.type_id)) .Emit(); - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } // For `as`, don't perform any value category conversions. In particular, an @@ -770,7 +770,7 @@ auto Convert(Context& context, Parse::Node parse_node, SemIR::NodeId expr_id, << " after builtin conversions"; case SemIR::ExpressionCategory::Error: - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; case SemIR::ExpressionCategory::Initializing: if (target.is_initializer()) { @@ -803,7 +803,7 @@ auto Convert(Context& context, Parse::Node parse_node, SemIR::NodeId expr_id, // If we have a reference and don't want one, form a value binding. // TODO: Support types with custom value representations. - expr_id = context.AddNode( + expr_id = context.AddInst( SemIR::BindValue{expr.parse_node(), expr.type_id(), expr_id}); // We now have a value expression. [[fallthrough]]; @@ -822,7 +822,7 @@ auto Convert(Context& context, Parse::Node parse_node, SemIR::NodeId expr_id, SemIR::GetInitializingRepresentation(sem_ir, target.type_id); init_rep.kind == SemIR::InitializingRepresentation::ByCopy) { target.init_block->InsertHere(); - expr_id = context.AddNode(SemIR::InitializeFrom{ + expr_id = context.AddInst(SemIR::InitializeFrom{ parse_node, target.type_id, expr_id, target.init_id}); } } @@ -831,49 +831,49 @@ auto Convert(Context& context, Parse::Node parse_node, SemIR::NodeId expr_id, } auto Initialize(Context& context, Parse::Node parse_node, - SemIR::NodeId target_id, SemIR::NodeId value_id) - -> SemIR::NodeId { + SemIR::InstId target_id, SemIR::InstId value_id) + -> SemIR::InstId { PendingBlock target_block(context); return Convert(context, parse_node, value_id, {.kind = ConversionTarget::Initializer, - .type_id = context.sem_ir().nodes().Get(target_id).type_id(), + .type_id = context.sem_ir().insts().Get(target_id).type_id(), .init_id = target_id, .init_block = &target_block}); } -auto ConvertToValueExpression(Context& context, SemIR::NodeId expr_id) - -> SemIR::NodeId { - auto expr = context.sem_ir().nodes().Get(expr_id); +auto ConvertToValueExpression(Context& context, SemIR::InstId expr_id) + -> SemIR::InstId { + auto expr = context.sem_ir().insts().Get(expr_id); return Convert(context, expr.parse_node(), expr_id, {.kind = ConversionTarget::Value, .type_id = expr.type_id()}); } auto ConvertToValueOrReferenceExpression(Context& context, - SemIR::NodeId expr_id) - -> SemIR::NodeId { - auto expr = context.sem_ir().nodes().Get(expr_id); + SemIR::InstId expr_id) + -> SemIR::InstId { + auto expr = context.sem_ir().insts().Get(expr_id); return Convert( context, expr.parse_node(), expr_id, {.kind = ConversionTarget::ValueOrReference, .type_id = expr.type_id()}); } auto ConvertToValueOfType(Context& context, Parse::Node parse_node, - SemIR::NodeId value_id, SemIR::TypeId type_id) - -> SemIR::NodeId { + SemIR::InstId value_id, SemIR::TypeId type_id) + -> SemIR::InstId { return Convert(context, parse_node, value_id, {.kind = ConversionTarget::Value, .type_id = type_id}); } auto ConvertToBoolValue(Context& context, Parse::Node parse_node, - SemIR::NodeId value_id) -> SemIR::NodeId { + SemIR::InstId value_id) -> SemIR::InstId { return ConvertToValueOfType( context, parse_node, value_id, context.GetBuiltinType(SemIR::BuiltinKind::BoolType)); } auto ConvertForExplicitAs(Context& context, Parse::Node as_node, - SemIR::NodeId value_id, SemIR::TypeId type_id) - -> SemIR::NodeId { + SemIR::InstId value_id, SemIR::TypeId type_id) + -> SemIR::InstId { return Convert(context, as_node, value_id, {.kind = ConversionTarget::ExplicitAs, .type_id = type_id}); } @@ -883,8 +883,8 @@ CARBON_DIAGNOSTIC(InCallToFunction, Note, "Calling function declared here."); // Convert the object argument in a method call to match the `self` parameter. static auto ConvertSelf(Context& context, Parse::Node call_parse_node, Parse::Node callee_parse_node, - SemIR::SelfParameter self_param, SemIR::NodeId self_id) - -> SemIR::NodeId { + SemIR::SelfParameter self_param, SemIR::InstId self_id) + -> SemIR::InstId { if (!self_id.is_valid()) { CARBON_DIAGNOSTIC(MissingObjectInMethodCall, Error, "Missing object argument in method call."); @@ -892,7 +892,7 @@ static auto ConvertSelf(Context& context, Parse::Node call_parse_node, .Build(call_parse_node, MissingObjectInMethodCall) .Note(callee_parse_node, InCallToFunction) .Emit(); - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } DiagnosticAnnotationScope annotate_diagnostics( @@ -912,7 +912,7 @@ static auto ConvertSelf(Context& context, Parse::Node call_parse_node, if (self_param.is_addr_self.index) { self_or_addr_id = ConvertToValueOrReferenceExpression(context, self_or_addr_id); - auto self = context.nodes().Get(self_or_addr_id); + auto self = context.insts().Get(self_or_addr_id); switch (SemIR::GetExpressionCategory(context.sem_ir(), self_id)) { case SemIR::ExpressionCategory::Error: case SemIR::ExpressionCategory::DurableReference: @@ -922,9 +922,9 @@ static auto ConvertSelf(Context& context, Parse::Node call_parse_node, CARBON_DIAGNOSTIC(AddrSelfIsNonReference, Error, "`addr self` method cannot be invoked on a value."); context.emitter().Emit(call_parse_node, AddrSelfIsNonReference); - return SemIR::NodeId::BuiltinError; + return SemIR::InstId::BuiltinError; } - self_or_addr_id = context.AddNode(SemIR::AddressOf{ + self_or_addr_id = context.AddInst(SemIR::AddressOf{ self.parse_node(), context.GetPointerType(self.parse_node(), self.type_id()), self_or_addr_id}); @@ -935,15 +935,15 @@ static auto ConvertSelf(Context& context, Parse::Node call_parse_node, } auto ConvertCallArgs(Context& context, Parse::Node call_parse_node, - SemIR::NodeId self_id, - llvm::ArrayRef arg_refs, - SemIR::NodeId return_storage_id, + SemIR::InstId self_id, + llvm::ArrayRef arg_refs, + SemIR::InstId return_storage_id, Parse::Node callee_parse_node, - SemIR::NodeBlockId implicit_param_refs_id, - SemIR::NodeBlockId param_refs_id) -> SemIR::NodeBlockId { + SemIR::InstBlockId implicit_param_refs_id, + SemIR::InstBlockId param_refs_id) -> SemIR::InstBlockId { auto implicit_param_refs = - context.sem_ir().node_blocks().Get(implicit_param_refs_id); - auto param_refs = context.sem_ir().node_blocks().Get(param_refs_id); + context.sem_ir().inst_blocks().Get(implicit_param_refs_id); + auto param_refs = context.sem_ir().inst_blocks().Get(param_refs_id); // If sizes mismatch, fail early. if (arg_refs.size() != param_refs.size()) { @@ -956,28 +956,28 @@ auto ConvertCallArgs(Context& context, Parse::Node call_parse_node, param_refs.size()) .Note(callee_parse_node, InCallToFunction) .Emit(); - return SemIR::NodeBlockId::Invalid; + return SemIR::InstBlockId::Invalid; } // Start building a block to hold the converted arguments. - llvm::SmallVector args; + llvm::SmallVector args; args.reserve(implicit_param_refs.size() + param_refs.size() + return_storage_id.is_valid()); // Check implicit parameters. for (auto implicit_param_id : implicit_param_refs) { - auto param = context.nodes().Get(implicit_param_id); + auto param = context.insts().Get(implicit_param_id); if (auto self_param = param.TryAs()) { auto converted_self_id = ConvertSelf( context, call_parse_node, callee_parse_node, *self_param, self_id); - if (converted_self_id == SemIR::NodeId::BuiltinError) { - return SemIR::NodeBlockId::Invalid; + if (converted_self_id == SemIR::InstId::BuiltinError) { + return SemIR::InstBlockId::Invalid; } args.push_back(converted_self_id); } else { // TODO: Form argument values for implicit parameters. context.TODO(call_parse_node, "Call with implicit parameters"); - return SemIR::NodeBlockId::Invalid; + return SemIR::InstBlockId::Invalid; } } @@ -995,13 +995,13 @@ auto ConvertCallArgs(Context& context, Parse::Node call_parse_node, for (auto [i, arg_id, param_id] : llvm::enumerate(arg_refs, param_refs)) { diag_param_index = i; - auto param_type_id = context.sem_ir().nodes().Get(param_id).type_id(); + auto param_type_id = context.sem_ir().insts().Get(param_id).type_id(); // TODO: Convert to the proper expression category. For now, we assume // parameters are all `let` bindings. auto converted_arg_id = ConvertToValueOfType(context, call_parse_node, arg_id, param_type_id); - if (converted_arg_id == SemIR::NodeId::BuiltinError) { - return SemIR::NodeBlockId::Invalid; + if (converted_arg_id == SemIR::InstId::BuiltinError) { + return SemIR::InstBlockId::Invalid; } args.push_back(converted_arg_id); @@ -1012,11 +1012,11 @@ auto ConvertCallArgs(Context& context, Parse::Node call_parse_node, args.push_back(return_storage_id); } - return context.node_blocks().Add(args); + return context.inst_blocks().Add(args); } auto ExpressionAsType(Context& context, Parse::Node parse_node, - SemIR::NodeId value_id) -> SemIR::TypeId { + SemIR::InstId value_id) -> SemIR::TypeId { return context.CanonicalizeType(ConvertToValueOfType( context, parse_node, value_id, SemIR::TypeId::TypeType)); } diff --git a/toolchain/check/convert.h b/toolchain/check/convert.h index d99e3cdc8bd6..46bde67ccadd 100644 --- a/toolchain/check/convert.h +++ b/toolchain/check/convert.h @@ -8,7 +8,7 @@ #include "toolchain/check/context.h" #include "toolchain/check/pending_block.h" #include "toolchain/parse/tree.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { @@ -39,7 +39,7 @@ struct ConversionTarget { // The target type for the conversion. SemIR::TypeId type_id; // For an initializer, the object being initialized. - SemIR::NodeId init_id = SemIR::NodeId::Invalid; + SemIR::InstId init_id = SemIR::InstId::Invalid; // For an initializer, a block of pending instructions that are needed to // form the value of `target_id`, and that can be discarded if no // initialization is needed. @@ -52,54 +52,54 @@ struct ConversionTarget { }; // Convert a value to another type and expression category. -auto Convert(Context& context, Parse::Node parse_node, SemIR::NodeId value_id, - ConversionTarget target) -> SemIR::NodeId; +auto Convert(Context& context, Parse::Node parse_node, SemIR::InstId value_id, + ConversionTarget target) -> SemIR::InstId; // Performs initialization of `target_id` from `value_id`. Returns the // possibly-converted initializing expression, which should be assigned to the // target using a suitable node for the kind of initialization. auto Initialize(Context& context, Parse::Node parse_node, - SemIR::NodeId target_id, SemIR::NodeId value_id) - -> SemIR::NodeId; + SemIR::InstId target_id, SemIR::InstId value_id) + -> SemIR::InstId; // Convert the given expression to a value expression of the same type. -auto ConvertToValueExpression(Context& context, SemIR::NodeId expr_id) - -> SemIR::NodeId; +auto ConvertToValueExpression(Context& context, SemIR::InstId expr_id) + -> SemIR::InstId; // Convert the given expression to a value or reference expression of the same // type. auto ConvertToValueOrReferenceExpression(Context& context, - SemIR::NodeId expr_id) - -> SemIR::NodeId; + SemIR::InstId expr_id) + -> SemIR::InstId; // Converts `value_id` to a value expression of type `type_id`. auto ConvertToValueOfType(Context& context, Parse::Node parse_node, - SemIR::NodeId value_id, SemIR::TypeId type_id) - -> SemIR::NodeId; + SemIR::InstId value_id, SemIR::TypeId type_id) + -> SemIR::InstId; // Converts `value_id` to a value expression of type `bool`. auto ConvertToBoolValue(Context& context, Parse::Node parse_node, - SemIR::NodeId value_id) -> SemIR::NodeId; + SemIR::InstId value_id) -> SemIR::InstId; // Converts `value_id` to type `type_id` for an `as` expression. auto ConvertForExplicitAs(Context& context, Parse::Node as_node, - SemIR::NodeId value_id, SemIR::TypeId type_id) - -> SemIR::NodeId; + SemIR::InstId value_id, SemIR::TypeId type_id) + -> SemIR::InstId; // Implicitly converts a set of arguments to match the parameter types in a // function call. Returns a block containing the converted implicit and explicit // argument values. auto ConvertCallArgs(Context& context, Parse::Node call_parse_node, - SemIR::NodeId self_id, - llvm::ArrayRef arg_refs, - SemIR::NodeId return_storage_id, + SemIR::InstId self_id, + llvm::ArrayRef arg_refs, + SemIR::InstId return_storage_id, Parse::Node callee_parse_node, - SemIR::NodeBlockId implicit_param_refs_id, - SemIR::NodeBlockId param_refs_id) -> SemIR::NodeBlockId; + SemIR::InstBlockId implicit_param_refs_id, + SemIR::InstBlockId param_refs_id) -> SemIR::InstBlockId; // Converts an expression for use as a type. auto ExpressionAsType(Context& context, Parse::Node parse_node, - SemIR::NodeId value_id) -> SemIR::TypeId; + SemIR::InstId value_id) -> SemIR::TypeId; } // namespace Carbon::Check diff --git a/toolchain/check/declaration_name_stack.cpp b/toolchain/check/declaration_name_stack.cpp index b96946852f94..8c15916831aa 100644 --- a/toolchain/check/declaration_name_stack.cpp +++ b/toolchain/check/declaration_name_stack.cpp @@ -43,12 +43,12 @@ auto DeclarationNameStack::Pop() -> NameContext { } auto DeclarationNameStack::LookupOrAddName(NameContext name_context, - SemIR::NodeId target_id) - -> SemIR::NodeId { + SemIR::InstId target_id) + -> SemIR::InstId { switch (name_context.state) { case NameContext::State::Error: // The name is invalid and a diagnostic has already been emitted. - return SemIR::NodeId::Invalid; + return SemIR::InstId::Invalid; case NameContext::State::Empty: CARBON_FATAL() << "Name is missing, not expected to call AddNameToLookup " @@ -56,7 +56,7 @@ auto DeclarationNameStack::LookupOrAddName(NameContext name_context, case NameContext::State::Resolved: case NameContext::State::ResolvedNonScope: - return name_context.resolved_node_id; + return name_context.resolved_inst_id; case NameContext::State::Unresolved: if (name_context.target_scope_id == SemIR::NameScopeId::Invalid) { @@ -73,15 +73,15 @@ auto DeclarationNameStack::LookupOrAddName(NameContext name_context, << name_context.unresolved_name_id << " in " << name_context.target_scope_id; } - return SemIR::NodeId::Invalid; + return SemIR::InstId::Invalid; } } auto DeclarationNameStack::AddNameToLookup(NameContext name_context, - SemIR::NodeId target_id) -> void { - auto existing_node_id = LookupOrAddName(name_context, target_id); - if (existing_node_id.is_valid()) { - context_->DiagnoseDuplicateName(name_context.parse_node, existing_node_id); + SemIR::InstId target_id) -> void { + auto existing_inst_id = LookupOrAddName(name_context, target_id); + if (existing_inst_id.is_valid()) { + context_->DiagnoseDuplicateName(name_context.parse_node, existing_inst_id); } } @@ -95,22 +95,23 @@ auto DeclarationNameStack::ApplyNameQualifierTo(NameContext& name_context, StringId name_id) -> void { if (CanResolveQualifier(name_context, parse_node)) { // For identifier nodes, we need to perform a lookup on the identifier. - // This means the input node_id is actually a string ID. + // This means the input instruction name_id is actually a string ID. // // TODO: This doesn't perform the right kind of lookup. We will find names // from enclosing lexical scopes here, in the case where `target_scope_id` // is invalid. - auto resolved_node_id = context_->LookupName( + auto resolved_inst_id = context_->LookupName( name_context.parse_node, name_id, name_context.target_scope_id, /*print_diagnostics=*/false); - if (resolved_node_id == SemIR::NodeId::BuiltinError) { - // Invalid indicates an unresolved node. Store it and return. + if (resolved_inst_id == SemIR::InstId::BuiltinError) { + // Invalid indicates an unresolved instruction. Store it and return. name_context.state = NameContext::State::Unresolved; name_context.unresolved_name_id = name_id; return; } else { - // Store the resolved node and continue for the target scope update. - name_context.resolved_node_id = resolved_node_id; + // Store the resolved instruction and continue for the target scope + // update. + name_context.resolved_inst_id = resolved_inst_id; } UpdateScopeIfNeeded(name_context); @@ -119,13 +120,13 @@ auto DeclarationNameStack::ApplyNameQualifierTo(NameContext& name_context, auto DeclarationNameStack::UpdateScopeIfNeeded(NameContext& name_context) -> void { - // This will only be reached for resolved nodes. We update the target + // This will only be reached for resolved instructions. We update the target // scope based on the resolved type. - auto resolved_node = context_->nodes().Get(name_context.resolved_node_id); - switch (resolved_node.kind()) { + auto resolved_inst = context_->insts().Get(name_context.resolved_inst_id); + switch (resolved_inst.kind()) { case SemIR::ClassDeclaration::Kind: { const auto& class_info = context_->classes().Get( - resolved_node.As().class_id); + resolved_inst.As().class_id); if (class_info.is_defined()) { name_context.state = NameContext::State::Resolved; name_context.target_scope_id = class_info.scope_id; @@ -137,7 +138,7 @@ auto DeclarationNameStack::UpdateScopeIfNeeded(NameContext& name_context) case SemIR::Namespace::Kind: name_context.state = NameContext::State::Resolved; name_context.target_scope_id = - resolved_node.As().name_scope_id; + resolved_inst.As().name_scope_id; break; default: name_context.state = NameContext::State::ResolvedNonScope; @@ -163,8 +164,8 @@ auto DeclarationNameStack::CanResolveQualifier(NameContext& name_context, case NameContext::State::ResolvedNonScope: { // Because more qualifiers were found, we diagnose that the earlier // qualifier didn't resolve to a scoped entity. - if (auto class_decl = context_->nodes() - .Get(name_context.resolved_node_id) + if (auto class_decl = context_->insts() + .Get(name_context.resolved_inst_id) .TryAs()) { CARBON_DIAGNOSTIC(QualifiedDeclarationInIncompleteClassScope, Error, "Cannot declare a member of incomplete class `{0}`.", diff --git a/toolchain/check/declaration_name_stack.h b/toolchain/check/declaration_name_stack.h index 0968e8db6a65..48f21b0e0ea9 100644 --- a/toolchain/check/declaration_name_stack.h +++ b/toolchain/check/declaration_name_stack.h @@ -7,7 +7,7 @@ #include "llvm/ADT/SmallVector.h" #include "toolchain/parse/tree.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { @@ -55,11 +55,11 @@ class DeclarationNameStack { // A context that has not processed any parts of the qualifier. Empty, - // A node ID has been resolved, whether through an identifier or + // An instruction ID has been resolved, whether through an identifier or // expression. This provided a new scope, such as a type. Resolved, - // A node ID has been resolved, whether through an identifier or + // An instruction ID has been resolved, whether through an identifier or // expression. It did not provide a new scope, so must be the final part, // such as an out-of-line function definition. ResolvedNonScope, @@ -85,7 +85,7 @@ class DeclarationNameStack { union { // The ID of a resolved qualifier, including both identifiers and // expressions. Invalid indicates resolution failed. - SemIR::NodeId resolved_node_id = SemIR::NodeId::Invalid; + SemIR::InstId resolved_inst_id = SemIR::InstId::Invalid; // The ID of an unresolved identifier. StringId unresolved_name_id; @@ -100,7 +100,7 @@ class DeclarationNameStack { // Pops the current declaration name processing, returning the final context // for adding the name to lookup. This also pops the final name node from the - // node stack, which will be applied to the declaration name if appropriate. + // name stack, which will be applied to the declaration name if appropriate. auto Pop() -> NameContext; // Creates and returns a name context corresponding to declaring an @@ -110,24 +110,24 @@ class DeclarationNameStack { auto MakeUnqualifiedName(Parse::Node parse_node, StringId name_id) -> NameContext; - // Applies a Name from the node stack to the top of the declaration name + // Applies a Name from the name stack to the top of the declaration name // stack. auto ApplyNameQualifier(Parse::Node parse_node, StringId name_id) -> void; // Adds a name to name lookup. Prints a diagnostic for name conflicts. - auto AddNameToLookup(NameContext name_context, SemIR::NodeId target_id) + auto AddNameToLookup(NameContext name_context, SemIR::InstId target_id) -> void; - // Adds a name to name lookup, or returns the existing node if this name has - // already been declared in this scope. - auto LookupOrAddName(NameContext name_context, SemIR::NodeId target_id) - -> SemIR::NodeId; + // Adds a name to name lookup, or returns the existing instruction if this + // name has already been declared in this scope. + auto LookupOrAddName(NameContext name_context, SemIR::InstId target_id) + -> SemIR::InstId; private: // Returns a name context corresponding to an empty name. auto MakeEmptyNameContext() -> NameContext; - // Applies a Name from the node stack to given name context. + // Applies a Name from the name stack to given name context. auto ApplyNameQualifierTo(NameContext& name_context, Parse::Node parse_node, StringId name_id) -> void; diff --git a/toolchain/check/handle_array.cpp b/toolchain/check/handle_array.cpp index b450ce4f7d8d..b5f4634eae4a 100644 --- a/toolchain/check/handle_array.cpp +++ b/toolchain/check/handle_array.cpp @@ -5,7 +5,7 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" #include "toolchain/parse/node_kind.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/node_kind.h" namespace Carbon::Check { @@ -30,26 +30,26 @@ auto HandleArrayExpression(Context& context, Parse::Node parse_node) -> bool { return context.TODO(parse_node, "HandleArrayExpressionWithoutBounds"); } - auto bound_node_id = context.node_stack().PopExpression(); + auto bound_inst_id = context.node_stack().PopExpression(); context.node_stack() .PopAndDiscardSoloParseNode(); - auto element_type_node_id = context.node_stack().PopExpression(); - auto bound_node = context.nodes().Get(bound_node_id); - if (auto literal = bound_node.TryAs()) { + auto element_type_inst_id = context.node_stack().PopExpression(); + auto bound_inst = context.insts().Get(bound_inst_id); + if (auto literal = bound_inst.TryAs()) { const auto& bound_value = context.integers().Get(literal->integer_id); // TODO: Produce an error if the array type is too large. if (bound_value.getActiveBits() <= 64) { - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::ArrayType{ - parse_node, SemIR::TypeId::TypeType, bound_node_id, - ExpressionAsType(context, parse_node, element_type_node_id)}); + parse_node, SemIR::TypeId::TypeType, bound_inst_id, + ExpressionAsType(context, parse_node, element_type_inst_id)}); return true; } } CARBON_DIAGNOSTIC(InvalidArrayExpression, Error, "Invalid array expression."); context.emitter().Emit(parse_node, InvalidArrayExpression); - context.node_stack().Push(parse_node, SemIR::NodeId::BuiltinError); + context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError); return true; } diff --git a/toolchain/check/handle_call_expression.cpp b/toolchain/check/handle_call_expression.cpp index 1692975ee38c..d213e0b5a199 100644 --- a/toolchain/check/handle_call_expression.cpp +++ b/toolchain/check/handle_call_expression.cpp @@ -5,7 +5,7 @@ #include "llvm/ADT/ScopeExit.h" #include "toolchain/check/context.h" #include "toolchain/check/convert.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { @@ -22,7 +22,7 @@ auto HandleCallExpression(Context& context, Parse::Node parse_node) -> bool { auto diagnose_not_callable = [&, call_expr_parse_node = call_expr_parse_node, callee_id = callee_id] { - auto callee_type_id = context.nodes().Get(callee_id).type_id(); + auto callee_type_id = context.insts().Get(callee_id).type_id(); if (callee_type_id != SemIR::TypeId::Error) { CARBON_DIAGNOSTIC(CallToNonCallable, Error, "Value of type `{0}` is not callable.", std::string); @@ -30,15 +30,15 @@ auto HandleCallExpression(Context& context, Parse::Node parse_node) -> bool { call_expr_parse_node, CallToNonCallable, context.sem_ir().StringifyType(callee_type_id, true)); } - context.node_stack().Push(parse_node, SemIR::NodeId::BuiltinError); + context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError); return true; }; // For a method call, pick out the `self` value. auto function_callee_id = callee_id; - SemIR::NodeId self_id = SemIR::NodeId::Invalid; + SemIR::InstId self_id = SemIR::InstId::Invalid; if (auto bound_method = - context.nodes().Get(callee_id).TryAs()) { + context.insts().Get(callee_id).TryAs()) { self_id = bound_method->object_id; function_callee_id = bound_method->function_id; } @@ -49,7 +49,7 @@ auto HandleCallExpression(Context& context, Parse::Node parse_node) -> bool { return diagnose_not_callable(); } auto function_decl = - context.nodes().Get(function_decl_id).TryAs(); + context.insts().Get(function_decl_id).TryAs(); if (!function_decl) { return diagnose_not_callable(); } @@ -64,11 +64,11 @@ auto HandleCallExpression(Context& context, Parse::Node parse_node) -> bool { } // If there is a return slot, build storage for the result. - SemIR::NodeId return_storage_id = SemIR::NodeId::Invalid; + SemIR::InstId return_storage_id = SemIR::InstId::Invalid; if (callable.return_slot_id.is_valid()) { // Tentatively put storage for a temporary in the function's return slot. // This will be replaced if necessary when we perform initialization. - return_storage_id = context.AddNode( + return_storage_id = context.AddInst( SemIR::TemporaryStorage{call_expr_parse_node, callable.return_type_id}); } @@ -78,10 +78,10 @@ auto HandleCallExpression(Context& context, Parse::Node parse_node) -> bool { context.params_or_args_stack().PeekCurrentBlockContents(), return_storage_id, function_decl->parse_node, callable.implicit_param_refs_id, callable.param_refs_id); - auto call_node_id = context.AddNode( + auto call_inst_id = context.AddInst( SemIR::Call{call_expr_parse_node, type_id, callee_id, converted_args_id}); - context.node_stack().Push(parse_node, call_node_id); + context.node_stack().Push(parse_node, call_inst_id); return true; } diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index 93a9a9ce5189..996a195b1dcd 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -8,9 +8,9 @@ namespace Carbon::Check { auto HandleClassIntroducer(Context& context, Parse::Node parse_node) -> bool { - // Create a node block to hold the nodes created as part of the class - // signature, such as generic parameters. - context.node_block_stack().Push(); + // Create an instruction block to hold the instructions created as part of the + // class signature, such as generic parameters. + context.inst_block_stack().Push(); // Push the bracketing node. context.node_stack().Push(parse_node); // A name should always follow. @@ -19,24 +19,24 @@ auto HandleClassIntroducer(Context& context, Parse::Node parse_node) -> bool { } static auto BuildClassDeclaration(Context& context) - -> std::tuple { + -> std::tuple { auto name_context = context.declaration_name_stack().Pop(); auto class_keyword = context.node_stack() .PopForSoloParseNode(); - auto decl_block_id = context.node_block_stack().Pop(); + auto decl_block_id = context.inst_block_stack().Pop(); // Add the class declaration. auto class_decl = SemIR::ClassDeclaration{ class_keyword, SemIR::ClassId::Invalid, decl_block_id}; - auto class_decl_id = context.AddNode(class_decl); + auto class_decl_id = context.AddInst(class_decl); // Check whether this is a redeclaration. auto existing_id = context.declaration_name_stack().LookupOrAddName( name_context, class_decl_id); if (existing_id.is_valid()) { if (auto existing_class_decl = - context.nodes().Get(existing_id).TryAs()) { + context.insts().Get(existing_id).TryAs()) { // This is a redeclaration of an existing class. class_decl.class_id = existing_class_decl->class_id; } else { @@ -62,13 +62,13 @@ static auto BuildClassDeclaration(Context& context) // Build the `Self` type. auto& class_info = context.classes().Get(class_decl.class_id); class_info.self_type_id = - context.CanonicalizeType(context.AddNode(SemIR::ClassType{ + context.CanonicalizeType(context.AddInst(SemIR::ClassType{ class_keyword, context.GetBuiltinType(SemIR::BuiltinKind::TypeType), class_decl.class_id})); } // Write the class ID into the ClassDeclaration. - context.nodes().Set(class_decl_id, class_decl); + context.insts().Set(class_decl_id, class_decl); return {class_decl.class_id, class_decl_id}; } @@ -93,7 +93,7 @@ auto HandleClassDefinitionStart(Context& context, Parse::Node parse_node) context.emitter() .Build(parse_node, ClassRedefinition, context.strings().Get(class_info.name_id)) - .Note(context.nodes().Get(class_info.definition_id).parse_node(), + .Note(context.insts().Get(class_info.definition_id).parse_node(), ClassPreviousDefinition) .Emit(); } else { @@ -114,7 +114,7 @@ auto HandleClassDefinitionStart(Context& context, Parse::Node parse_node) Lex::TokenKind::SelfTypeIdentifier.fixed_spelling()), context.sem_ir().GetTypeAllowBuiltinTypes(class_info.self_type_id)); - context.node_block_stack().Push(); + context.inst_block_stack().Push(); context.node_stack().Push(parse_node, class_id); context.args_type_info_stack().Push(); @@ -125,8 +125,9 @@ auto HandleClassDefinitionStart(Context& context, Parse::Node parse_node) // var v: if true then i32 else f64; // } // - // We may need to track a list of node blocks here, as we do for a function. - class_info.body_block_id = context.node_block_stack().PeekOrAdd(); + // We may need to track a list of instruction blocks here, as we do for a + // function. + class_info.body_block_id = context.inst_block_stack().PeekOrAdd(); return true; } @@ -134,7 +135,7 @@ auto HandleClassDefinition(Context& context, Parse::Node parse_node) -> bool { auto fields_id = context.args_type_info_stack().Pop(); auto class_id = context.node_stack().Pop(); - context.node_block_stack().Pop(); + context.inst_block_stack().Pop(); context.PopScope(); // The class type is now fully defined. diff --git a/toolchain/check/handle_function.cpp b/toolchain/check/handle_function.cpp index e23195996306..b9220c73f593 100644 --- a/toolchain/check/handle_function.cpp +++ b/toolchain/check/handle_function.cpp @@ -12,7 +12,7 @@ namespace Carbon::Check { // handles the common logic shared by function declaration syntax and function // definition syntax. static auto BuildFunctionDeclaration(Context& context, bool is_definition) - -> std::pair { + -> std::pair { // TODO: This contains the IR block for the parameters and return type. At // present, it's just loose, but it's not strictly required for parameter // refs; we should either stop constructing it completely or, if it turns out @@ -20,16 +20,16 @@ static auto BuildFunctionDeclaration(Context& context, bool is_definition) // nowhere clear to emit, so changing storage would require addressing that // problem. For comparison with function calls, the IR needs to be emitted // prior to the call. - context.node_block_stack().Pop(); + context.inst_block_stack().Pop(); auto return_type_id = SemIR::TypeId::Invalid; - auto return_slot_id = SemIR::NodeId::Invalid; + auto return_slot_id = SemIR::InstId::Invalid; if (context.parse_tree().node_kind(context.node_stack().PeekParseNode()) == Parse::NodeKind::ReturnType) { auto [return_node, return_storage_id] = context.node_stack().PopWithParseNode(); auto return_node_copy = return_node; - return_type_id = context.nodes().Get(return_storage_id).type_id(); + return_type_id = context.insts().Get(return_storage_id).type_id(); if (!context.TryToCompleteType(return_type_id, [&] { CARBON_DIAGNOSTIC(IncompleteTypeInFunctionReturnType, Error, @@ -49,12 +49,12 @@ static auto BuildFunctionDeclaration(Context& context, bool is_definition) } } - SemIR::NodeBlockId param_refs_id = + SemIR::InstBlockId param_refs_id = context.node_stack().Pop(); - SemIR::NodeBlockId implicit_param_refs_id = + SemIR::InstBlockId implicit_param_refs_id = context.node_stack() .PopIf() - .value_or(SemIR::NodeBlockId::Empty); + .value_or(SemIR::InstBlockId::Empty); auto name_context = context.declaration_name_stack().Pop(); auto fn_node = context.node_stack() @@ -64,14 +64,14 @@ static auto BuildFunctionDeclaration(Context& context, bool is_definition) auto function_decl = SemIR::FunctionDeclaration{ fn_node, context.GetBuiltinType(SemIR::BuiltinKind::FunctionType), SemIR::FunctionId::Invalid}; - auto function_decl_id = context.AddNode(function_decl); + auto function_decl_id = context.AddInst(function_decl); // Check whether this is a redeclaration. auto existing_id = context.declaration_name_stack().LookupOrAddName( name_context, function_decl_id); if (existing_id.is_valid()) { if (auto existing_function_decl = - context.nodes() + context.insts() .Get(existing_id) .TryAs()) { // This is a redeclaration of an existing function. @@ -109,12 +109,12 @@ static auto BuildFunctionDeclaration(Context& context, bool is_definition) } // Write the function ID into the FunctionDeclaration. - context.nodes().Set(function_decl_id, function_decl); + context.insts().Set(function_decl_id, function_decl); if (SemIR::IsEntryPoint(context.sem_ir(), function_decl.function_id)) { // TODO: Update this once valid signatures for the entry point are decided. - if (!context.node_blocks().Get(implicit_param_refs_id).empty() || - !context.node_blocks().Get(param_refs_id).empty() || + if (!context.inst_blocks().Get(implicit_param_refs_id).empty() || + !context.inst_blocks().Get(param_refs_id).empty() || (return_slot_id.is_valid() && return_type_id != context.GetBuiltinType(SemIR::BuiltinKind::BoolType) && @@ -149,12 +149,12 @@ auto HandleFunctionDefinition(Context& context, Parse::Node parse_node) "Missing `return` at end of function with declared return type."); context.emitter().Emit(parse_node, MissingReturnStatement); } else { - context.AddNode(SemIR::Return{parse_node}); + context.AddInst(SemIR::Return{parse_node}); } } context.PopScope(); - context.node_block_stack().Pop(); + context.inst_block_stack().Pop(); context.return_scope_stack().pop_back(); return true; } @@ -175,7 +175,7 @@ auto HandleFunctionDefinitionStart(Context& context, Parse::Node parse_node) context.emitter() .Build(parse_node, FunctionRedefinition, context.strings().Get(function.name_id)) - .Note(context.nodes().Get(function.definition_id).parse_node(), + .Note(context.insts().Get(function.definition_id).parse_node(), FunctionPreviousDefinition) .Emit(); } else { @@ -184,15 +184,15 @@ auto HandleFunctionDefinitionStart(Context& context, Parse::Node parse_node) // Create the function scope and the entry block. context.return_scope_stack().push_back(decl_id); - context.node_block_stack().Push(); + context.inst_block_stack().Push(); context.PushScope(decl_id); context.AddCurrentCodeBlockToFunction(); // Bring the implicit and explicit parameters into scope. - for (auto param_id : llvm::concat( - context.node_blocks().Get(function.implicit_param_refs_id), - context.node_blocks().Get(function.param_refs_id))) { - auto param = context.nodes().Get(param_id); + for (auto param_id : llvm::concat( + context.inst_blocks().Get(function.implicit_param_refs_id), + context.inst_blocks().Get(function.param_refs_id))) { + auto param = context.insts().Get(param_id); // The parameter types need to be complete. context.TryToCompleteType(param.type_id(), [&] { @@ -227,9 +227,9 @@ auto HandleFunctionDefinitionStart(Context& context, Parse::Node parse_node) auto HandleFunctionIntroducer(Context& context, Parse::Node parse_node) -> bool { - // Create a node block to hold the nodes created as part of the function - // signature, such as parameter and return types. - context.node_block_stack().Push(); + // Create an instruction block to hold the instructions created as part of the + // function signature, such as parameter and return types. + context.inst_block_stack().Push(); // Push the bracketing node. context.node_stack().Push(parse_node); // A name should always follow. @@ -239,11 +239,11 @@ auto HandleFunctionIntroducer(Context& context, Parse::Node parse_node) auto HandleReturnType(Context& context, Parse::Node parse_node) -> bool { // Propagate the type expression. - auto [type_parse_node, type_node_id] = + auto [type_parse_node, type_inst_id] = context.node_stack().PopExpressionWithParseNode(); - auto type_id = ExpressionAsType(context, type_parse_node, type_node_id); - // TODO: Use a dedicated node rather than VarStorage here. - context.AddNodeAndPush( + auto type_id = ExpressionAsType(context, type_parse_node, type_inst_id); + // TODO: Use a dedicated instruction rather than VarStorage here. + context.AddInstAndPush( parse_node, SemIR::VarStorage{parse_node, type_id, context.strings().Add("return")}); return true; diff --git a/toolchain/check/handle_if_expression.cpp b/toolchain/check/handle_if_expression.cpp index ad1eb88afb4b..dd4c1fafec99 100644 --- a/toolchain/check/handle_if_expression.cpp +++ b/toolchain/check/handle_if_expression.cpp @@ -20,8 +20,8 @@ auto HandleIfExpressionIf(Context& context, Parse::Node parse_node) -> bool { auto else_block_id = context.AddDominatedBlockAndBranch(if_node); // Start emitting the `then` block. - context.node_block_stack().Pop(); - context.node_block_stack().Push(then_block_id); + context.inst_block_stack().Pop(); + context.inst_block_stack().Push(then_block_id); context.AddCurrentCodeBlockToFunction(); context.node_stack().Push(if_node, else_block_id); @@ -37,7 +37,7 @@ auto HandleIfExpressionThen(Context& context, Parse::Node parse_node) -> bool { then_value_id = ConvertToValueExpression(context, then_value_id); // Start emitting the `else` block. - context.node_block_stack().Push(else_block_id); + context.inst_block_stack().Push(else_block_id); context.AddCurrentCodeBlockToFunction(); context.node_stack().Push(parse_node, then_value_id); @@ -57,7 +57,7 @@ auto HandleIfExpressionElse(Context& context, Parse::Node parse_node) -> bool { // Convert the `else` value to the `then` value's type, and finish the `else` // block. // TODO: Find a common type, and convert both operands to it instead. - auto result_type_id = context.nodes().Get(then_value_id).type_id(); + auto result_type_id = context.insts().Get(then_value_id).type_id(); else_value_id = ConvertToValueOfType(context, else_node, else_value_id, result_type_id); diff --git a/toolchain/check/handle_if_statement.cpp b/toolchain/check/handle_if_statement.cpp index 1c98a45e2ae4..ff79a7ea8890 100644 --- a/toolchain/check/handle_if_statement.cpp +++ b/toolchain/check/handle_if_statement.cpp @@ -4,7 +4,7 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { @@ -26,8 +26,8 @@ auto HandleIfCondition(Context& context, Parse::Node parse_node) -> bool { auto else_block_id = context.AddDominatedBlockAndBranch(parse_node); // Start emitting the `then` block. - context.node_block_stack().Pop(); - context.node_block_stack().Push(then_block_id); + context.inst_block_stack().Pop(); + context.inst_block_stack().Push(then_block_id); context.AddCurrentCodeBlockToFunction(); context.node_stack().Push(parse_node, else_block_id); @@ -38,7 +38,7 @@ auto HandleIfStatementElse(Context& context, Parse::Node parse_node) -> bool { auto else_block_id = context.node_stack().Pop(); // Switch to emitting the `else` block. - context.node_block_stack().Push(else_block_id); + context.inst_block_stack().Push(else_block_id); context.AddCurrentCodeBlockToFunction(); context.node_stack().Push(parse_node); @@ -53,9 +53,9 @@ auto HandleIfStatement(Context& context, Parse::Node parse_node) -> bool { // block. auto else_block_id = context.node_stack().Pop(); - context.AddNode(SemIR::Branch{parse_node, else_block_id}); - context.node_block_stack().Pop(); - context.node_block_stack().Push(else_block_id); + context.AddInst(SemIR::Branch{parse_node, else_block_id}); + context.inst_block_stack().Pop(); + context.inst_block_stack().Push(else_block_id); break; } diff --git a/toolchain/check/handle_index.cpp b/toolchain/check/handle_index.cpp index 6d97d9049727..936f78382824 100644 --- a/toolchain/check/handle_index.cpp +++ b/toolchain/check/handle_index.cpp @@ -5,7 +5,7 @@ #include "llvm/ADT/APSInt.h" #include "toolchain/check/context.h" #include "toolchain/check/convert.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/node_kind.h" namespace Carbon::Check { @@ -20,10 +20,10 @@ auto HandleIndexExpressionStart(Context& /*context*/, // the array or tuple size. Returns the index on success, or nullptr on failure. static auto ValidateIntegerLiteralBound(Context& context, Parse::Node parse_node, - SemIR::Node operand_node, - SemIR::IntegerLiteral index_node, + SemIR::Inst operand_inst, + SemIR::IntegerLiteral index_inst, int size) -> const llvm::APInt* { - const auto& index_val = context.integers().Get(index_node.integer_id); + const auto& index_val = context.integers().Get(index_inst.integer_id); if (index_val.uge(size)) { CARBON_DIAGNOSTIC(IndexOutOfBounds, Error, "Index `{0}` is past the end of `{1}`.", llvm::APSInt, @@ -31,49 +31,49 @@ static auto ValidateIntegerLiteralBound(Context& context, context.emitter().Emit( parse_node, IndexOutOfBounds, llvm::APSInt(index_val, /*isUnsigned=*/true), - context.sem_ir().StringifyType(operand_node.type_id())); + context.sem_ir().StringifyType(operand_inst.type_id())); return nullptr; } return &index_val; } auto HandleIndexExpression(Context& context, Parse::Node parse_node) -> bool { - auto index_node_id = context.node_stack().PopExpression(); - auto index_node = context.nodes().Get(index_node_id); - auto operand_node_id = context.node_stack().PopExpression(); - operand_node_id = - ConvertToValueOrReferenceExpression(context, operand_node_id); - auto operand_node = context.nodes().Get(operand_node_id); - auto operand_type_id = operand_node.type_id(); - auto operand_type_node = context.nodes().Get( + auto index_inst_id = context.node_stack().PopExpression(); + auto index_inst = context.insts().Get(index_inst_id); + auto operand_inst_id = context.node_stack().PopExpression(); + operand_inst_id = + ConvertToValueOrReferenceExpression(context, operand_inst_id); + auto operand_inst = context.insts().Get(operand_inst_id); + auto operand_type_id = operand_inst.type_id(); + auto operand_type_inst = context.insts().Get( context.sem_ir().GetTypeAllowBuiltinTypes(operand_type_id)); - switch (operand_type_node.kind()) { + switch (operand_type_inst.kind()) { case SemIR::ArrayType::Kind: { - auto array_type = operand_type_node.As(); + auto array_type = operand_type_inst.As(); // We can check whether integers are in-bounds, although it doesn't affect // the IR for an array. - if (auto index_literal = index_node.TryAs(); + if (auto index_literal = index_inst.TryAs(); index_literal && !ValidateIntegerLiteralBound( - context, parse_node, operand_node, *index_literal, + context, parse_node, operand_inst, *index_literal, context.sem_ir().GetArrayBoundValue(array_type.bound_id))) { - index_node_id = SemIR::NodeId::BuiltinError; + index_inst_id = SemIR::InstId::BuiltinError; } auto cast_index_id = ConvertToValueOfType( - context, index_node.parse_node(), index_node_id, + context, index_inst.parse_node(), index_inst_id, context.GetBuiltinType(SemIR::BuiltinKind::IntegerType)); auto array_cat = - SemIR::GetExpressionCategory(context.sem_ir(), operand_node_id); + SemIR::GetExpressionCategory(context.sem_ir(), operand_inst_id); if (array_cat == SemIR::ExpressionCategory::Value) { // If the operand is an array value, convert it to an ephemeral // reference to an array so we can perform a primitive indexing into it. - operand_node_id = context.AddNode(SemIR::ValueAsReference{ - parse_node, operand_type_id, operand_node_id}); + operand_inst_id = context.AddInst(SemIR::ValueAsReference{ + parse_node, operand_type_id, operand_inst_id}); } - auto elem_id = context.AddNode( + auto elem_id = context.AddInst( SemIR::ArrayIndex{parse_node, array_type.element_type_id, - operand_node_id, cast_index_id}); + operand_inst_id, cast_index_id}); if (array_cat != SemIR::ExpressionCategory::DurableReference) { // Indexing a durable reference gives a durable reference expression. // Indexing anything else gives a value expression. @@ -86,25 +86,25 @@ auto HandleIndexExpression(Context& context, Parse::Node parse_node) -> bool { } case SemIR::TupleType::Kind: { SemIR::TypeId element_type_id = SemIR::TypeId::Error; - if (auto index_literal = index_node.TryAs()) { + if (auto index_literal = index_inst.TryAs()) { auto type_block = context.type_blocks().Get( - operand_type_node.As().elements_id); + operand_type_inst.As().elements_id); if (const auto* index_val = ValidateIntegerLiteralBound( - context, parse_node, operand_node, *index_literal, + context, parse_node, operand_inst, *index_literal, type_block.size())) { element_type_id = type_block[index_val->getZExtValue()]; } else { - index_node_id = SemIR::NodeId::BuiltinError; + index_inst_id = SemIR::InstId::BuiltinError; } - } else if (index_node.type_id() != SemIR::TypeId::Error) { + } else if (index_inst.type_id() != SemIR::TypeId::Error) { CARBON_DIAGNOSTIC(TupleIndexIntegerLiteral, Error, "Tuples indices must be integer literals."); context.emitter().Emit(parse_node, TupleIndexIntegerLiteral); - index_node_id = SemIR::NodeId::BuiltinError; + index_inst_id = SemIR::InstId::BuiltinError; } - context.AddNodeAndPush(parse_node, + context.AddInstAndPush(parse_node, SemIR::TupleIndex{parse_node, element_type_id, - operand_node_id, index_node_id}); + operand_inst_id, index_inst_id}); return true; } default: { @@ -114,7 +114,7 @@ auto HandleIndexExpression(Context& context, Parse::Node parse_node) -> bool { context.emitter().Emit(parse_node, TypeNotIndexable, context.sem_ir().StringifyType(operand_type_id)); } - context.node_stack().Push(parse_node, SemIR::NodeId::BuiltinError); + context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError); return true; } } diff --git a/toolchain/check/handle_let.cpp b/toolchain/check/handle_let.cpp index 76644b0a5e6a..bf116abf6189 100644 --- a/toolchain/check/handle_let.cpp +++ b/toolchain/check/handle_let.cpp @@ -4,19 +4,19 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { auto HandleLetDeclaration(Context& context, Parse::Node parse_node) -> bool { auto value_id = context.node_stack().PopExpression(); - SemIR::NodeId pattern_id = + SemIR::InstId pattern_id = context.node_stack().Pop(); context.node_stack() .PopAndDiscardSoloParseNode(); // Convert the value to match the type of the pattern. - auto pattern = context.nodes().Get(pattern_id); + auto pattern = context.insts().Get(pattern_id); value_id = ConvertToValueOfType(context, parse_node, value_id, pattern.type_id()); @@ -27,8 +27,8 @@ auto HandleLetDeclaration(Context& context, Parse::Node parse_node) -> bool { CARBON_CHECK(!bind_name.value_id.is_valid()) << "Binding should not already have a value!"; bind_name.value_id = value_id; - context.nodes().Set(pattern_id, bind_name); - context.node_block_stack().AddNodeId(pattern_id); + context.insts().Set(pattern_id, bind_name); + context.inst_block_stack().AddInstId(pattern_id); // Add the name of the binding to the current scope. context.AddNameToLookup(pattern.parse_node(), bind_name.name_id, pattern_id); diff --git a/toolchain/check/handle_literal.cpp b/toolchain/check/handle_literal.cpp index 14c6fd0adc2e..68ddd8d41d41 100644 --- a/toolchain/check/handle_literal.cpp +++ b/toolchain/check/handle_literal.cpp @@ -11,7 +11,7 @@ auto HandleLiteral(Context& context, Parse::Node parse_node) -> bool { switch (auto token_kind = context.tokens().GetKind(token)) { case Lex::TokenKind::False: case Lex::TokenKind::True: { - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::BoolLiteral{ parse_node, context.GetBuiltinType(SemIR::BuiltinKind::BoolType), @@ -20,7 +20,7 @@ auto HandleLiteral(Context& context, Parse::Node parse_node) -> bool { break; } case Lex::TokenKind::IntegerLiteral: { - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::IntegerLiteral{ parse_node, @@ -29,7 +29,7 @@ auto HandleLiteral(Context& context, Parse::Node parse_node) -> bool { break; } case Lex::TokenKind::RealLiteral: { - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::RealLiteral{ parse_node, @@ -39,7 +39,7 @@ auto HandleLiteral(Context& context, Parse::Node parse_node) -> bool { } case Lex::TokenKind::StringLiteral: { auto id = context.tokens().GetStringLiteral(token); - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::StringLiteral{ parse_node, @@ -47,11 +47,11 @@ auto HandleLiteral(Context& context, Parse::Node parse_node) -> bool { break; } case Lex::TokenKind::Type: { - context.node_stack().Push(parse_node, SemIR::NodeId::BuiltinTypeType); + context.node_stack().Push(parse_node, SemIR::InstId::BuiltinTypeType); break; } case Lex::TokenKind::Bool: { - context.node_stack().Push(parse_node, SemIR::NodeId::BuiltinBoolType); + context.node_stack().Push(parse_node, SemIR::InstId::BuiltinBoolType); break; } case Lex::TokenKind::IntegerTypeLiteral: { @@ -59,7 +59,7 @@ auto HandleLiteral(Context& context, Parse::Node parse_node) -> bool { if (text != "i32") { return context.TODO(parse_node, "Currently only i32 is allowed"); } - context.node_stack().Push(parse_node, SemIR::NodeId::BuiltinIntegerType); + context.node_stack().Push(parse_node, SemIR::InstId::BuiltinIntegerType); break; } case Lex::TokenKind::FloatingPointTypeLiteral: { @@ -68,11 +68,11 @@ auto HandleLiteral(Context& context, Parse::Node parse_node) -> bool { return context.TODO(parse_node, "Currently only f64 is allowed"); } context.node_stack().Push(parse_node, - SemIR::NodeId::BuiltinFloatingPointType); + SemIR::InstId::BuiltinFloatingPointType); break; } case Lex::TokenKind::StringTypeLiteral: { - context.node_stack().Push(parse_node, SemIR::NodeId::BuiltinStringType); + context.node_stack().Push(parse_node, SemIR::InstId::BuiltinStringType); break; } default: { diff --git a/toolchain/check/handle_loop_statement.cpp b/toolchain/check/handle_loop_statement.cpp index 923f4427d32e..861a0f3e2e5f 100644 --- a/toolchain/check/handle_loop_statement.cpp +++ b/toolchain/check/handle_loop_statement.cpp @@ -20,11 +20,11 @@ auto HandleBreakStatementStart(Context& context, Parse::Node parse_node) "`break` can only be used in a loop."); context.emitter().Emit(parse_node, BreakOutsideLoop); } else { - context.AddNode(SemIR::Branch{parse_node, stack.back().break_target}); + context.AddInst(SemIR::Branch{parse_node, stack.back().break_target}); } - context.node_block_stack().Pop(); - context.node_block_stack().PushUnreachable(); + context.inst_block_stack().Pop(); + context.inst_block_stack().PushUnreachable(); return true; } @@ -41,11 +41,11 @@ auto HandleContinueStatementStart(Context& context, Parse::Node parse_node) "`continue` can only be used in a loop."); context.emitter().Emit(parse_node, ContinueOutsideLoop); } else { - context.AddNode(SemIR::Branch{parse_node, stack.back().continue_target}); + context.AddInst(SemIR::Branch{parse_node, stack.back().continue_target}); } - context.node_block_stack().Pop(); - context.node_block_stack().PushUnreachable(); + context.inst_block_stack().Pop(); + context.inst_block_stack().PushUnreachable(); return true; } @@ -71,10 +71,10 @@ auto HandleWhileConditionStart(Context& context, Parse::Node parse_node) // if the current block is empty; this ensures that the loop always has a // preheader block. auto loop_header_id = context.AddDominatedBlockAndBranch(parse_node); - context.node_block_stack().Pop(); + context.inst_block_stack().Pop(); // Start emitting the loop header block. - context.node_block_stack().Push(loop_header_id); + context.inst_block_stack().Push(loop_header_id); context.AddCurrentCodeBlockToFunction(); context.node_stack().Push(parse_node, loop_header_id); @@ -91,10 +91,10 @@ auto HandleWhileCondition(Context& context, Parse::Node parse_node) -> bool { auto loop_body_id = context.AddDominatedBlockAndBranchIf(parse_node, cond_value_id); auto loop_exit_id = context.AddDominatedBlockAndBranch(parse_node); - context.node_block_stack().Pop(); + context.inst_block_stack().Pop(); // Start emitting the loop body. - context.node_block_stack().Push(loop_body_id); + context.inst_block_stack().Push(loop_body_id); context.AddCurrentCodeBlockToFunction(); context.break_continue_stack().push_back( {.break_target = loop_exit_id, .continue_target = loop_header_id}); @@ -111,11 +111,11 @@ auto HandleWhileStatement(Context& context, Parse::Node parse_node) -> bool { context.break_continue_stack().pop_back(); // Add the loop backedge. - context.AddNode(SemIR::Branch{parse_node, loop_header_id}); - context.node_block_stack().Pop(); + context.AddInst(SemIR::Branch{parse_node, loop_header_id}); + context.inst_block_stack().Pop(); // Start emitting the loop exit block. - context.node_block_stack().Push(loop_exit_id); + context.inst_block_stack().Push(loop_exit_id); context.AddCurrentCodeBlockToFunction(); return true; } diff --git a/toolchain/check/handle_name.cpp b/toolchain/check/handle_name.cpp index b6c565cb1bcd..e1b87fde3bfc 100644 --- a/toolchain/check/handle_name.cpp +++ b/toolchain/check/handle_name.cpp @@ -6,15 +6,15 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" #include "toolchain/lex/token_kind.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { // Returns the name scope corresponding to base_id, or nullopt if not a scope. // On invalid scopes, prints a diagnostic and still returns the scope. -static auto GetAsNameScope(Context& context, SemIR::NodeId base_id) +static auto GetAsNameScope(Context& context, SemIR::InstId base_id) -> std::optional { - auto base = context.nodes().Get(context.FollowNameReferences(base_id)); + auto base = context.insts().Get(context.FollowNameReferences(base_id)); if (auto base_as_namespace = base.TryAs()) { return base_as_namespace->name_scope_id; } @@ -25,7 +25,7 @@ static auto GetAsNameScope(Context& context, SemIR::NodeId base_id) "Member access into incomplete class `{0}`.", std::string); auto builder = context.emitter().Build( - context.nodes().Get(base_id).parse_node(), + context.insts().Get(base_id).parse_node(), QualifiedExpressionInIncompleteClassScope, context.sem_ir().StringifyTypeExpression(base_id, true)); context.NoteIncompleteClass(base_as_class->class_id, builder); @@ -36,20 +36,20 @@ static auto GetAsNameScope(Context& context, SemIR::NodeId base_id) return std::nullopt; } -// Given a node produced by a name lookup, get the value to use for that result -// in an expression. +// Given an instruction produced by a name lookup, get the value to use for that +// result in an expression. static auto GetExpressionValueForLookupResult(Context& context, - SemIR::NodeId lookup_result_id) - -> SemIR::NodeId { + SemIR::InstId lookup_result_id) + -> SemIR::InstId { // If lookup finds a class declaration, the value is its `Self` type. - auto lookup_result = context.nodes().Get(lookup_result_id); + auto lookup_result = context.insts().Get(lookup_result_id); if (auto class_decl = lookup_result.TryAs()) { return context.sem_ir().GetTypeAllowBuiltinTypes( context.classes().Get(class_decl->class_id).self_type_id); } // Anything else should be a typed value already. - CARBON_CHECK(lookup_result.kind().value_kind() == SemIR::NodeValueKind::Typed) + CARBON_CHECK(lookup_result.kind().value_kind() == SemIR::InstValueKind::Typed) << "Unexpected kind for lookup result"; return lookup_result_id; } @@ -62,39 +62,39 @@ auto HandleMemberAccessExpression(Context& context, Parse::Node parse_node) // If the base is a name scope, such as a class or namespace, perform lookup // into that scope. if (auto name_scope_id = GetAsNameScope(context, base_id)) { - auto node_id = name_scope_id->is_valid() + auto inst_id = name_scope_id->is_valid() ? context.LookupName(parse_node, name_id, *name_scope_id, /*print_diagnostics=*/true) - : SemIR::NodeId::BuiltinError; - node_id = GetExpressionValueForLookupResult(context, node_id); - auto node = context.nodes().Get(node_id); - // TODO: Track that this node was named within `base_id`. - context.AddNodeAndPush( + : SemIR::InstId::BuiltinError; + inst_id = GetExpressionValueForLookupResult(context, inst_id); + auto inst = context.insts().Get(inst_id); + // TODO: Track that this instruction was named within `base_id`. + context.AddInstAndPush( parse_node, - SemIR::NameReference{parse_node, node.type_id(), name_id, node_id}); + SemIR::NameReference{parse_node, inst.type_id(), name_id, inst_id}); return true; } // If the base isn't a scope, it must have a complete type. - auto base_type_id = context.nodes().Get(base_id).type_id(); + auto base_type_id = context.insts().Get(base_id).type_id(); if (!context.TryToCompleteType(base_type_id, [&] { CARBON_DIAGNOSTIC(IncompleteTypeInMemberAccess, Error, "Member access into object of incomplete type `{0}`.", std::string); return context.emitter().Build( - context.nodes().Get(base_id).parse_node(), + context.insts().Get(base_id).parse_node(), IncompleteTypeInMemberAccess, context.sem_ir().StringifyType(base_type_id, true)); })) { - context.node_stack().Push(parse_node, SemIR::NodeId::BuiltinError); + context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError); return true; } // Materialize a temporary for the base expression if necessary. base_id = ConvertToValueOrReferenceExpression(context, base_id); - base_type_id = context.nodes().Get(base_id).type_id(); + base_type_id = context.insts().Get(base_id).type_id(); - auto base_type = context.nodes().Get( + auto base_type = context.insts().Get( context.sem_ir().GetTypeAllowBuiltinTypes(base_type_id)); switch (base_type.kind()) { @@ -108,24 +108,24 @@ auto HandleMemberAccessExpression(Context& context, Parse::Node parse_node) member_id = GetExpressionValueForLookupResult(context, member_id); // Perform instance binding if we found an instance member. - auto member_type_id = context.nodes().Get(member_id).type_id(); - auto member_type_node = context.nodes().Get( + auto member_type_id = context.insts().Get(member_id).type_id(); + auto member_type_inst = context.insts().Get( context.sem_ir().GetTypeAllowBuiltinTypes(member_type_id)); if (auto unbound_field_type = - member_type_node.TryAs()) { + member_type_inst.TryAs()) { // TODO: Check that the unbound field type describes a member of this // class. Perform a conversion of the base if necessary. // Find the named field and build a field access expression. auto field_id = context.GetConstantValue(member_id); CARBON_CHECK(field_id.is_valid()) - << "Non-constant value " << context.nodes().Get(member_id) + << "Non-constant value " << context.insts().Get(member_id) << " of unbound field type"; - auto field = context.nodes().Get(field_id).TryAs(); + auto field = context.insts().Get(field_id).TryAs(); CARBON_CHECK(field) - << "Unexpected value " << context.nodes().Get(field_id) + << "Unexpected value " << context.insts().Get(field_id) << " for field name expression"; - auto access_id = context.AddNode(SemIR::ClassFieldAccess{ + auto access_id = context.AddInst(SemIR::ClassFieldAccess{ parse_node, unbound_field_type->field_type_id, base_id, field->index}); if (SemIR::GetExpressionCategory(context.sem_ir(), base_id) == @@ -147,19 +147,19 @@ auto HandleMemberAccessExpression(Context& context, Parse::Node parse_node) // Find the named function and check whether it's an instance method. auto function_name_id = context.GetConstantValue(member_id); CARBON_CHECK(function_name_id.is_valid()) - << "Non-constant value " << context.nodes().Get(member_id) + << "Non-constant value " << context.insts().Get(member_id) << " of function type"; - auto function_decl = context.nodes() + auto function_decl = context.insts() .Get(function_name_id) .TryAs(); CARBON_CHECK(function_decl) - << "Unexpected value " << context.nodes().Get(function_name_id) + << "Unexpected value " << context.insts().Get(function_name_id) << " of function type"; auto& function = context.functions().Get(function_decl->function_id); for (auto param_id : - context.node_blocks().Get(function.implicit_param_refs_id)) { - if (context.nodes().Get(param_id).Is()) { - context.AddNodeAndPush( + context.inst_blocks().Get(function.implicit_param_refs_id)) { + if (context.insts().Get(param_id).Is()) { + context.AddInstAndPush( parse_node, SemIR::BoundMethod{ parse_node, @@ -172,19 +172,19 @@ auto HandleMemberAccessExpression(Context& context, Parse::Node parse_node) // For a non-instance member, the result is that member. // TODO: Track that this was named within `base_id`. - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::NameReference{parse_node, member_type_id, name_id, member_id}); return true; } case SemIR::StructType::Kind: { - auto refs = context.node_blocks().Get( + auto refs = context.inst_blocks().Get( base_type.As().fields_id); // TODO: Do we need to optimize this with a lookup table for O(1)? for (auto [i, ref_id] : llvm::enumerate(refs)) { - auto field = context.nodes().GetAs(ref_id); + auto field = context.insts().GetAs(ref_id); if (name_id == field.name_id) { - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::StructAccess{parse_node, field.field_type_id, base_id, SemIR::MemberIndex(i)}); return true; @@ -214,7 +214,7 @@ auto HandleMemberAccessExpression(Context& context, Parse::Node parse_node) } // Should only be reached on error. - context.node_stack().Push(parse_node, SemIR::NodeId::BuiltinError); + context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError); return true; } @@ -237,9 +237,10 @@ auto HandleNameExpression(Context& context, Parse::Node parse_node) -> bool { auto value_id = context.LookupName(parse_node, name_id, SemIR::NameScopeId::Invalid, /*print_diagnostics=*/true); + value_id = GetExpressionValueForLookupResult(context, value_id); - auto value = context.nodes().Get(value_id); - context.AddNodeAndPush( + auto value = context.insts().Get(value_id); + context.AddInstAndPush( parse_node, SemIR::NameReference{parse_node, value.type_id(), name_id, value_id}); return true; @@ -287,8 +288,8 @@ auto HandleSelfTypeNameExpression(Context& context, Parse::Node parse_node) auto value_id = context.LookupName(parse_node, name_id, SemIR::NameScopeId::Invalid, /*print_diagnostics=*/true); - auto value = context.nodes().Get(value_id); - context.AddNodeAndPush( + auto value = context.insts().Get(value_id); + context.AddInstAndPush( parse_node, SemIR::NameReference{parse_node, value.type_id(), name_id, value_id}); return true; @@ -308,8 +309,8 @@ auto HandleSelfValueNameExpression(Context& context, Parse::Node parse_node) auto value_id = context.LookupName(parse_node, name_id, SemIR::NameScopeId::Invalid, /*print_diagnostics=*/true); - auto value = context.nodes().Get(value_id); - context.AddNodeAndPush( + auto value = context.insts().Get(value_id); + context.AddInstAndPush( parse_node, SemIR::NameReference{parse_node, value.type_id(), name_id, value_id}); return true; diff --git a/toolchain/check/handle_namespace.cpp b/toolchain/check/handle_namespace.cpp index 4ccae6008c0a..7311001bf7c5 100644 --- a/toolchain/check/handle_namespace.cpp +++ b/toolchain/check/handle_namespace.cpp @@ -3,7 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "toolchain/check/context.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { @@ -15,7 +15,7 @@ auto HandleNamespaceStart(Context& context, Parse::Node /*parse_node*/) auto HandleNamespace(Context& context, Parse::Node parse_node) -> bool { auto name_context = context.declaration_name_stack().Pop(); - auto namespace_id = context.AddNode(SemIR::Namespace{ + auto namespace_id = context.AddInst(SemIR::Namespace{ parse_node, context.GetBuiltinType(SemIR::BuiltinKind::NamespaceType), context.name_scopes().Add()}); context.declaration_name_stack().AddNameToLookup(name_context, namespace_id); diff --git a/toolchain/check/handle_operator.cpp b/toolchain/check/handle_operator.cpp index 8658b645694f..82cf11ca4316 100644 --- a/toolchain/check/handle_operator.cpp +++ b/toolchain/check/handle_operator.cpp @@ -18,12 +18,12 @@ auto HandleInfixOperator(Context& context, Parse::Node parse_node) -> bool { // TODO: This should search for a compatible interface. For now, it's a // very trivial check of validity on the operation. lhs_id = ConvertToValueOfType(context, parse_node, lhs_id, - context.nodes().Get(rhs_id).type_id()); + context.insts().Get(rhs_id).type_id()); rhs_id = ConvertToValueExpression(context, rhs_id); - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::BinaryOperatorAdd{ - parse_node, context.nodes().Get(lhs_id).type_id(), + parse_node, context.insts().Get(lhs_id).type_id(), lhs_id, rhs_id}); return true; @@ -36,16 +36,16 @@ auto HandleInfixOperator(Context& context, Parse::Node parse_node) -> bool { // When the second operand is evaluated, the result of `and` and `or` is // its value. - auto resume_block_id = context.node_block_stack().PeekOrAdd(/*depth=*/1); - context.AddNode( + auto resume_block_id = context.inst_block_stack().PeekOrAdd(/*depth=*/1); + context.AddInst( SemIR::BranchWithArg{parse_node, resume_block_id, rhs_id}); - context.node_block_stack().Pop(); + context.inst_block_stack().Pop(); context.AddCurrentCodeBlockToFunction(); // Collect the result from either the first or second operand. - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, - SemIR::BlockArg{parse_node, context.nodes().Get(rhs_id).type_id(), + SemIR::BlockArg{parse_node, context.insts().Get(rhs_id).type_id(), resume_block_id}); return true; } @@ -68,7 +68,7 @@ auto HandleInfixOperator(Context& context, Parse::Node parse_node) -> bool { // TODO: Destroy the old value before reinitializing. This will require // building the destruction code before we build the RHS subexpression. rhs_id = Initialize(context, parse_node, lhs_id, rhs_id); - context.AddNode(SemIR::Assign{parse_node, lhs_id, rhs_id}); + context.AddInst(SemIR::Assign{parse_node, lhs_id, rhs_id}); // We model assignment as an expression, so we need to push a value for // it, even though it doesn't produce a value. // TODO: Consider changing our parse tree to model assignment as a @@ -89,7 +89,7 @@ auto HandlePostfixOperator(Context& context, Parse::Node parse_node) -> bool { switch (auto token_kind = context.tokens().GetKind(token)) { case Lex::TokenKind::Star: { auto inner_type_id = ExpressionAsType(context, parse_node, value_id); - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::PointerType{parse_node, SemIR::TypeId::TypeType, inner_type_id}); return true; @@ -124,12 +124,12 @@ auto HandlePrefixOperator(Context& context, Parse::Node parse_node) -> bool { context.emitter().Emit(parse_node, AddressOfNonReference); break; } - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::AddressOf{ parse_node, context.GetPointerType(parse_node, - context.nodes().Get(value_id).type_id()), + context.insts().Get(value_id).type_id()), value_id}); return true; } @@ -138,14 +138,14 @@ auto HandlePrefixOperator(Context& context, Parse::Node parse_node) -> bool { // `const (const T)` is probably not what the developer intended. // TODO: Detect `const (const T)*` and suggest moving the `*` inside the // parentheses. - if (context.nodes().Get(value_id).kind() == SemIR::ConstType::Kind) { + if (context.insts().Get(value_id).kind() == SemIR::ConstType::Kind) { CARBON_DIAGNOSTIC(RepeatedConst, Warning, "`const` applied repeatedly to the same type has no " "additional effect."); context.emitter().Emit(parse_node, RepeatedConst); } auto inner_type_id = ExpressionAsType(context, parse_node, value_id); - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::ConstType{parse_node, SemIR::TypeId::TypeType, inner_type_id}); return true; @@ -153,20 +153,20 @@ auto HandlePrefixOperator(Context& context, Parse::Node parse_node) -> bool { case Lex::TokenKind::Not: value_id = ConvertToBoolValue(context, parse_node, value_id); - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::UnaryOperatorNot{ - parse_node, context.nodes().Get(value_id).type_id(), value_id}); + parse_node, context.insts().Get(value_id).type_id(), value_id}); return true; case Lex::TokenKind::Star: { value_id = ConvertToValueExpression(context, value_id); auto type_id = - context.GetUnqualifiedType(context.nodes().Get(value_id).type_id()); - auto type_node = context.nodes().Get( + context.GetUnqualifiedType(context.insts().Get(value_id).type_id()); + auto type_inst = context.insts().Get( context.sem_ir().GetTypeAllowBuiltinTypes(type_id)); auto result_type_id = SemIR::TypeId::Error; - if (auto pointer_type = type_node.TryAs()) { + if (auto pointer_type = type_inst.TryAs()) { result_type_id = pointer_type->pointee_id; } else if (type_id != SemIR::TypeId::Error) { CARBON_DIAGNOSTIC( @@ -185,7 +185,7 @@ auto HandlePrefixOperator(Context& context, Parse::Node parse_node) -> bool { } builder.Emit(); } - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::Dereference{parse_node, result_type_id, value_id}); return true; } @@ -200,23 +200,23 @@ auto HandleShortCircuitOperand(Context& context, Parse::Node parse_node) // Convert the condition to `bool`. auto cond_value_id = context.node_stack().PopExpression(); cond_value_id = ConvertToBoolValue(context, parse_node, cond_value_id); - auto bool_type_id = context.nodes().Get(cond_value_id).type_id(); + auto bool_type_id = context.insts().Get(cond_value_id).type_id(); // Compute the branch value: the condition for `and`, inverted for `or`. auto token = context.parse_tree().node_token(parse_node); - SemIR::NodeId branch_value_id = SemIR::NodeId::Invalid; - auto short_circuit_result_id = SemIR::NodeId::Invalid; + SemIR::InstId branch_value_id = SemIR::InstId::Invalid; + auto short_circuit_result_id = SemIR::InstId::Invalid; switch (auto token_kind = context.tokens().GetKind(token)) { case Lex::TokenKind::And: branch_value_id = cond_value_id; - short_circuit_result_id = context.AddNode(SemIR::BoolLiteral{ + short_circuit_result_id = context.AddInst(SemIR::BoolLiteral{ parse_node, bool_type_id, SemIR::BoolValue::False}); break; case Lex::TokenKind::Or: - branch_value_id = context.AddNode( + branch_value_id = context.AddInst( SemIR::UnaryOperatorNot{parse_node, bool_type_id, cond_value_id}); - short_circuit_result_id = context.AddNode( + short_circuit_result_id = context.AddInst( SemIR::BoolLiteral{parse_node, bool_type_id, SemIR::BoolValue::True}); break; @@ -232,9 +232,9 @@ auto HandleShortCircuitOperand(Context& context, Parse::Node parse_node) // Push the resumption and the right-hand side blocks, and start emitting the // right-hand operand. - context.node_block_stack().Pop(); - context.node_block_stack().Push(end_block_id); - context.node_block_stack().Push(rhs_block_id); + context.inst_block_stack().Pop(); + context.inst_block_stack().Push(end_block_id); + context.inst_block_stack().Push(rhs_block_id); context.AddCurrentCodeBlockToFunction(); // Put the condition back on the stack for HandleInfixOperator. diff --git a/toolchain/check/handle_paren.cpp b/toolchain/check/handle_paren.cpp index 1e117b3927ff..f1df906961a3 100644 --- a/toolchain/check/handle_paren.cpp +++ b/toolchain/check/handle_paren.cpp @@ -40,16 +40,16 @@ auto HandleTupleLiteral(Context& context, Parse::Node parse_node) -> bool { context.node_stack() .PopAndDiscardSoloParseNode< Parse::NodeKind::ParenExpressionOrTupleLiteralStart>(); - const auto& node_block = context.node_blocks().Get(refs_id); + const auto& inst_block = context.inst_blocks().Get(refs_id); llvm::SmallVector type_ids; - type_ids.reserve(node_block.size()); - for (auto node : node_block) { - type_ids.push_back(context.nodes().Get(node).type_id()); + type_ids.reserve(inst_block.size()); + for (auto inst : inst_block) { + type_ids.push_back(context.insts().Get(inst).type_id()); } auto type_id = context.CanonicalizeTupleType(parse_node, std::move(type_ids)); auto value_id = - context.AddNode(SemIR::TupleLiteral{parse_node, type_id, refs_id}); + context.AddInst(SemIR::TupleLiteral{parse_node, type_id, refs_id}); context.node_stack().Push(parse_node, value_id); return true; } diff --git a/toolchain/check/handle_pattern_binding.cpp b/toolchain/check/handle_pattern_binding.cpp index 094fd4d842f0..ca52aa3700f3 100644 --- a/toolchain/check/handle_pattern_binding.cpp +++ b/toolchain/check/handle_pattern_binding.cpp @@ -4,7 +4,7 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { @@ -12,9 +12,9 @@ auto HandleAddress(Context& context, Parse::Node parse_node) -> bool { auto self_param_id = context.node_stack().Peek(); if (auto self_param = - context.nodes().Get(self_param_id).TryAs()) { + context.insts().Get(self_param_id).TryAs()) { self_param->is_addr_self = SemIR::BoolValue::True; - context.nodes().Set(self_param_id, *self_param); + context.insts().Set(self_param_id, *self_param); } else { CARBON_DIAGNOSTIC(AddrOnNonSelfParameter, Error, "`addr` can only be applied to a `self` parameter"); @@ -45,7 +45,7 @@ auto HandlePatternBinding(Context& context, Parse::Node parse_node) -> bool { "`self` can only be declared in an implicit parameter list"); context.emitter().Emit(parse_node, SelfOutsideImplicitParameterList); } - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::SelfParameter{*self_node, cast_type_id, /*is_addr_self=*/SemIR::BoolValue::False}); @@ -58,8 +58,8 @@ auto HandlePatternBinding(Context& context, Parse::Node parse_node) -> bool { auto [name_node, name_id] = context.node_stack().PopWithParseNode(); - // Allocate a node of the appropriate kind, linked to the name for error - // locations. + // Allocate an instruction of the appropriate kind, linked to the name for + // error locations. switch (auto context_parse_node_kind = context.parse_tree().node_kind( context.node_stack().PeekParseNode())) { case Parse::NodeKind::VariableIntroducer: { @@ -77,29 +77,29 @@ auto HandlePatternBinding(Context& context, Parse::Node parse_node) -> bool { })) { cast_type_id = SemIR::TypeId::Error; } - SemIR::NodeId value_id = SemIR::NodeId::Invalid; + SemIR::InstId value_id = SemIR::InstId::Invalid; SemIR::TypeId value_type_id = cast_type_id; if (enclosing_class_decl) { auto& class_info = context.classes().Get(enclosing_class_decl->class_id); - auto field_type_node_id = context.AddNode(SemIR::UnboundFieldType{ + auto field_type_inst_id = context.AddInst(SemIR::UnboundFieldType{ parse_node, context.GetBuiltinType(SemIR::BuiltinKind::TypeType), class_info.self_type_id, cast_type_id}); - value_type_id = context.CanonicalizeType(field_type_node_id); - value_id = context.AddNode( + value_type_id = context.CanonicalizeType(field_type_inst_id); + value_id = context.AddInst( SemIR::Field{parse_node, value_type_id, name_id, SemIR::MemberIndex(context.args_type_info_stack() .PeekCurrentBlockContents() .size())}); // Add a corresponding field to the object representation of the class. - context.args_type_info_stack().AddNode( + context.args_type_info_stack().AddInst( SemIR::StructTypeField{parse_node, name_id, cast_type_id}); } else { - value_id = context.AddNode( + value_id = context.AddInst( SemIR::VarStorage{name_node, value_type_id, name_id}); } - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::BindName{name_node, value_type_id, name_id, value_id}); break; @@ -109,9 +109,9 @@ auto HandlePatternBinding(Context& context, Parse::Node parse_node) -> bool { case Parse::NodeKind::ParameterListStart: // Parameters can have incomplete types in a function declaration, but not // in a function definition. We don't know which kind we have here. - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::Parameter{name_node, cast_type_id, name_id}); - // TODO: Create a `BindName` node. + // TODO: Create a `BindName` instruction. break; case Parse::NodeKind::LetIntroducer: @@ -125,14 +125,14 @@ auto HandlePatternBinding(Context& context, Parse::Node parse_node) -> bool { })) { cast_type_id = SemIR::TypeId::Error; } - // Create the node, but don't add it to a block until after we've formed - // its initializer. + // Create the instruction, but don't add it to a block until after we've + // formed its initializer. // TODO: For general pattern parsing, we'll need to create a block to hold // the `let` pattern before we see the initializer. context.node_stack().Push( parse_node, - context.nodes().AddInNoBlock(SemIR::BindName{ - name_node, cast_type_id, name_id, SemIR::NodeId::Invalid})); + context.insts().AddInNoBlock(SemIR::BindName{ + name_node, cast_type_id, name_id, SemIR::InstId::Invalid})); break; default: diff --git a/toolchain/check/handle_statement.cpp b/toolchain/check/handle_statement.cpp index 0a5f497bd157..bae5d1e09325 100644 --- a/toolchain/check/handle_statement.cpp +++ b/toolchain/check/handle_statement.cpp @@ -4,17 +4,17 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { // TODO: Find a better home for this. We'll likely need it for more than just // expression statements. -static auto HandleDiscardedExpression(Context& context, SemIR::NodeId expr_id) +static auto HandleDiscardedExpression(Context& context, SemIR::InstId expr_id) -> void { // If we discard an initializing expression, convert it to a value or // reference so that it has something to initialize. - auto expr = context.nodes().Get(expr_id); + auto expr = context.insts().Get(expr_id); Convert(context, expr.parse_node(), expr_id, {.kind = ConversionTarget::Discarded, .type_id = expr.type_id()}); @@ -29,9 +29,9 @@ auto HandleExpressionStatement(Context& context, Parse::Node /*parse_node*/) auto HandleReturnStatement(Context& context, Parse::Node parse_node) -> bool { CARBON_CHECK(!context.return_scope_stack().empty()); - auto fn_node = context.nodes().GetAs( + auto fn_inst = context.insts().GetAs( context.return_scope_stack().back()); - const auto& callable = context.functions().Get(fn_node.function_id); + const auto& callable = context.functions().Get(fn_inst.function_id); if (context.parse_tree().node_kind(context.node_stack().PeekParseNode()) == Parse::NodeKind::ReturnStatementStart) { @@ -48,7 +48,7 @@ auto HandleReturnStatement(Context& context, Parse::Node parse_node) -> bool { .Emit(); } - context.AddNode(SemIR::Return{parse_node}); + context.AddInst(SemIR::Return{parse_node}); } else { auto arg = context.node_stack().PopExpression(); context.node_stack() @@ -62,7 +62,7 @@ auto HandleReturnStatement(Context& context, Parse::Node parse_node) -> bool { "There was no return type provided."); context.emitter() .Build(parse_node, ReturnStatementDisallowExpression) - .Note(fn_node.parse_node, ReturnStatementImplicitNote) + .Note(fn_inst.parse_node, ReturnStatementImplicitNote) .Emit(); } else if (callable.return_slot_id.is_valid()) { arg = Initialize(context, parse_node, callable.return_slot_id, arg); @@ -71,14 +71,14 @@ auto HandleReturnStatement(Context& context, Parse::Node parse_node) -> bool { callable.return_type_id); } - context.AddNode(SemIR::ReturnExpression{parse_node, arg}); + context.AddInst(SemIR::ReturnExpression{parse_node, arg}); } - // Switch to a new, unreachable, empty node block. This typically won't + // Switch to a new, unreachable, empty instruction block. This typically won't // contain any semantics IR, but it can do if there are statements following // the `return` statement. - context.node_block_stack().Pop(); - context.node_block_stack().PushUnreachable(); + context.inst_block_stack().Pop(); + context.inst_block_stack().PushUnreachable(); return true; } diff --git a/toolchain/check/handle_struct.cpp b/toolchain/check/handle_struct.cpp index 5f8a764d6aea..24b6f12a62a1 100644 --- a/toolchain/check/handle_struct.cpp +++ b/toolchain/check/handle_struct.cpp @@ -28,7 +28,7 @@ auto HandleStructFieldType(Context& context, Parse::Node parse_node) -> bool { auto [name_node, name_id] = context.node_stack().PopWithParseNode(); - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::StructTypeField{name_node, name_id, cast_type_id}); return true; } @@ -39,16 +39,16 @@ auto HandleStructFieldUnknown(Context& context, Parse::Node parse_node) } auto HandleStructFieldValue(Context& context, Parse::Node parse_node) -> bool { - auto [value_parse_node, value_node_id] = + auto [value_parse_node, value_inst_id] = context.node_stack().PopExpressionWithParseNode(); StringId name_id = context.node_stack().Pop(); // Store the name for the type. - context.args_type_info_stack().AddNode(SemIR::StructTypeField{ - parse_node, name_id, context.nodes().Get(value_node_id).type_id()}); + context.args_type_info_stack().AddInst(SemIR::StructTypeField{ + parse_node, name_id, context.insts().Get(value_inst_id).type_id()}); // Push the value back on the stack as an argument. - context.node_stack().Push(parse_node, value_node_id); + context.node_stack().Push(parse_node, value_inst_id); return true; } @@ -65,7 +65,7 @@ auto HandleStructLiteral(Context& context, Parse::Node parse_node) -> bool { auto type_id = context.CanonicalizeStructType(parse_node, type_block_id); auto value_id = - context.AddNode(SemIR::StructLiteral{parse_node, type_id, refs_id}); + context.AddInst(SemIR::StructLiteral{parse_node, type_id, refs_id}); context.node_stack().Push(parse_node, value_id); return true; } @@ -94,10 +94,10 @@ auto HandleStructTypeLiteral(Context& context, Parse::Node parse_node) -> bool { // This is only used for value literals. context.args_type_info_stack().Pop(); - CARBON_CHECK(refs_id != SemIR::NodeBlockId::Empty) + CARBON_CHECK(refs_id != SemIR::InstBlockId::Empty) << "{} is handled by StructLiteral."; - context.AddNodeAndPush( + context.AddInstAndPush( parse_node, SemIR::StructType{parse_node, SemIR::TypeId::TypeType, refs_id}); return true; diff --git a/toolchain/check/handle_variable.cpp b/toolchain/check/handle_variable.cpp index 90372bc5c000..c032e214a818 100644 --- a/toolchain/check/handle_variable.cpp +++ b/toolchain/check/handle_variable.cpp @@ -4,14 +4,14 @@ #include "toolchain/check/context.h" #include "toolchain/check/convert.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { auto HandleVariableDeclaration(Context& context, Parse::Node parse_node) -> bool { // Handle the optional initializer. - auto init_id = SemIR::NodeId::Invalid; + auto init_id = SemIR::InstId::Invalid; bool has_init = context.parse_tree().node_kind(context.node_stack().PeekParseNode()) != Parse::NodeKind::PatternBinding; @@ -23,7 +23,7 @@ auto HandleVariableDeclaration(Context& context, Parse::Node parse_node) // Extract the name binding. auto value_id = context.node_stack().Pop(); - if (auto bind_name = context.nodes().Get(value_id).TryAs()) { + if (auto bind_name = context.insts().Get(value_id).TryAs()) { // Form a corresponding name in the current context, and bind the name to // the variable. context.declaration_name_stack().AddNameToLookup( @@ -35,11 +35,11 @@ auto HandleVariableDeclaration(Context& context, Parse::Node parse_node) // If there was an initializer, assign it to the storage. if (has_init) { - if (context.nodes().Get(value_id).Is()) { + if (context.insts().Get(value_id).Is()) { init_id = Initialize(context, parse_node, value_id, init_id); - // TODO: Consider using different node kinds for assignment versus + // TODO: Consider using different instruction kinds for assignment versus // initialization. - context.AddNode(SemIR::Assign{parse_node, value_id, init_id}); + context.AddInst(SemIR::Assign{parse_node, value_id, init_id}); } else { // TODO: In a class scope, we should instead save the initializer // somewhere so that we can use it as a default. diff --git a/toolchain/check/node_block_stack.cpp b/toolchain/check/inst_block_stack.cpp similarity index 72% rename from toolchain/check/node_block_stack.cpp rename to toolchain/check/inst_block_stack.cpp index a52ad3e62a08..f53c4470bebc 100644 --- a/toolchain/check/node_block_stack.cpp +++ b/toolchain/check/inst_block_stack.cpp @@ -2,16 +2,15 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include "toolchain/check/node_block_stack.h" - #include "common/vlog.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/check/node_block_stack.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { -auto NodeBlockStack::Push(SemIR::NodeBlockId id) -> void { +auto InstBlockStack::Push(SemIR::InstBlockId id) -> void { CARBON_VLOG() << name_ << " Push " << size_ << "\n"; CARBON_CHECK(size_ < (1 << 20)) << "Excessive stack size: likely infinite loop"; @@ -22,44 +21,44 @@ auto NodeBlockStack::Push(SemIR::NodeBlockId id) -> void { ++size_; } -auto NodeBlockStack::PeekOrAdd(int depth) -> SemIR::NodeBlockId { +auto InstBlockStack::PeekOrAdd(int depth) -> SemIR::InstBlockId { CARBON_CHECK(size() > depth) << "no such block"; int index = size() - depth - 1; auto& slot = stack_[index]; if (!slot.id.is_valid()) { - slot.id = sem_ir_->node_blocks().AddDefaultValue(); + slot.id = sem_ir_->inst_blocks().AddDefaultValue(); } return slot.id; } -auto NodeBlockStack::Pop() -> SemIR::NodeBlockId { +auto InstBlockStack::Pop() -> SemIR::InstBlockId { CARBON_CHECK(!empty()) << "no current block"; --size_; auto& back = stack_[size_]; // Finalize the block. - if (!back.content.empty() && back.id != SemIR::NodeBlockId::Unreachable) { + if (!back.content.empty() && back.id != SemIR::InstBlockId::Unreachable) { if (back.id.is_valid()) { - sem_ir_->node_blocks().Set(back.id, back.content); + sem_ir_->inst_blocks().Set(back.id, back.content); } else { - back.id = sem_ir_->node_blocks().Add(back.content); + back.id = sem_ir_->inst_blocks().Add(back.content); } } CARBON_VLOG() << name_ << " Pop " << size_ << ": " << back.id << "\n"; if (!back.id.is_valid()) { - return SemIR::NodeBlockId::Empty; + return SemIR::InstBlockId::Empty; } return back.id; } -auto NodeBlockStack::PopAndDiscard() -> void { +auto InstBlockStack::PopAndDiscard() -> void { CARBON_CHECK(!empty()) << "no current block"; --size_; CARBON_VLOG() << name_ << " PopAndDiscard " << size_ << "\n"; } -auto NodeBlockStack::PrintForStackDump(llvm::raw_ostream& output) const +auto InstBlockStack::PrintForStackDump(llvm::raw_ostream& output) const -> void { output << name_ << ":\n"; for (const auto& [i, entry] : llvm::enumerate(stack_)) { diff --git a/toolchain/check/node_block_stack.h b/toolchain/check/node_block_stack.h index 727b845290e4..0e9e458d7e27 100644 --- a/toolchain/check/node_block_stack.h +++ b/toolchain/check/node_block_stack.h @@ -7,66 +7,68 @@ #include "llvm/ADT/SmallVector.h" #include "toolchain/sem_ir/file.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { -// A stack of node blocks that are currently being constructed in a Context. The -// contents of the node blocks are stored here until the node block is popped -// from the stack, at which point they are transferred into the SemIR::File for -// long-term storage. +// A stack of instruction blocks that are currently being constructed in a +// Context. The contents of the instruction blocks are stored here until the +// instruction block is popped from the stack, at which point they are +// transferred into the SemIR::File for long-term storage. // // All pushes and pops will be vlogged. -class NodeBlockStack { +class InstBlockStack { public: - explicit NodeBlockStack(llvm::StringLiteral name, SemIR::File& sem_ir, + explicit InstBlockStack(llvm::StringLiteral name, SemIR::File& sem_ir, llvm::raw_ostream* vlog_stream) : name_(name), sem_ir_(&sem_ir), vlog_stream_(vlog_stream) {} - // Pushes an existing node block. - auto Push(SemIR::NodeBlockId id) -> void; + // Pushes an existing instruction block. + auto Push(SemIR::InstBlockId id) -> void; - // Pushes a new node block. It will be invalid unless PeekOrAdd is called in - // order to support lazy allocation. - auto Push() -> void { Push(SemIR::NodeBlockId::Invalid); } + // Pushes a new instruction block. It will be invalid unless PeekOrAdd is + // called in order to support lazy allocation. + auto Push() -> void { Push(SemIR::InstBlockId::Invalid); } // Pushes a new unreachable code block. - auto PushUnreachable() -> void { Push(SemIR::NodeBlockId::Unreachable); } + auto PushUnreachable() -> void { Push(SemIR::InstBlockId::Unreachable); } - // Returns the ID of the top node block, allocating one if necessary. If - // `depth` is specified, returns the node at `depth` levels from the top of - // the stack instead of the top block, where the top block is at depth 0. - auto PeekOrAdd(int depth = 0) -> SemIR::NodeBlockId; + // Returns the ID of the top instruction block, allocating one if necessary. + // If `depth` is specified, returns the instruction at `depth` levels from the + // top of the stack instead of the top block, where the top block is at depth + // 0. + auto PeekOrAdd(int depth = 0) -> SemIR::InstBlockId; - // Pops the top node block. This will always return a valid node block; - // SemIR::NodeBlockId::Empty is returned if one wasn't allocated. - auto Pop() -> SemIR::NodeBlockId; + // Pops the top instruction block. This will always return a valid instruction + // block; SemIR::InstBlockId::Empty is returned if one wasn't allocated. + auto Pop() -> SemIR::InstBlockId; - // Pops the top node block, and discards it if it hasn't had an ID allocated. + // Pops the top instruction block, and discards it if it hasn't had an ID + // allocated. auto PopAndDiscard() -> void; - // Adds the given node to the block at the top of the stack and returns its - // ID. - auto AddNode(SemIR::Node node) -> SemIR::NodeId { - auto node_id = sem_ir_->nodes().AddInNoBlock(node); - AddNodeId(node_id); - return node_id; + // Adds the given instruction to the block at the top of the stack and returns + // its ID. + auto AddInst(SemIR::Inst inst) -> SemIR::InstId { + auto inst_id = sem_ir_->insts().AddInNoBlock(inst); + AddInstId(inst_id); + return inst_id; } - // Adds the given node ID to the block at the top of the stack. - auto AddNodeId(SemIR::NodeId node_id) -> void { + // Adds the given instruction ID to the block at the top of the stack. + auto AddInstId(SemIR::InstId inst_id) -> void { CARBON_CHECK(!empty()) << "no current block"; - stack_[size_ - 1].content.push_back(node_id); + stack_[size_ - 1].content.push_back(inst_id); } // Returns whether the current block is statically reachable. auto is_current_block_reachable() -> bool { return size_ != 0 && - stack_[size_ - 1].id != SemIR::NodeBlockId::Unreachable; + stack_[size_ - 1].id != SemIR::InstBlockId::Unreachable; } - // Returns a view of the contents of the top node block on the stack. - auto PeekCurrentBlockContents() -> llvm::ArrayRef { + // Returns a view of the contents of the top instruction block on the stack. + auto PeekCurrentBlockContents() -> llvm::ArrayRef { CARBON_CHECK(!empty()) << "no current block"; return stack_[size_ - 1].content; } @@ -84,18 +86,18 @@ class NodeBlockStack { // reallocation. StackEntry() { content.reserve(32); } - auto Reset(SemIR::NodeBlockId new_id) { + auto Reset(SemIR::InstBlockId new_id) { id = new_id; content.clear(); } // The block ID, if one has been allocated, Invalid if no block has been // allocated, or Unreachable if this block is known to be unreachable. - SemIR::NodeBlockId id = SemIR::NodeBlockId::Invalid; + SemIR::InstBlockId id = SemIR::InstBlockId::Invalid; // The content of the block. Stored as a vector rather than as a SmallVector // to reduce the cost of resizing `stack_` and performing swaps. - std::vector content; + std::vector content; }; // A name for debugging. diff --git a/toolchain/check/node_stack.cpp b/toolchain/check/node_stack.cpp index 0ed21bb981de..139ea8bd0cc3 100644 --- a/toolchain/check/node_stack.cpp +++ b/toolchain/check/node_stack.cpp @@ -5,7 +5,7 @@ #include "toolchain/check/node_stack.h" #include "llvm/ADT/STLExtras.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { @@ -17,8 +17,8 @@ auto NodeStack::PrintForStackDump(llvm::raw_ostream& output) const -> void { if (parse_node_kind == Parse::NodeKind::PatternBinding) { output << " -> " << entry.name_id; } else { - if (entry.node_id.is_valid()) { - output << " -> " << entry.node_id; + if (entry.inst_id.is_valid()) { + output << " -> " << entry.inst_id; } } output << "\n"; diff --git a/toolchain/check/node_stack.h b/toolchain/check/node_stack.h index 638d43b4a86c..1561a539a0e8 100644 --- a/toolchain/check/node_stack.h +++ b/toolchain/check/node_stack.h @@ -11,11 +11,13 @@ #include "llvm/ADT/SmallVector.h" #include "toolchain/parse/node_kind.h" #include "toolchain/parse/tree.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Check { -// Wraps the stack of nodes for Context. +// Wraps the stack of parse nodes for Context. Each parse node can have an +// associated id of some kind (instruction, instruction block, function, class, +// ...). // // All pushes and pops will be vlogged. // @@ -23,7 +25,7 @@ namespace Carbon::Check { // // - If receiving a pop_parse_kind, verify that the parse_node being popped is // of pop_parse_kind. -// - Validates presence of node_id based on whether it's a solo +// - Validates presence of inst_id based on whether it's a solo // parse_node. // // These should be assumed API constraints unless otherwise mentioned on a @@ -44,7 +46,7 @@ class NodeStack { << parse_tree_->node_kind(parse_node) << " -> \n"; CARBON_CHECK(stack_.size() < (1 << 20)) << "Excessive stack size: likely infinite loop"; - stack_.push_back(Entry(parse_node, SemIR::NodeId::Invalid)); + stack_.push_back(Entry(parse_node, SemIR::InstId::Invalid)); } // Pushes a parse tree node onto the stack with an ID. @@ -70,12 +72,12 @@ class NodeStack { } // Pops the top of the stack without any verification. - auto PopAndIgnore() -> void { PopEntry(); } + auto PopAndIgnore() -> void { PopEntry(); } // Pops the top of the stack and returns the parse_node. template auto PopForSoloParseNode() -> Parse::Node { - Entry back = PopEntry(); + Entry back = PopEntry(); RequireIdKind(Parse::NodeKind::Create(RequiredParseKind), IdKind::SoloParseNode); RequireParseKind(back.parse_node); @@ -100,8 +102,8 @@ class NodeStack { // Pops an expression from the top of the stack and returns the parse_node and // the ID. - auto PopExpressionWithParseNode() -> std::pair { - return PopWithParseNode(); + auto PopExpressionWithParseNode() -> std::pair { + return PopWithParseNode(); } // Pops the top of the stack and returns the parse_node and the ID. @@ -109,13 +111,13 @@ class NodeStack { auto PopWithParseNode() -> auto { constexpr IdKind RequiredIdKind = ParseNodeKindToIdKind(Parse::NodeKind::Create(RequiredParseKind)); - if constexpr (RequiredIdKind == IdKind::NodeId) { - auto back = PopWithParseNode(); + if constexpr (RequiredIdKind == IdKind::InstId) { + auto back = PopWithParseNode(); RequireParseKind(back.first); return back; } - if constexpr (RequiredIdKind == IdKind::NodeBlockId) { - auto back = PopWithParseNode(); + if constexpr (RequiredIdKind == IdKind::InstBlockId) { + auto back = PopWithParseNode(); RequireParseKind(back.first); return back; } @@ -145,8 +147,8 @@ class NodeStack { } // Pops an expression from the top of the stack and returns the ID. - // Expressions map multiple Parse::NodeKinds to SemIR::NodeId always. - auto PopExpression() -> SemIR::NodeId { + // Expressions map multiple Parse::NodeKinds to SemIR::InstId always. + auto PopExpression() -> SemIR::InstId { return PopExpressionWithParseNode().second; } @@ -166,7 +168,7 @@ class NodeStack { return std::nullopt; } - // Peeks at the parse_node of the given depth in the stack, or by default the + // Peeks at the parse node of the given depth in the stack, or by default the // top node. auto PeekParseNode() const -> Parse::Node { return stack_.back().parse_node; } @@ -178,11 +180,11 @@ class NodeStack { RequireParseKind(back.parse_node); constexpr IdKind RequiredIdKind = ParseNodeKindToIdKind(Parse::NodeKind::Create(RequiredParseKind)); - if constexpr (RequiredIdKind == IdKind::NodeId) { - return back.id(); + if constexpr (RequiredIdKind == IdKind::InstId) { + return back.id(); } - if constexpr (RequiredIdKind == IdKind::NodeBlockId) { - return back.id(); + if constexpr (RequiredIdKind == IdKind::InstBlockId) { + return back.id(); } if constexpr (RequiredIdKind == IdKind::FunctionId) { return back.id(); @@ -210,8 +212,8 @@ class NodeStack { private: // Possible associated ID types. enum class IdKind : int8_t { - NodeId, - NodeBlockId, + InstId, + InstBlockId, FunctionId, ClassId, StringId, @@ -224,10 +226,10 @@ class NodeStack { // An entry in stack_. struct Entry { - explicit Entry(Parse::Node parse_node, SemIR::NodeId node_id) - : parse_node(parse_node), node_id(node_id) {} - explicit Entry(Parse::Node parse_node, SemIR::NodeBlockId node_block_id) - : parse_node(parse_node), node_block_id(node_block_id) {} + explicit Entry(Parse::Node parse_node, SemIR::InstId inst_id) + : parse_node(parse_node), inst_id(inst_id) {} + explicit Entry(Parse::Node parse_node, SemIR::InstBlockId inst_block_id) + : parse_node(parse_node), inst_block_id(inst_block_id) {} explicit Entry(Parse::Node parse_node, SemIR::FunctionId function_id) : parse_node(parse_node), function_id(function_id) {} explicit Entry(Parse::Node parse_node, SemIR::ClassId class_id) @@ -240,11 +242,11 @@ class NodeStack { // Returns the appropriate ID basaed on type. template auto id() -> T& { - if constexpr (std::is_same()) { - return node_id; + if constexpr (std::is_same()) { + return inst_id; } - if constexpr (std::is_same()) { - return node_block_id; + if constexpr (std::is_same()) { + return inst_block_id; } if constexpr (std::is_same()) { return function_id; @@ -260,7 +262,7 @@ class NodeStack { } } - // The node associated with the stack entry. + // The parse node associated with the stack entry. Parse::Node parse_node; // The entries will evaluate as invalid if and only if they're a solo @@ -269,8 +271,8 @@ class NodeStack { // A discriminator isn't needed because the caller can determine which field // is used based on the Parse::NodeKind. union { - SemIR::NodeId node_id; - SemIR::NodeBlockId node_block_id; + SemIR::InstId inst_id; + SemIR::InstBlockId inst_block_id; SemIR::FunctionId function_id; SemIR::ClassId class_id; StringId name_id; @@ -305,14 +307,14 @@ class NodeStack { case Parse::NodeKind::StructFieldType: case Parse::NodeKind::StructTypeLiteral: case Parse::NodeKind::TupleLiteral: - return IdKind::NodeId; + return IdKind::InstId; case Parse::NodeKind::IfCondition: case Parse::NodeKind::IfExpressionIf: case Parse::NodeKind::ImplicitParameterList: case Parse::NodeKind::ParameterList: case Parse::NodeKind::WhileCondition: case Parse::NodeKind::WhileConditionStart: - return IdKind::NodeBlockId; + return IdKind::InstBlockId; case Parse::NodeKind::FunctionDefinitionStart: return IdKind::FunctionId; case Parse::NodeKind::ClassDefinitionStart: @@ -344,11 +346,11 @@ class NodeStack { // ParseNodeKindToIdKind. template static constexpr auto IdTypeToIdKind() -> IdKind { - if constexpr (std::is_same_v) { - return IdKind::NodeId; + if constexpr (std::is_same_v) { + return IdKind::InstId; } - if constexpr (std::is_same_v) { - return IdKind::NodeBlockId; + if constexpr (std::is_same_v) { + return IdKind::InstBlockId; } if constexpr (std::is_same_v) { return IdKind::FunctionId; diff --git a/toolchain/check/pending_block.h b/toolchain/check/pending_block.h index 42a32b36f63f..6393b0671661 100644 --- a/toolchain/check/pending_block.h +++ b/toolchain/check/pending_block.h @@ -19,18 +19,18 @@ class PendingBlock { PendingBlock(const PendingBlock&) = delete; PendingBlock& operator=(const PendingBlock&) = delete; - // A scope in which we will tentatively add nodes to a pending block. If we - // leave the scope without inserting or merging the block, nodes added after - // this point will be removed again. - class DiscardUnusedNodesScope { + // A scope in which we will tentatively add instructions to a pending block. + // If we leave the scope without inserting or merging the block, instructions + // added after this point will be removed again. + class DiscardUnusedInstsScope { public: // If `block` is not null, enters the scope. If `block` is null, this object // has no effect. - DiscardUnusedNodesScope(PendingBlock* block) - : block_(block), size_(block ? block->nodes_.size() : 0) {} - ~DiscardUnusedNodesScope() { - if (block_ && block_->nodes_.size() > size_) { - block_->nodes_.truncate(size_); + DiscardUnusedInstsScope(PendingBlock* block) + : block_(block), size_(block ? block->insts_.size() : 0) {} + ~DiscardUnusedInstsScope() { + if (block_ && block_->insts_.size() > size_) { + block_->insts_.truncate(size_); } } @@ -39,52 +39,52 @@ class PendingBlock { size_t size_; }; - auto AddNode(SemIR::Node node) -> SemIR::NodeId { - auto node_id = context_.nodes().AddInNoBlock(node); - nodes_.push_back(node_id); - return node_id; + auto AddInst(SemIR::Inst inst) -> SemIR::InstId { + auto inst_id = context_.insts().AddInNoBlock(inst); + insts_.push_back(inst_id); + return inst_id; } // Insert the pending block of code at the current position. auto InsertHere() -> void { - for (auto id : nodes_) { - context_.node_block_stack().AddNodeId(id); + for (auto id : insts_) { + context_.inst_block_stack().AddInstId(id); } - nodes_.clear(); + insts_.clear(); } - // Replace the node at target_id with the nodes in this block. The new value - // for target_id should be value_id. - auto MergeReplacing(SemIR::NodeId target_id, SemIR::NodeId value_id) -> void { - auto value = context_.nodes().Get(value_id); + // Replace the instruction at target_id with the instructions in this block. + // The new value for target_id should be value_id. + auto MergeReplacing(SemIR::InstId target_id, SemIR::InstId value_id) -> void { + auto value = context_.insts().Get(value_id); // There are three cases here: - if (nodes_.empty()) { + if (insts_.empty()) { // 1) The block is empty. Replace `target_id` with an empty splice // pointing at `value_id`. - context_.nodes().Set( + context_.insts().Set( target_id, SemIR::SpliceBlock{value.parse_node(), value.type_id(), - SemIR::NodeBlockId::Empty, value_id}); - } else if (nodes_.size() == 1 && nodes_[0] == value_id) { - // 2) The block is {value_id}. Replace `target_id` with the node referred - // to by `value_id`. This is intended to be the common case. - context_.nodes().Set(target_id, value); + SemIR::InstBlockId::Empty, value_id}); + } else if (insts_.size() == 1 && insts_[0] == value_id) { + // 2) The block is {value_id}. Replace `target_id` with the instruction + // referred to by `value_id`. This is intended to be the common case. + context_.insts().Set(target_id, value); } else { // 3) Anything else: splice it into the IR, replacing `target_id`. - context_.nodes().Set( + context_.insts().Set( target_id, SemIR::SpliceBlock{value.parse_node(), value.type_id(), - context_.node_blocks().Add(nodes_), value_id}); + context_.inst_blocks().Add(insts_), value_id}); } // Prepare to stash more pending instructions. - nodes_.clear(); + insts_.clear(); } private: Context& context_; - llvm::SmallVector nodes_; + llvm::SmallVector insts_; }; } // namespace Carbon::Check diff --git a/toolchain/check/testdata/basics/builtin_nodes.carbon b/toolchain/check/testdata/basics/builtin_nodes.carbon index d50c1eb4af2e..d832e99ad4ad 100644 --- a/toolchain/check/testdata/basics/builtin_nodes.carbon +++ b/toolchain/check/testdata/basics/builtin_nodes.carbon @@ -14,16 +14,16 @@ // CHECK:STDOUT: classes: {} // CHECK:STDOUT: types: {} // CHECK:STDOUT: type_blocks: {} -// CHECK:STDOUT: nodes: -// CHECK:STDOUT: nodeTypeType: {kind: CrossReference, arg0: ir0, arg1: nodeTypeType, type: typeTypeType} -// CHECK:STDOUT: nodeError: {kind: CrossReference, arg0: ir0, arg1: nodeError, type: typeError} -// CHECK:STDOUT: nodeBoolType: {kind: CrossReference, arg0: ir0, arg1: nodeBoolType, type: typeTypeType} -// CHECK:STDOUT: nodeIntegerType: {kind: CrossReference, arg0: ir0, arg1: nodeIntegerType, type: typeTypeType} -// CHECK:STDOUT: nodeFloatingPointType: {kind: CrossReference, arg0: ir0, arg1: nodeFloatingPointType, type: typeTypeType} -// CHECK:STDOUT: nodeStringType: {kind: CrossReference, arg0: ir0, arg1: nodeStringType, type: typeTypeType} -// CHECK:STDOUT: nodeFunctionType: {kind: CrossReference, arg0: ir0, arg1: nodeFunctionType, type: typeTypeType} -// CHECK:STDOUT: nodeBoundMethodType: {kind: CrossReference, arg0: ir0, arg1: nodeBoundMethodType, type: typeTypeType} -// CHECK:STDOUT: nodeNamespaceType: {kind: CrossReference, arg0: ir0, arg1: nodeNamespaceType, type: typeTypeType} -// CHECK:STDOUT: node_blocks: +// CHECK:STDOUT: insts: +// CHECK:STDOUT: instTypeType: {kind: CrossReference, arg0: ir0, arg1: instTypeType, type: typeTypeType} +// CHECK:STDOUT: instError: {kind: CrossReference, arg0: ir0, arg1: instError, type: typeError} +// CHECK:STDOUT: instBoolType: {kind: CrossReference, arg0: ir0, arg1: instBoolType, type: typeTypeType} +// CHECK:STDOUT: instIntegerType: {kind: CrossReference, arg0: ir0, arg1: instIntegerType, type: typeTypeType} +// CHECK:STDOUT: instFloatingPointType: {kind: CrossReference, arg0: ir0, arg1: instFloatingPointType, type: typeTypeType} +// CHECK:STDOUT: instStringType: {kind: CrossReference, arg0: ir0, arg1: instStringType, type: typeTypeType} +// CHECK:STDOUT: instFunctionType: {kind: CrossReference, arg0: ir0, arg1: instFunctionType, type: typeTypeType} +// CHECK:STDOUT: instBoundMethodType: {kind: CrossReference, arg0: ir0, arg1: instBoundMethodType, type: typeTypeType} +// CHECK:STDOUT: instNamespaceType: {kind: CrossReference, arg0: ir0, arg1: instNamespaceType, type: typeTypeType} +// CHECK:STDOUT: inst_blocks: // CHECK:STDOUT: block0: {} // CHECK:STDOUT: ... diff --git a/toolchain/check/testdata/basics/multifile_raw_and_textual_ir.carbon b/toolchain/check/testdata/basics/multifile_raw_and_textual_ir.carbon index 8759f4c9bdb2..0baa2d738ea3 100644 --- a/toolchain/check/testdata/basics/multifile_raw_and_textual_ir.carbon +++ b/toolchain/check/testdata/basics/multifile_raw_and_textual_ir.carbon @@ -22,17 +22,17 @@ fn B() {} // CHECK:STDOUT: function0: {name: str0, param_refs: block0, body: [block1]} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: type0: {node: nodeFunctionType, value_rep: {kind: copy, type: type0}} +// CHECK:STDOUT: type0: {inst: instFunctionType, value_rep: {kind: copy, type: type0}} // CHECK:STDOUT: type_blocks: {} -// CHECK:STDOUT: nodes: -// CHECK:STDOUT: node+0: {kind: FunctionDeclaration, arg0: function0, type: type0} -// CHECK:STDOUT: node+1: {kind: Return} -// CHECK:STDOUT: node_blocks: +// CHECK:STDOUT: insts: +// CHECK:STDOUT: inst+0: {kind: FunctionDeclaration, arg0: function0, type: type0} +// CHECK:STDOUT: inst+1: {kind: Return} +// CHECK:STDOUT: inst_blocks: // CHECK:STDOUT: block0: {} // CHECK:STDOUT: block1: -// CHECK:STDOUT: 0: node+1 +// CHECK:STDOUT: 0: inst+1 // CHECK:STDOUT: block2: -// CHECK:STDOUT: 0: node+0 +// CHECK:STDOUT: 0: inst+0 // CHECK:STDOUT: ... // CHECK:STDOUT: // CHECK:STDOUT: file "a.carbon" { @@ -51,17 +51,17 @@ fn B() {} // CHECK:STDOUT: function0: {name: str0, param_refs: block0, body: [block1]} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: type0: {node: nodeFunctionType, value_rep: {kind: copy, type: type0}} +// CHECK:STDOUT: type0: {inst: instFunctionType, value_rep: {kind: copy, type: type0}} // CHECK:STDOUT: type_blocks: {} -// CHECK:STDOUT: nodes: -// CHECK:STDOUT: node+0: {kind: FunctionDeclaration, arg0: function0, type: type0} -// CHECK:STDOUT: node+1: {kind: Return} -// CHECK:STDOUT: node_blocks: +// CHECK:STDOUT: insts: +// CHECK:STDOUT: inst+0: {kind: FunctionDeclaration, arg0: function0, type: type0} +// CHECK:STDOUT: inst+1: {kind: Return} +// CHECK:STDOUT: inst_blocks: // CHECK:STDOUT: block0: {} // CHECK:STDOUT: block1: -// CHECK:STDOUT: 0: node+1 +// CHECK:STDOUT: 0: inst+1 // CHECK:STDOUT: block2: -// CHECK:STDOUT: 0: node+0 +// CHECK:STDOUT: 0: inst+0 // CHECK:STDOUT: ... // CHECK:STDOUT: // CHECK:STDOUT: file "b.carbon" { diff --git a/toolchain/check/testdata/basics/multifile_raw_ir.carbon b/toolchain/check/testdata/basics/multifile_raw_ir.carbon index ba0fa9739bd2..1b8d811c0fba 100644 --- a/toolchain/check/testdata/basics/multifile_raw_ir.carbon +++ b/toolchain/check/testdata/basics/multifile_raw_ir.carbon @@ -22,17 +22,17 @@ fn B() {} // CHECK:STDOUT: function0: {name: str0, param_refs: block0, body: [block1]} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: type0: {node: nodeFunctionType, value_rep: {kind: copy, type: type0}} +// CHECK:STDOUT: type0: {inst: instFunctionType, value_rep: {kind: copy, type: type0}} // CHECK:STDOUT: type_blocks: {} -// CHECK:STDOUT: nodes: -// CHECK:STDOUT: node+0: {kind: FunctionDeclaration, arg0: function0, type: type0} -// CHECK:STDOUT: node+1: {kind: Return} -// CHECK:STDOUT: node_blocks: +// CHECK:STDOUT: insts: +// CHECK:STDOUT: inst+0: {kind: FunctionDeclaration, arg0: function0, type: type0} +// CHECK:STDOUT: inst+1: {kind: Return} +// CHECK:STDOUT: inst_blocks: // CHECK:STDOUT: block0: {} // CHECK:STDOUT: block1: -// CHECK:STDOUT: 0: node+1 +// CHECK:STDOUT: 0: inst+1 // CHECK:STDOUT: block2: -// CHECK:STDOUT: 0: node+0 +// CHECK:STDOUT: 0: inst+0 // CHECK:STDOUT: ... // CHECK:STDOUT: --- // CHECK:STDOUT: filename: b.carbon @@ -42,15 +42,15 @@ fn B() {} // CHECK:STDOUT: function0: {name: str0, param_refs: block0, body: [block1]} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: type0: {node: nodeFunctionType, value_rep: {kind: copy, type: type0}} +// CHECK:STDOUT: type0: {inst: instFunctionType, value_rep: {kind: copy, type: type0}} // CHECK:STDOUT: type_blocks: {} -// CHECK:STDOUT: nodes: -// CHECK:STDOUT: node+0: {kind: FunctionDeclaration, arg0: function0, type: type0} -// CHECK:STDOUT: node+1: {kind: Return} -// CHECK:STDOUT: node_blocks: +// CHECK:STDOUT: insts: +// CHECK:STDOUT: inst+0: {kind: FunctionDeclaration, arg0: function0, type: type0} +// CHECK:STDOUT: inst+1: {kind: Return} +// CHECK:STDOUT: inst_blocks: // CHECK:STDOUT: block0: {} // CHECK:STDOUT: block1: -// CHECK:STDOUT: 0: node+1 +// CHECK:STDOUT: 0: inst+1 // CHECK:STDOUT: block2: -// CHECK:STDOUT: 0: node+0 +// CHECK:STDOUT: 0: inst+0 // CHECK:STDOUT: ... diff --git a/toolchain/check/testdata/basics/raw_and_textual_ir.carbon b/toolchain/check/testdata/basics/raw_and_textual_ir.carbon index e24c3068a32f..73ec1a46cb67 100644 --- a/toolchain/check/testdata/basics/raw_and_textual_ir.carbon +++ b/toolchain/check/testdata/basics/raw_and_textual_ir.carbon @@ -17,15 +17,15 @@ fn Foo(n: i32) -> (i32, f64) { // CHECK:STDOUT: sem_ir: // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: -// CHECK:STDOUT: function0: {name: str0, param_refs: block1, return_type: type3, return_slot: node+4, body: [block4]} +// CHECK:STDOUT: function0: {name: str0, param_refs: block1, return_type: type3, return_slot: inst+4, body: [block4]} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: type0: {node: nodeIntegerType, value_rep: {kind: copy, type: type0}} -// CHECK:STDOUT: type1: {node: node+1, value_rep: {kind: unknown, type: type}} -// CHECK:STDOUT: type2: {node: nodeFloatingPointType, value_rep: {kind: copy, type: type2}} -// CHECK:STDOUT: type3: {node: node+3, value_rep: {kind: pointer, type: type4}} -// CHECK:STDOUT: type4: {node: node+5, value_rep: {kind: copy, type: type4}} -// CHECK:STDOUT: type5: {node: nodeFunctionType, value_rep: {kind: copy, type: type5}} +// CHECK:STDOUT: type0: {inst: instIntegerType, value_rep: {kind: copy, type: type0}} +// CHECK:STDOUT: type1: {inst: inst+1, value_rep: {kind: unknown, type: type}} +// CHECK:STDOUT: type2: {inst: instFloatingPointType, value_rep: {kind: copy, type: type2}} +// CHECK:STDOUT: type3: {inst: inst+3, value_rep: {kind: pointer, type: type4}} +// CHECK:STDOUT: type4: {inst: inst+5, value_rep: {kind: copy, type: type4}} +// CHECK:STDOUT: type5: {inst: instFunctionType, value_rep: {kind: copy, type: type5}} // CHECK:STDOUT: type_blocks: // CHECK:STDOUT: typeBlock0: // CHECK:STDOUT: 0: typeTypeType @@ -33,59 +33,59 @@ fn Foo(n: i32) -> (i32, f64) { // CHECK:STDOUT: typeBlock1: // CHECK:STDOUT: 0: type0 // CHECK:STDOUT: 1: type2 -// CHECK:STDOUT: nodes: -// CHECK:STDOUT: node+0: {kind: Parameter, arg0: str1, type: type0} -// CHECK:STDOUT: node+1: {kind: TupleType, arg0: typeBlock0, type: typeTypeType} -// CHECK:STDOUT: node+2: {kind: TupleLiteral, arg0: block2, type: type1} -// CHECK:STDOUT: node+3: {kind: TupleType, arg0: typeBlock1, type: typeTypeType} -// CHECK:STDOUT: node+4: {kind: VarStorage, arg0: str2, type: type3} -// CHECK:STDOUT: node+5: {kind: PointerType, arg0: type3, type: typeTypeType} -// CHECK:STDOUT: node+6: {kind: FunctionDeclaration, arg0: function0, type: type5} -// CHECK:STDOUT: node+7: {kind: NameReference, arg0: str1, arg1: node+0, type: type0} -// CHECK:STDOUT: node+8: {kind: IntegerLiteral, arg0: int3, type: type0} -// CHECK:STDOUT: node+9: {kind: BinaryOperatorAdd, arg0: node+7, arg1: node+8, type: type0} -// CHECK:STDOUT: node+10: {kind: RealLiteral, arg0: real0, type: type2} -// CHECK:STDOUT: node+11: {kind: TupleLiteral, arg0: block5, type: type3} -// CHECK:STDOUT: node+12: {kind: TupleAccess, arg0: node+4, arg1: member0, type: type0} -// CHECK:STDOUT: node+13: {kind: InitializeFrom, arg0: node+9, arg1: node+12, type: type0} -// CHECK:STDOUT: node+14: {kind: TupleAccess, arg0: node+4, arg1: member1, type: type2} -// CHECK:STDOUT: node+15: {kind: InitializeFrom, arg0: node+10, arg1: node+14, type: type2} -// CHECK:STDOUT: node+16: {kind: TupleInit, arg0: node+11, arg1: block6, type: type3} -// CHECK:STDOUT: node+17: {kind: ReturnExpression, arg0: node+16} -// CHECK:STDOUT: node_blocks: +// CHECK:STDOUT: insts: +// CHECK:STDOUT: inst+0: {kind: Parameter, arg0: str1, type: type0} +// CHECK:STDOUT: inst+1: {kind: TupleType, arg0: typeBlock0, type: typeTypeType} +// CHECK:STDOUT: inst+2: {kind: TupleLiteral, arg0: block2, type: type1} +// CHECK:STDOUT: inst+3: {kind: TupleType, arg0: typeBlock1, type: typeTypeType} +// CHECK:STDOUT: inst+4: {kind: VarStorage, arg0: str2, type: type3} +// CHECK:STDOUT: inst+5: {kind: PointerType, arg0: type3, type: typeTypeType} +// CHECK:STDOUT: inst+6: {kind: FunctionDeclaration, arg0: function0, type: type5} +// CHECK:STDOUT: inst+7: {kind: NameReference, arg0: str1, arg1: inst+0, type: type0} +// CHECK:STDOUT: inst+8: {kind: IntegerLiteral, arg0: int3, type: type0} +// CHECK:STDOUT: inst+9: {kind: BinaryOperatorAdd, arg0: inst+7, arg1: inst+8, type: type0} +// CHECK:STDOUT: inst+10: {kind: RealLiteral, arg0: real0, type: type2} +// CHECK:STDOUT: inst+11: {kind: TupleLiteral, arg0: block5, type: type3} +// CHECK:STDOUT: inst+12: {kind: TupleAccess, arg0: inst+4, arg1: member0, type: type0} +// CHECK:STDOUT: inst+13: {kind: InitializeFrom, arg0: inst+9, arg1: inst+12, type: type0} +// CHECK:STDOUT: inst+14: {kind: TupleAccess, arg0: inst+4, arg1: member1, type: type2} +// CHECK:STDOUT: inst+15: {kind: InitializeFrom, arg0: inst+10, arg1: inst+14, type: type2} +// CHECK:STDOUT: inst+16: {kind: TupleInit, arg0: inst+11, arg1: block6, type: type3} +// CHECK:STDOUT: inst+17: {kind: ReturnExpression, arg0: inst+16} +// CHECK:STDOUT: inst_blocks: // CHECK:STDOUT: block0: {} // CHECK:STDOUT: block1: -// CHECK:STDOUT: 0: node+0 +// CHECK:STDOUT: 0: inst+0 // CHECK:STDOUT: block2: -// CHECK:STDOUT: 0: nodeIntegerType -// CHECK:STDOUT: 1: nodeFloatingPointType +// CHECK:STDOUT: 0: instIntegerType +// CHECK:STDOUT: 1: instFloatingPointType // CHECK:STDOUT: block3: -// CHECK:STDOUT: 0: node+0 -// CHECK:STDOUT: 1: node+1 -// CHECK:STDOUT: 2: node+2 -// CHECK:STDOUT: 3: node+3 -// CHECK:STDOUT: 4: node+4 +// CHECK:STDOUT: 0: inst+0 +// CHECK:STDOUT: 1: inst+1 +// CHECK:STDOUT: 2: inst+2 +// CHECK:STDOUT: 3: inst+3 +// CHECK:STDOUT: 4: inst+4 // CHECK:STDOUT: block4: -// CHECK:STDOUT: 0: node+7 -// CHECK:STDOUT: 1: node+8 -// CHECK:STDOUT: 2: node+9 -// CHECK:STDOUT: 3: node+10 -// CHECK:STDOUT: 4: node+11 -// CHECK:STDOUT: 5: node+12 -// CHECK:STDOUT: 6: node+13 -// CHECK:STDOUT: 7: node+14 -// CHECK:STDOUT: 8: node+15 -// CHECK:STDOUT: 9: node+16 -// CHECK:STDOUT: 10: node+17 +// CHECK:STDOUT: 0: inst+7 +// CHECK:STDOUT: 1: inst+8 +// CHECK:STDOUT: 2: inst+9 +// CHECK:STDOUT: 3: inst+10 +// CHECK:STDOUT: 4: inst+11 +// CHECK:STDOUT: 5: inst+12 +// CHECK:STDOUT: 6: inst+13 +// CHECK:STDOUT: 7: inst+14 +// CHECK:STDOUT: 8: inst+15 +// CHECK:STDOUT: 9: inst+16 +// CHECK:STDOUT: 10: inst+17 // CHECK:STDOUT: block5: -// CHECK:STDOUT: 0: node+9 -// CHECK:STDOUT: 1: node+10 +// CHECK:STDOUT: 0: inst+9 +// CHECK:STDOUT: 1: inst+10 // CHECK:STDOUT: block6: -// CHECK:STDOUT: 0: node+13 -// CHECK:STDOUT: 1: node+15 +// CHECK:STDOUT: 0: inst+13 +// CHECK:STDOUT: 1: inst+15 // CHECK:STDOUT: block7: -// CHECK:STDOUT: 0: node+5 -// CHECK:STDOUT: 1: node+6 +// CHECK:STDOUT: 0: inst+5 +// CHECK:STDOUT: 1: inst+6 // CHECK:STDOUT: ... // CHECK:STDOUT: // CHECK:STDOUT: file "raw_and_textual_ir.carbon" { diff --git a/toolchain/check/testdata/basics/raw_ir.carbon b/toolchain/check/testdata/basics/raw_ir.carbon index 5bb0d0a8fdb6..725045b348ae 100644 --- a/toolchain/check/testdata/basics/raw_ir.carbon +++ b/toolchain/check/testdata/basics/raw_ir.carbon @@ -17,15 +17,15 @@ fn Foo(n: i32) -> (i32, f64) { // CHECK:STDOUT: sem_ir: // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: -// CHECK:STDOUT: function0: {name: str0, param_refs: block1, return_type: type3, return_slot: node+4, body: [block4]} +// CHECK:STDOUT: function0: {name: str0, param_refs: block1, return_type: type3, return_slot: inst+4, body: [block4]} // CHECK:STDOUT: classes: {} // CHECK:STDOUT: types: -// CHECK:STDOUT: type0: {node: nodeIntegerType, value_rep: {kind: copy, type: type0}} -// CHECK:STDOUT: type1: {node: node+1, value_rep: {kind: unknown, type: type}} -// CHECK:STDOUT: type2: {node: nodeFloatingPointType, value_rep: {kind: copy, type: type2}} -// CHECK:STDOUT: type3: {node: node+3, value_rep: {kind: pointer, type: type4}} -// CHECK:STDOUT: type4: {node: node+5, value_rep: {kind: copy, type: type4}} -// CHECK:STDOUT: type5: {node: nodeFunctionType, value_rep: {kind: copy, type: type5}} +// CHECK:STDOUT: type0: {inst: instIntegerType, value_rep: {kind: copy, type: type0}} +// CHECK:STDOUT: type1: {inst: inst+1, value_rep: {kind: unknown, type: type}} +// CHECK:STDOUT: type2: {inst: instFloatingPointType, value_rep: {kind: copy, type: type2}} +// CHECK:STDOUT: type3: {inst: inst+3, value_rep: {kind: pointer, type: type4}} +// CHECK:STDOUT: type4: {inst: inst+5, value_rep: {kind: copy, type: type4}} +// CHECK:STDOUT: type5: {inst: instFunctionType, value_rep: {kind: copy, type: type5}} // CHECK:STDOUT: type_blocks: // CHECK:STDOUT: typeBlock0: // CHECK:STDOUT: 0: typeTypeType @@ -33,57 +33,57 @@ fn Foo(n: i32) -> (i32, f64) { // CHECK:STDOUT: typeBlock1: // CHECK:STDOUT: 0: type0 // CHECK:STDOUT: 1: type2 -// CHECK:STDOUT: nodes: -// CHECK:STDOUT: node+0: {kind: Parameter, arg0: str1, type: type0} -// CHECK:STDOUT: node+1: {kind: TupleType, arg0: typeBlock0, type: typeTypeType} -// CHECK:STDOUT: node+2: {kind: TupleLiteral, arg0: block2, type: type1} -// CHECK:STDOUT: node+3: {kind: TupleType, arg0: typeBlock1, type: typeTypeType} -// CHECK:STDOUT: node+4: {kind: VarStorage, arg0: str2, type: type3} -// CHECK:STDOUT: node+5: {kind: PointerType, arg0: type3, type: typeTypeType} -// CHECK:STDOUT: node+6: {kind: FunctionDeclaration, arg0: function0, type: type5} -// CHECK:STDOUT: node+7: {kind: NameReference, arg0: str1, arg1: node+0, type: type0} -// CHECK:STDOUT: node+8: {kind: IntegerLiteral, arg0: int3, type: type0} -// CHECK:STDOUT: node+9: {kind: BinaryOperatorAdd, arg0: node+7, arg1: node+8, type: type0} -// CHECK:STDOUT: node+10: {kind: RealLiteral, arg0: real0, type: type2} -// CHECK:STDOUT: node+11: {kind: TupleLiteral, arg0: block5, type: type3} -// CHECK:STDOUT: node+12: {kind: TupleAccess, arg0: node+4, arg1: member0, type: type0} -// CHECK:STDOUT: node+13: {kind: InitializeFrom, arg0: node+9, arg1: node+12, type: type0} -// CHECK:STDOUT: node+14: {kind: TupleAccess, arg0: node+4, arg1: member1, type: type2} -// CHECK:STDOUT: node+15: {kind: InitializeFrom, arg0: node+10, arg1: node+14, type: type2} -// CHECK:STDOUT: node+16: {kind: TupleInit, arg0: node+11, arg1: block6, type: type3} -// CHECK:STDOUT: node+17: {kind: ReturnExpression, arg0: node+16} -// CHECK:STDOUT: node_blocks: +// CHECK:STDOUT: insts: +// CHECK:STDOUT: inst+0: {kind: Parameter, arg0: str1, type: type0} +// CHECK:STDOUT: inst+1: {kind: TupleType, arg0: typeBlock0, type: typeTypeType} +// CHECK:STDOUT: inst+2: {kind: TupleLiteral, arg0: block2, type: type1} +// CHECK:STDOUT: inst+3: {kind: TupleType, arg0: typeBlock1, type: typeTypeType} +// CHECK:STDOUT: inst+4: {kind: VarStorage, arg0: str2, type: type3} +// CHECK:STDOUT: inst+5: {kind: PointerType, arg0: type3, type: typeTypeType} +// CHECK:STDOUT: inst+6: {kind: FunctionDeclaration, arg0: function0, type: type5} +// CHECK:STDOUT: inst+7: {kind: NameReference, arg0: str1, arg1: inst+0, type: type0} +// CHECK:STDOUT: inst+8: {kind: IntegerLiteral, arg0: int3, type: type0} +// CHECK:STDOUT: inst+9: {kind: BinaryOperatorAdd, arg0: inst+7, arg1: inst+8, type: type0} +// CHECK:STDOUT: inst+10: {kind: RealLiteral, arg0: real0, type: type2} +// CHECK:STDOUT: inst+11: {kind: TupleLiteral, arg0: block5, type: type3} +// CHECK:STDOUT: inst+12: {kind: TupleAccess, arg0: inst+4, arg1: member0, type: type0} +// CHECK:STDOUT: inst+13: {kind: InitializeFrom, arg0: inst+9, arg1: inst+12, type: type0} +// CHECK:STDOUT: inst+14: {kind: TupleAccess, arg0: inst+4, arg1: member1, type: type2} +// CHECK:STDOUT: inst+15: {kind: InitializeFrom, arg0: inst+10, arg1: inst+14, type: type2} +// CHECK:STDOUT: inst+16: {kind: TupleInit, arg0: inst+11, arg1: block6, type: type3} +// CHECK:STDOUT: inst+17: {kind: ReturnExpression, arg0: inst+16} +// CHECK:STDOUT: inst_blocks: // CHECK:STDOUT: block0: {} // CHECK:STDOUT: block1: -// CHECK:STDOUT: 0: node+0 +// CHECK:STDOUT: 0: inst+0 // CHECK:STDOUT: block2: -// CHECK:STDOUT: 0: nodeIntegerType -// CHECK:STDOUT: 1: nodeFloatingPointType +// CHECK:STDOUT: 0: instIntegerType +// CHECK:STDOUT: 1: instFloatingPointType // CHECK:STDOUT: block3: -// CHECK:STDOUT: 0: node+0 -// CHECK:STDOUT: 1: node+1 -// CHECK:STDOUT: 2: node+2 -// CHECK:STDOUT: 3: node+3 -// CHECK:STDOUT: 4: node+4 +// CHECK:STDOUT: 0: inst+0 +// CHECK:STDOUT: 1: inst+1 +// CHECK:STDOUT: 2: inst+2 +// CHECK:STDOUT: 3: inst+3 +// CHECK:STDOUT: 4: inst+4 // CHECK:STDOUT: block4: -// CHECK:STDOUT: 0: node+7 -// CHECK:STDOUT: 1: node+8 -// CHECK:STDOUT: 2: node+9 -// CHECK:STDOUT: 3: node+10 -// CHECK:STDOUT: 4: node+11 -// CHECK:STDOUT: 5: node+12 -// CHECK:STDOUT: 6: node+13 -// CHECK:STDOUT: 7: node+14 -// CHECK:STDOUT: 8: node+15 -// CHECK:STDOUT: 9: node+16 -// CHECK:STDOUT: 10: node+17 +// CHECK:STDOUT: 0: inst+7 +// CHECK:STDOUT: 1: inst+8 +// CHECK:STDOUT: 2: inst+9 +// CHECK:STDOUT: 3: inst+10 +// CHECK:STDOUT: 4: inst+11 +// CHECK:STDOUT: 5: inst+12 +// CHECK:STDOUT: 6: inst+13 +// CHECK:STDOUT: 7: inst+14 +// CHECK:STDOUT: 8: inst+15 +// CHECK:STDOUT: 9: inst+16 +// CHECK:STDOUT: 10: inst+17 // CHECK:STDOUT: block5: -// CHECK:STDOUT: 0: node+9 -// CHECK:STDOUT: 1: node+10 +// CHECK:STDOUT: 0: inst+9 +// CHECK:STDOUT: 1: inst+10 // CHECK:STDOUT: block6: -// CHECK:STDOUT: 0: node+13 -// CHECK:STDOUT: 1: node+15 +// CHECK:STDOUT: 0: inst+13 +// CHECK:STDOUT: 1: inst+15 // CHECK:STDOUT: block7: -// CHECK:STDOUT: 0: node+5 -// CHECK:STDOUT: 1: node+6 +// CHECK:STDOUT: 0: inst+5 +// CHECK:STDOUT: 1: inst+6 // CHECK:STDOUT: ... diff --git a/toolchain/check/testdata/basics/verbose.carbon b/toolchain/check/testdata/basics/verbose.carbon index e1a4aeffe637..8eca8e6c7f0c 100644 --- a/toolchain/check/testdata/basics/verbose.carbon +++ b/toolchain/check/testdata/basics/verbose.carbon @@ -8,10 +8,10 @@ // NOAUTOUPDATE // SET-CHECK-SUBSET // CHECK:STDERR: Node Push 0: FunctionIntroducer -> -// CHECK:STDERR: AddNode: {kind: FunctionDeclaration, arg0: {{.*}}, type: type{{[0-9]+}}} -// CHECK:STDERR: node_block_stack_ Push 1 -// CHECK:STDERR: AddNode: {kind: Return} -// CHECK:STDERR: node_block_stack_ Pop 1: block{{[0-9]+}} +// CHECK:STDERR: AddInst: {kind: FunctionDeclaration, arg0: {{.*}}, type: type{{[0-9]+}}} +// CHECK:STDERR: inst_block_stack_ Push 1 +// CHECK:STDERR: AddInst: {kind: Return} +// CHECK:STDERR: inst_block_stack_ Pop 1: block{{[0-9]+}} fn Foo() { return; diff --git a/toolchain/check/testdata/class/fail_redefinition.carbon b/toolchain/check/testdata/class/fail_redefinition.carbon index 638faa03fe45..887cf7c3fe4e 100644 --- a/toolchain/check/testdata/class/fail_redefinition.carbon +++ b/toolchain/check/testdata/class/fail_redefinition.carbon @@ -39,8 +39,8 @@ fn Class.H() {} // CHECK:STDOUT: %H: = fn_decl @H // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .F = -// CHECK:STDOUT: .H = +// CHECK:STDOUT: .F = +// CHECK:STDOUT: .H = // CHECK:STDOUT: .G = %G // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/nested_name.carbon b/toolchain/check/testdata/class/nested_name.carbon index 774c8985b1b5..9e9c206c57ed 100644 --- a/toolchain/check/testdata/class/nested_name.carbon +++ b/toolchain/check/testdata/class/nested_name.carbon @@ -32,7 +32,7 @@ fn G(o: Outer) { // CHECK:STDOUT: %.loc10: type = struct_type {.n: i32} // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Inner = +// CHECK:STDOUT: .Inner = // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Inner { diff --git a/toolchain/lower/BUILD b/toolchain/lower/BUILD index 3051a4a3574e..7cc8f92d30b7 100644 --- a/toolchain/lower/BUILD +++ b/toolchain/lower/BUILD @@ -43,8 +43,8 @@ cc_library( "//common:vlog", "//toolchain/sem_ir:entry_point", "//toolchain/sem_ir:file", - "//toolchain/sem_ir:node", - "//toolchain/sem_ir:node_kind", + "//toolchain/sem_ir:inst", + "//toolchain/sem_ir:inst_kind", "@llvm-project//llvm:Core", "@llvm-project//llvm:Support", ], diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index 6b1ffe5c7aef..fcca4bb80b75 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -10,7 +10,7 @@ #include "toolchain/lower/function_context.h" #include "toolchain/sem_ir/entry_point.h" #include "toolchain/sem_ir/file.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/node_kind.h" namespace Carbon::Lower { @@ -35,7 +35,7 @@ auto FileContext::Run() -> std::unique_ptr { // used. types_.resize(sem_ir_->types().size()); for (auto type_id : sem_ir_->complete_types()) { - types_[type_id.index] = BuildType(sem_ir_->types().Get(type_id).node_id); + types_[type_id.index] = BuildType(sem_ir_->types().Get(type_id).inst_id); } // Lower function declarations. @@ -61,8 +61,8 @@ auto FileContext::BuildFunctionDeclaration(SemIR::FunctionId function_id) const auto& function = sem_ir().functions().Get(function_id); const bool has_return_slot = function.return_slot_id.is_valid(); auto implicit_param_refs = - sem_ir().node_blocks().Get(function.implicit_param_refs_id); - auto param_refs = sem_ir().node_blocks().Get(function.param_refs_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 = function.return_type_id.is_valid() @@ -73,22 +73,22 @@ auto FileContext::BuildFunctionDeclaration(SemIR::FunctionId function_id) CARBON_CHECK(return_rep.has_return_slot() == has_return_slot); llvm::SmallVector param_types; - // TODO: Consider either storing `param_node_ids` somewhere so that we can + // TODO: Consider either storing `param_inst_ids` somewhere so that we can // reuse it from `BuildFunctionDefinition` and when building calls, or factor // out a mechanism to compute the mapping between parameters and arguments on // demand. - llvm::SmallVector param_node_ids; + llvm::SmallVector param_inst_ids; auto max_llvm_params = has_return_slot + implicit_param_refs.size() + param_refs.size(); param_types.reserve(max_llvm_params); - param_node_ids.reserve(max_llvm_params); + param_inst_ids.reserve(max_llvm_params); if (has_return_slot) { param_types.push_back(GetType(function.return_type_id)->getPointerTo()); - param_node_ids.push_back(function.return_slot_id); + param_inst_ids.push_back(function.return_slot_id); } for (auto param_ref_id : - llvm::concat(implicit_param_refs, param_refs)) { - auto param_type_id = sem_ir().nodes().Get(param_ref_id).type_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); value_rep.kind) { @@ -101,7 +101,7 @@ auto FileContext::BuildFunctionDeclaration(SemIR::FunctionId function_id) case SemIR::ValueRepresentation::Custom: case SemIR::ValueRepresentation::Pointer: param_types.push_back(GetType(value_rep.type_id)); - param_node_ids.push_back(param_ref_id); + param_inst_ids.push_back(param_ref_id); break; } } @@ -129,17 +129,17 @@ auto FileContext::BuildFunctionDeclaration(SemIR::FunctionId function_id) mangled_name, llvm_module()); // Set up parameters and the return slot. - for (auto [node_id, arg] : - llvm::zip_equal(param_node_ids, llvm_function->args())) { - auto node = sem_ir().nodes().Get(node_id); - if (node_id == function.return_slot_id) { + for (auto [inst_id, arg] : + llvm::zip_equal(param_inst_ids, llvm_function->args())) { + auto inst = sem_ir().insts().Get(inst_id); + if (inst_id == function.return_slot_id) { arg.setName("return"); arg.addAttr(llvm::Attribute::getWithStructRetType( llvm_context(), GetType(function.return_type_id))); - } else if (node.Is()) { + } else if (inst.Is()) { arg.setName("self"); } else { - arg.setName(sem_ir().strings().Get(node.As().name_id)); + arg.setName(sem_ir().strings().Get(inst.As().name_id)); } } @@ -161,12 +161,12 @@ auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id) const bool has_return_slot = function.return_slot_id.is_valid(); // Add parameters to locals. - // TODO: This duplicates the mapping between semantics nodes and LLVM + // TODO: This duplicates the mapping between sem_ir instructions and LLVM // function parameters that was already computed in BuildFunctionDeclaration. // We should only do that once. auto implicit_param_refs = - sem_ir().node_blocks().Get(function.implicit_param_refs_id); - auto param_refs = sem_ir().node_blocks().Get(function.param_refs_id); + sem_ir().inst_blocks().Get(function.implicit_param_refs_id); + auto param_refs = sem_ir().inst_blocks().Get(function.param_refs_id); int param_index = 0; if (has_return_slot) { function_lowering.SetLocal(function.return_slot_id, @@ -174,8 +174,8 @@ auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id) ++param_index; } for (auto param_ref_id : - llvm::concat(implicit_param_refs, param_refs)) { - auto param_type_id = sem_ir().nodes().Get(param_ref_id).type_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) { function_lowering.SetLocal( @@ -206,8 +206,8 @@ auto FileContext::BuildFunctionDefinition(SemIR::FunctionId function_id) } } -auto FileContext::BuildType(SemIR::NodeId node_id) -> llvm::Type* { - switch (node_id.index) { +auto FileContext::BuildType(SemIR::InstId inst_id) -> llvm::Type* { + switch (inst_id.index) { case SemIR::BuiltinKind::FloatingPointType.AsInt(): // TODO: Handle different sizes. return llvm::Type::getDoubleTy(*llvm_context_); @@ -228,10 +228,10 @@ auto FileContext::BuildType(SemIR::NodeId node_id) -> llvm::Type* { break; } - auto node = sem_ir_->nodes().Get(node_id); - switch (node.kind()) { + auto inst = sem_ir_->insts().Get(inst_id); + switch (inst.kind()) { case SemIR::ArrayType::Kind: { - auto array_type = node.As(); + auto array_type = inst.As(); return llvm::ArrayType::get( GetType(array_type.element_type_id), sem_ir_->GetArrayBoundValue(array_type.bound_id)); @@ -239,21 +239,21 @@ auto FileContext::BuildType(SemIR::NodeId node_id) -> llvm::Type* { case SemIR::ClassType::Kind: { auto object_representation_id = sem_ir_->classes() - .Get(node.As().class_id) + .Get(inst.As().class_id) .object_representation_id; return GetType(object_representation_id); } case SemIR::ConstType::Kind: - return GetType(node.As().inner_id); + return GetType(inst.As().inner_id); case SemIR::PointerType::Kind: return llvm::PointerType::get(*llvm_context_, /*AddressSpace=*/0); case SemIR::StructType::Kind: { auto fields = - sem_ir_->node_blocks().Get(node.As().fields_id); + sem_ir_->inst_blocks().Get(inst.As().fields_id); llvm::SmallVector subtypes; subtypes.reserve(fields.size()); for (auto field_id : fields) { - auto field = sem_ir_->nodes().GetAs(field_id); + auto field = sem_ir_->insts().GetAs(field_id); // TODO: Handle recursive types. The restriction for builtins prevents // recursion while still letting them cache. CARBON_CHECK(field.field_type_id.index < SemIR::BuiltinKind::ValidCount) @@ -268,7 +268,7 @@ auto FileContext::BuildType(SemIR::NodeId node_id) -> llvm::Type* { // function returns. LLVM doesn't allow declaring variables with a void // type, so that may require significant special casing. auto elements = - sem_ir_->type_blocks().Get(node.As().elements_id); + sem_ir_->type_blocks().Get(inst.As().elements_id); llvm::SmallVector subtypes; subtypes.reserve(elements.size()); for (auto element_id : elements) { @@ -281,7 +281,7 @@ auto FileContext::BuildType(SemIR::NodeId node_id) -> llvm::Type* { return llvm::StructType::get(*llvm_context_); } default: { - CARBON_FATAL() << "Cannot use node as type: " << node_id << " " << node; + CARBON_FATAL() << "Cannot use inst as type: " << inst_id << " " << inst; } } } diff --git a/toolchain/lower/file_context.h b/toolchain/lower/file_context.h index fb12a80a8954..057de752a611 100644 --- a/toolchain/lower/file_context.h +++ b/toolchain/lower/file_context.h @@ -9,7 +9,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "toolchain/sem_ir/file.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Lower { @@ -60,9 +60,9 @@ class FileContext { // declaration with no definition, does nothing. auto BuildFunctionDefinition(SemIR::FunctionId function_id) -> void; - // Builds the type for the given node, which should then be cached by the - // caller. - auto BuildType(SemIR::NodeId node_id) -> llvm::Type*; + // Builds the type for the given instruction, which should then be cached by + // the caller. + auto BuildType(SemIR::InstId inst_id) -> llvm::Type*; // Returns the empty LLVM struct type used to represent the type `type`. auto GetTypeType() -> llvm::StructType* { diff --git a/toolchain/lower/function_context.cpp b/toolchain/lower/function_context.cpp index 1228f138dbca..7ef8f03960ed 100644 --- a/toolchain/lower/function_context.cpp +++ b/toolchain/lower/function_context.cpp @@ -17,7 +17,7 @@ FunctionContext::FunctionContext(FileContext& file_context, builder_(file_context.llvm_context()), vlog_stream_(vlog_stream) {} -auto FunctionContext::GetBlock(SemIR::NodeBlockId block_id) +auto FunctionContext::GetBlock(SemIR::InstBlockId block_id) -> llvm::BasicBlock* { llvm::BasicBlock*& entry = blocks_[block_id]; if (!entry) { @@ -26,7 +26,7 @@ auto FunctionContext::GetBlock(SemIR::NodeBlockId block_id) return entry; } -auto FunctionContext::TryToReuseBlock(SemIR::NodeBlockId block_id, +auto FunctionContext::TryToReuseBlock(SemIR::InstBlockId block_id, llvm::BasicBlock* block) -> bool { if (!blocks_.insert({block_id, block}).second) { return false; @@ -37,23 +37,23 @@ auto FunctionContext::TryToReuseBlock(SemIR::NodeBlockId block_id, return true; } -auto FunctionContext::LowerBlock(SemIR::NodeBlockId block_id) -> void { - for (const auto& node_id : sem_ir().node_blocks().Get(block_id)) { - auto node = sem_ir().nodes().Get(node_id); - CARBON_VLOG() << "Lowering " << node_id << ": " << node << "\n"; +auto FunctionContext::LowerBlock(SemIR::InstBlockId block_id) -> void { + for (const auto& inst_id : sem_ir().inst_blocks().Get(block_id)) { + auto inst = sem_ir().insts().Get(inst_id); + CARBON_VLOG() << "Lowering " << inst_id << ": " << inst << "\n"; // clang warns on unhandled enum values; clang-tidy is incorrect here. // NOLINTNEXTLINE(bugprone-switch-missing-default-case) - switch (node.kind()) { -#define CARBON_SEM_IR_NODE_KIND(Name) \ + switch (inst.kind()) { +#define CARBON_SEM_IR_INST_KIND(Name) \ case SemIR::Name::Kind: \ - Handle##Name(*this, node_id, node.As()); \ + Handle##Name(*this, inst_id, inst.As()); \ break; #include "toolchain/sem_ir/node_kind.def" } } } -auto FunctionContext::GetBlockArg(SemIR::NodeBlockId block_id, +auto FunctionContext::GetBlockArg(SemIR::InstBlockId block_id, SemIR::TypeId type_id) -> llvm::PHINode* { llvm::BasicBlock* block = GetBlock(block_id); @@ -78,8 +78,8 @@ auto FunctionContext::CreateSyntheticBlock() -> llvm::BasicBlock* { return synthetic_block_; } -auto FunctionContext::GetLocalOrGlobal(SemIR::NodeId node_id) -> llvm::Value* { - auto target = sem_ir().nodes().Get(node_id); +auto FunctionContext::GetLocalOrGlobal(SemIR::InstId inst_id) -> llvm::Value* { + auto target = sem_ir().insts().Get(inst_id); if (auto function_decl = target.TryAs()) { return GetFunction(function_decl->function_id); } @@ -87,12 +87,12 @@ auto FunctionContext::GetLocalOrGlobal(SemIR::NodeId node_id) -> llvm::Value* { return GetTypeAsValue(); } // TODO: Handle other kinds of name references to globals. - return GetLocal(node_id); + return GetLocal(inst_id); } auto FunctionContext::FinishInitialization(SemIR::TypeId type_id, - SemIR::NodeId dest_id, - SemIR::NodeId source_id) -> void { + 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: @@ -103,8 +103,8 @@ auto FunctionContext::FinishInitialization(SemIR::TypeId type_id, } } -auto FunctionContext::CopyValue(SemIR::TypeId type_id, SemIR::NodeId source_id, - SemIR::NodeId dest_id) -> void { +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: diff --git a/toolchain/lower/function_context.h b/toolchain/lower/function_context.h index fbf710370d7d..9924dc2028d9 100644 --- a/toolchain/lower/function_context.h +++ b/toolchain/lower/function_context.h @@ -10,7 +10,7 @@ #include "llvm/IR/Module.h" #include "toolchain/lower/file_context.h" #include "toolchain/sem_ir/file.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::Lower { @@ -23,44 +23,44 @@ class FunctionContext { // Returns a basic block corresponding to the start of the given semantics // block, and enqueues it for emission. - auto GetBlock(SemIR::NodeBlockId block_id) -> llvm::BasicBlock*; + auto GetBlock(SemIR::InstBlockId block_id) -> llvm::BasicBlock*; // If we have not yet allocated a `BasicBlock` for this `block_id`, set it to // `block`, and enqueue `block_id` for emission. Returns whether we set the // block. - auto TryToReuseBlock(SemIR::NodeBlockId block_id, llvm::BasicBlock* block) + auto TryToReuseBlock(SemIR::InstBlockId block_id, llvm::BasicBlock* block) -> bool; // Builds LLVM IR for the sequence of instructions in `block_id`. - auto LowerBlock(SemIR::NodeBlockId block_id) -> void; + auto LowerBlock(SemIR::InstBlockId block_id) -> void; // Returns a phi node corresponding to the block argument of the given basic // block. - auto GetBlockArg(SemIR::NodeBlockId block_id, SemIR::TypeId type_id) + auto GetBlockArg(SemIR::InstBlockId block_id, SemIR::TypeId type_id) -> llvm::PHINode*; - // Returns a local (versus global) value for the given node. - auto GetLocal(SemIR::NodeId node_id) -> llvm::Value* { + // Returns a local (versus global) value for the given instruction. + auto GetLocal(SemIR::InstId inst_id) -> llvm::Value* { // All builtins are types, with the same empty lowered value. - if (node_id.index < SemIR::BuiltinKind::ValidCount) { + if (inst_id.index < SemIR::BuiltinKind::ValidCount) { return GetTypeAsValue(); } - auto it = locals_.find(node_id); + auto it = locals_.find(inst_id); CARBON_CHECK(it != locals_.end()) - << "Missing local: " << node_id << " " << sem_ir().nodes().Get(node_id); + << "Missing local: " << inst_id << " " << sem_ir().insts().Get(inst_id); return it->second; } - // Sets the value for the given node. - auto SetLocal(SemIR::NodeId node_id, llvm::Value* value) { - bool added = locals_.insert({node_id, value}).second; - CARBON_CHECK(added) << "Duplicate local insert: " << node_id << " " - << sem_ir().nodes().Get(node_id); + // Sets the value for the given instruction. + auto SetLocal(SemIR::InstId inst_id, llvm::Value* value) { + bool added = locals_.insert({inst_id, value}).second; + CARBON_CHECK(added) << "Duplicate local insert: " << inst_id << " " + << sem_ir().insts().Get(inst_id); } - // Returns a value for the given node, which might not be local. - auto GetLocalOrGlobal(SemIR::NodeId node_id) -> llvm::Value*; + // Returns a value for the given instruction, which might not be local. + auto GetLocalOrGlobal(SemIR::InstId inst_id) -> llvm::Value*; // Gets a callable's function. auto GetFunction(SemIR::FunctionId function_id) -> llvm::Function* { @@ -77,7 +77,7 @@ class FunctionContext { return file_context_->GetTypeAsValue(); } - // Create a synthetic block that corresponds to no SemIR::NodeBlockId. Such + // Create a synthetic block that corresponds to no SemIR::InstBlockId. Such // a block should only ever have a single predecessor, and is used when we // need multiple `llvm::BasicBlock`s to model the linear control flow in a // single SemIR::File block. @@ -92,8 +92,8 @@ class FunctionContext { // initialization of `dest_id` from that initializer. This is a no-op if the // initialization was performed in-place, and otherwise performs a store or a // copy. - auto FinishInitialization(SemIR::TypeId type_id, SemIR::NodeId dest_id, - SemIR::NodeId init_id) -> void; + auto FinishInitialization(SemIR::TypeId type_id, SemIR::InstId dest_id, + SemIR::InstId init_id) -> void; auto llvm_context() -> llvm::LLVMContext& { return file_context_->llvm_context(); @@ -106,8 +106,8 @@ class FunctionContext { // Emits a value copy for type `type_id` from `source_id` to `dest_id`. // `source_id` must produce a value representation for `type_id`, and // `dest_id` must be a pointer to a `type_id` object. - auto CopyValue(SemIR::TypeId type_id, SemIR::NodeId source_id, - SemIR::NodeId dest_id) -> void; + auto CopyValue(SemIR::TypeId type_id, SemIR::InstId source_id, + SemIR::InstId dest_id) -> void; // Context for the overall lowering process. FileContext* file_context_; @@ -121,22 +121,22 @@ class FunctionContext { llvm::raw_ostream* vlog_stream_; // Maps a function's SemIR::File blocks to lowered blocks. - llvm::DenseMap blocks_; + llvm::DenseMap blocks_; // The synthetic block we most recently created. May be null if there is no // such block. llvm::BasicBlock* synthetic_block_ = nullptr; - // Maps a function's SemIR::File nodes to lowered values. + // Maps a function's SemIR::File instructions to lowered values. // TODO: Handle nested scopes. Right now this is just cleared at the end of // every block. - llvm::DenseMap locals_; + llvm::DenseMap locals_; }; -// Declare handlers for each SemIR::File node. -#define CARBON_SEM_IR_NODE_KIND(Name) \ - auto Handle##Name(FunctionContext& context, SemIR::NodeId node_id, \ - SemIR::Name node) \ +// Declare handlers for each SemIR::File instruction. +#define CARBON_SEM_IR_INST_KIND(Name) \ + auto Handle##Name(FunctionContext& context, SemIR::InstId inst_id, \ + SemIR::Name inst) \ ->void; #include "toolchain/sem_ir/node_kind.def" diff --git a/toolchain/lower/handle.cpp b/toolchain/lower/handle.cpp index ed81011ac449..699347e4bf06 100644 --- a/toolchain/lower/handle.cpp +++ b/toolchain/lower/handle.cpp @@ -5,109 +5,109 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Sequence.h" #include "toolchain/lower/function_context.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/node_kind.h" namespace Carbon::Lower { auto HandleCrossReference(FunctionContext& /*context*/, - SemIR::NodeId /*node_id*/, SemIR::CrossReference node) + SemIR::InstId /*inst_id*/, SemIR::CrossReference inst) -> void { - CARBON_FATAL() << "TODO: Add support: " << node; + CARBON_FATAL() << "TODO: Add support: " << inst; } -auto HandleAddressOf(FunctionContext& context, SemIR::NodeId node_id, - SemIR::AddressOf node) -> void { - context.SetLocal(node_id, context.GetLocal(node.lvalue_id)); +auto HandleAddressOf(FunctionContext& context, SemIR::InstId inst_id, + SemIR::AddressOf inst) -> void { + context.SetLocal(inst_id, context.GetLocal(inst.lvalue_id)); } -auto HandleArrayIndex(FunctionContext& context, SemIR::NodeId node_id, - SemIR::ArrayIndex node) -> void { - auto* array_value = context.GetLocal(node.array_id); +auto HandleArrayIndex(FunctionContext& context, SemIR::InstId inst_id, + SemIR::ArrayIndex inst) -> void { + auto* array_value = context.GetLocal(inst.array_id); auto* llvm_type = - context.GetType(context.sem_ir().nodes().Get(node.array_id).type_id()); + context.GetType(context.sem_ir().insts().Get(inst.array_id).type_id()); llvm::Value* indexes[2] = { llvm::ConstantInt::get(llvm::Type::getInt32Ty(context.llvm_context()), 0), - context.GetLocal(node.index_id)}; - context.SetLocal(node_id, + context.GetLocal(inst.index_id)}; + context.SetLocal(inst_id, context.builder().CreateInBoundsGEP(llvm_type, array_value, indexes, "array.index")); } -auto HandleArrayInit(FunctionContext& context, SemIR::NodeId node_id, - SemIR::ArrayInit node) -> void { +auto HandleArrayInit(FunctionContext& context, SemIR::InstId inst_id, + SemIR::ArrayInit inst) -> void { // The result of initialization is the return slot of the initializer. - context.SetLocal(node_id, + context.SetLocal(inst_id, context.GetLocal(context.sem_ir() - .node_blocks() - .Get(node.inits_and_return_slot_id) + .inst_blocks() + .Get(inst.inits_and_return_slot_id) .back())); } -auto HandleAssign(FunctionContext& context, SemIR::NodeId /*node_id*/, - SemIR::Assign node) -> void { - auto storage_type_id = context.sem_ir().nodes().Get(node.lhs_id).type_id(); - context.FinishInitialization(storage_type_id, node.lhs_id, node.rhs_id); +auto HandleAssign(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.FinishInitialization(storage_type_id, inst.lhs_id, inst.rhs_id); } auto HandleBinaryOperatorAdd(FunctionContext& /*context*/, - SemIR::NodeId /*node_id*/, - SemIR::BinaryOperatorAdd node) -> void { - CARBON_FATAL() << "TODO: Add support: " << node; + SemIR::InstId /*inst_id*/, + SemIR::BinaryOperatorAdd inst) -> void { + CARBON_FATAL() << "TODO: Add support: " << inst; } -auto HandleBindName(FunctionContext& context, SemIR::NodeId node_id, - SemIR::BindName node) -> void { - context.SetLocal(node_id, context.GetLocal(node.value_id)); +auto HandleBindName(FunctionContext& context, SemIR::InstId inst_id, + SemIR::BindName inst) -> void { + context.SetLocal(inst_id, context.GetLocal(inst.value_id)); } -auto HandleBlockArg(FunctionContext& context, SemIR::NodeId node_id, - SemIR::BlockArg node) -> void { - context.SetLocal(node_id, context.GetBlockArg(node.block_id, node.type_id)); +auto HandleBlockArg(FunctionContext& context, SemIR::InstId inst_id, + SemIR::BlockArg inst) -> void { + context.SetLocal(inst_id, context.GetBlockArg(inst.block_id, inst.type_id)); } -auto HandleBoolLiteral(FunctionContext& context, SemIR::NodeId node_id, - SemIR::BoolLiteral node) -> void { +auto HandleBoolLiteral(FunctionContext& context, SemIR::InstId inst_id, + SemIR::BoolLiteral inst) -> void { llvm::Value* v = - llvm::ConstantInt::get(context.builder().getInt1Ty(), node.value.index); - context.SetLocal(node_id, v); + llvm::ConstantInt::get(context.builder().getInt1Ty(), inst.value.index); + context.SetLocal(inst_id, v); } -auto HandleBoundMethod(FunctionContext& context, SemIR::NodeId node_id, - SemIR::BoundMethod node) -> void { +auto HandleBoundMethod(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(node_id, context.GetLocalOrGlobal(node.function_id)); + context.SetLocal(inst_id, context.GetLocalOrGlobal(inst.function_id)); } -auto HandleBranch(FunctionContext& context, SemIR::NodeId /*node_id*/, - SemIR::Branch node) -> void { +auto HandleBranch(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(); - if (block->empty() && context.TryToReuseBlock(node.target_id, block)) { + if (block->empty() && context.TryToReuseBlock(inst.target_id, block)) { // Reuse this block as the branch target. } else { - context.builder().CreateBr(context.GetBlock(node.target_id)); + context.builder().CreateBr(context.GetBlock(inst.target_id)); } context.builder().ClearInsertionPoint(); } -auto HandleBranchIf(FunctionContext& context, SemIR::NodeId /*node_id*/, - SemIR::BranchIf node) -> void { - llvm::Value* cond = context.GetLocal(node.cond_id); - llvm::BasicBlock* then_block = context.GetBlock(node.target_id); +auto HandleBranchIf(FunctionContext& context, SemIR::InstId /*inst_id*/, + SemIR::BranchIf inst) -> void { + llvm::Value* cond = context.GetLocal(inst.cond_id); + llvm::BasicBlock* then_block = context.GetBlock(inst.target_id); llvm::BasicBlock* else_block = context.CreateSyntheticBlock(); context.builder().CreateCondBr(cond, then_block, else_block); context.builder().SetInsertPoint(else_block); } -auto HandleBranchWithArg(FunctionContext& context, SemIR::NodeId /*node_id*/, - SemIR::BranchWithArg node) -> void { - llvm::Value* arg = context.GetLocal(node.arg_id); +auto HandleBranchWithArg(FunctionContext& context, SemIR::InstId /*inst_id*/, + SemIR::BranchWithArg inst) -> void { + llvm::Value* arg = context.GetLocal(inst.arg_id); SemIR::TypeId arg_type_id = - context.sem_ir().nodes().Get(node.arg_id).type_id(); + context.sem_ir().insts().Get(inst.arg_id).type_id(); // Opportunistically avoid creating a BasicBlock that contains just a branch. // We only do this for a block that we know will only have a single @@ -116,41 +116,41 @@ auto HandleBranchWithArg(FunctionContext& context, SemIR::NodeId /*node_id*/, llvm::BasicBlock* block = context.builder().GetInsertBlock(); llvm::BasicBlock* phi_predecessor = block; if (block->empty() && context.IsCurrentSyntheticBlock(block) && - context.TryToReuseBlock(node.target_id, block)) { + context.TryToReuseBlock(inst.target_id, block)) { // Reuse this block as the branch target. phi_predecessor = block->getSinglePredecessor(); CARBON_CHECK(phi_predecessor) << "Synthetic block did not have a single predecessor"; } else { - context.builder().CreateBr(context.GetBlock(node.target_id)); + context.builder().CreateBr(context.GetBlock(inst.target_id)); } - context.GetBlockArg(node.target_id, arg_type_id) + context.GetBlockArg(inst.target_id, arg_type_id) ->addIncoming(arg, phi_predecessor); context.builder().ClearInsertionPoint(); } -auto HandleBuiltin(FunctionContext& /*context*/, SemIR::NodeId /*node_id*/, - SemIR::Builtin node) -> void { - CARBON_FATAL() << "TODO: Add support: " << node; +auto HandleBuiltin(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/, + SemIR::Builtin inst) -> void { + CARBON_FATAL() << "TODO: Add support: " << inst; } -auto HandleCall(FunctionContext& context, SemIR::NodeId node_id, - SemIR::Call node) -> void { - auto* callee = llvm::cast(context.GetLocal(node.callee_id)); +auto HandleCall(FunctionContext& context, SemIR::InstId inst_id, + SemIR::Call inst) -> void { + auto* callee = llvm::cast(context.GetLocal(inst.callee_id)); std::vector args; - llvm::ArrayRef arg_ids = - context.sem_ir().node_blocks().Get(node.args_id); + llvm::ArrayRef arg_ids = + context.sem_ir().inst_blocks().Get(inst.args_id); - if (SemIR::GetInitializingRepresentation(context.sem_ir(), node.type_id) + if (SemIR::GetInitializingRepresentation(context.sem_ir(), inst.type_id) .has_return_slot()) { args.push_back(context.GetLocal(arg_ids.back())); arg_ids = arg_ids.drop_back(); } for (auto arg_id : arg_ids) { - auto arg_type_id = context.sem_ir().nodes().Get(arg_id).type_id(); + 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) { args.push_back(context.GetLocal(arg_id)); @@ -158,7 +158,7 @@ auto HandleCall(FunctionContext& context, SemIR::NodeId node_id, } auto* call = context.builder().CreateCall(callee, args); - context.SetLocal(node_id, call); + context.SetLocal(inst_id, call); // Name the call's result the same as the callee. // TODO: Is this a helpful name? @@ -168,8 +168,8 @@ auto HandleCall(FunctionContext& context, SemIR::NodeId node_id, } auto HandleClassDeclaration(FunctionContext& /*context*/, - SemIR::NodeId /*node_id*/, - SemIR::ClassDeclaration /*node*/) -> void { + SemIR::InstId /*inst_id*/, + SemIR::ClassDeclaration /*inst*/) -> void { // No action to perform. } @@ -177,14 +177,14 @@ auto HandleClassDeclaration(FunctionContext& /*context*/, // index. Depending on the expression category and value representation of the // aggregate input, this will either produce a value or a reference. static auto GetAggregateElement(FunctionContext& context, - SemIR::NodeId aggr_node_id, + SemIR::InstId aggr_inst_id, SemIR::MemberIndex idx, SemIR::TypeId result_type_id, llvm::Twine name) -> llvm::Value* { - auto aggr_node = context.sem_ir().nodes().Get(aggr_node_id); - auto* aggr_value = context.GetLocal(aggr_node_id); + auto aggr_inst = context.sem_ir().insts().Get(aggr_inst_id); + auto* aggr_value = context.GetLocal(aggr_inst_id); - switch (SemIR::GetExpressionCategory(context.sem_ir(), aggr_node_id)) { + switch (SemIR::GetExpressionCategory(context.sem_ir(), aggr_inst_id)) { case SemIR::ExpressionCategory::Error: case SemIR::ExpressionCategory::NotExpression: case SemIR::ExpressionCategory::Initializing: @@ -193,7 +193,7 @@ static auto GetAggregateElement(FunctionContext& context, case SemIR::ExpressionCategory::Value: { auto value_rep = - SemIR::GetValueRepresentation(context.sem_ir(), aggr_node.type_id()); + SemIR::GetValueRepresentation(context.sem_ir(), aggr_inst.type_id()); CARBON_CHECK(value_rep.aggregate_kind != SemIR::ValueRepresentation::NotAggregate) << "aggregate type should have aggregate value representation"; @@ -237,7 +237,7 @@ static auto GetAggregateElement(FunctionContext& context, case SemIR::ExpressionCategory::DurableReference: case SemIR::ExpressionCategory::EphemeralReference: { // Just locate the aggregate element. - auto* aggr_type = context.GetType(aggr_node.type_id()); + auto* aggr_type = context.GetType(aggr_inst.type_id()); return context.builder().CreateStructGEP(aggr_type, aggr_value, idx.index, name); } @@ -247,24 +247,24 @@ static auto GetAggregateElement(FunctionContext& context, static auto GetStructFieldName(FunctionContext& context, SemIR::TypeId struct_type_id, SemIR::MemberIndex index) -> llvm::StringRef { - auto fields = context.sem_ir().node_blocks().Get( + auto fields = context.sem_ir().inst_blocks().Get( context.sem_ir() - .nodes() + .insts() .GetAs( - context.sem_ir().types().Get(struct_type_id).node_id) + context.sem_ir().types().Get(struct_type_id).inst_id) .fields_id); - auto field = context.sem_ir().nodes().GetAs( + auto field = context.sem_ir().insts().GetAs( fields[index.index]); return context.sem_ir().strings().Get(field.name_id); } -auto HandleClassFieldAccess(FunctionContext& context, SemIR::NodeId node_id, - SemIR::ClassFieldAccess node) -> void { +auto HandleClassFieldAccess(FunctionContext& context, SemIR::InstId inst_id, + SemIR::ClassFieldAccess inst) -> void { // Find the class that we're performing access into. - auto class_type_id = context.sem_ir().nodes().Get(node.base_id).type_id(); + auto class_type_id = context.sem_ir().insts().Get(inst.base_id).type_id(); auto class_id = context.sem_ir() - .nodes() + .insts() .GetAs( context.sem_ir().GetTypeAllowBuiltinTypes(class_type_id)) .class_id; @@ -273,97 +273,97 @@ auto HandleClassFieldAccess(FunctionContext& context, SemIR::NodeId node_id, // Translate the class field access into a struct access on the object // representation. context.SetLocal( - node_id, + inst_id, GetAggregateElement( - context, node.base_id, node.index, node.type_id, + context, inst.base_id, inst.index, inst.type_id, GetStructFieldName(context, class_info.object_representation_id, - node.index))); + inst.index))); } -auto HandleDereference(FunctionContext& context, SemIR::NodeId node_id, - SemIR::Dereference node) -> void { - context.SetLocal(node_id, context.GetLocal(node.pointer_id)); +auto HandleDereference(FunctionContext& context, SemIR::InstId inst_id, + SemIR::Dereference inst) -> void { + context.SetLocal(inst_id, context.GetLocal(inst.pointer_id)); } -auto HandleField(FunctionContext& /*context*/, SemIR::NodeId /*node_id*/, - SemIR::Field /*node*/) -> void { +auto HandleField(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/, + SemIR::Field /*inst*/) -> void { // No action to perform. } auto HandleFunctionDeclaration(FunctionContext& /*context*/, - SemIR::NodeId /*node_id*/, - SemIR::FunctionDeclaration node) -> void { + SemIR::InstId /*inst_id*/, + SemIR::FunctionDeclaration inst) -> void { CARBON_FATAL() << "Should not be encountered. If that changes, we may want to change " "higher-level logic to skip them rather than calling this. " - << node; + << inst; } -auto HandleInitializeFrom(FunctionContext& context, SemIR::NodeId /*node_id*/, - SemIR::InitializeFrom node) -> void { - auto storage_type_id = context.sem_ir().nodes().Get(node.dest_id).type_id(); - context.FinishInitialization(storage_type_id, node.dest_id, node.src_id); +auto HandleInitializeFrom(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.FinishInitialization(storage_type_id, inst.dest_id, inst.src_id); } -auto HandleIntegerLiteral(FunctionContext& context, SemIR::NodeId node_id, - SemIR::IntegerLiteral node) -> void { - const llvm::APInt& i = context.sem_ir().integers().Get(node.integer_id); +auto HandleIntegerLiteral(FunctionContext& context, SemIR::InstId inst_id, + SemIR::IntegerLiteral inst) -> void { + const llvm::APInt& i = context.sem_ir().integers().Get(inst.integer_id); // TODO: This won't offer correct semantics, but seems close enough for now. llvm::Value* v = llvm::ConstantInt::get(context.builder().getInt32Ty(), i.getZExtValue()); - context.SetLocal(node_id, v); + context.SetLocal(inst_id, v); } -auto HandleNameReference(FunctionContext& context, SemIR::NodeId node_id, - SemIR::NameReference node) -> void { - auto type_node_id = context.sem_ir().GetTypeAllowBuiltinTypes(node.type_id); - if (type_node_id == SemIR::NodeId::BuiltinNamespaceType) { +auto HandleNameReference(FunctionContext& context, SemIR::InstId inst_id, + SemIR::NameReference inst) -> void { + auto type_inst_id = context.sem_ir().GetTypeAllowBuiltinTypes(inst.type_id); + if (type_inst_id == SemIR::InstId::BuiltinNamespaceType) { return; } - context.SetLocal(node_id, context.GetLocalOrGlobal(node.value_id)); + context.SetLocal(inst_id, context.GetLocalOrGlobal(inst.value_id)); } -auto HandleNamespace(FunctionContext& /*context*/, SemIR::NodeId /*node_id*/, - SemIR::Namespace node) -> void { +auto HandleNamespace(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/, + SemIR::Namespace inst) -> void { CARBON_FATAL() << "Should not be encountered. If that changes, we may want to change " "higher-level logic to skip them rather than calling this. " - << node; + << inst; } -auto HandleNoOp(FunctionContext& /*context*/, SemIR::NodeId /*node_id*/, - SemIR::NoOp /*node*/) -> void { +auto HandleNoOp(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/, + SemIR::NoOp /*inst*/) -> void { // No action to take. } -auto HandleParameter(FunctionContext& /*context*/, SemIR::NodeId /*node_id*/, - SemIR::Parameter /*node*/) -> void { +auto HandleParameter(FunctionContext& /*context*/, SemIR::InstId /*inst_id*/, + SemIR::Parameter /*inst*/) -> void { CARBON_FATAL() << "Parameters should be lowered by `BuildFunctionDefinition`"; } -auto HandleRealLiteral(FunctionContext& context, SemIR::NodeId node_id, - SemIR::RealLiteral node) -> void { - const Real& real = context.sem_ir().reals().Get(node.real_id); +auto HandleRealLiteral(FunctionContext& context, SemIR::InstId inst_id, + SemIR::RealLiteral inst) -> void { + const Real& real = context.sem_ir().reals().Get(inst.real_id); // TODO: This will probably have overflow issues, and should be fixed. double val = real.mantissa.getZExtValue() * std::pow((real.is_decimal ? 10 : 2), real.exponent.getSExtValue()); llvm::APFloat llvm_val(val); - context.SetLocal(node_id, llvm::ConstantFP::get( + context.SetLocal(inst_id, llvm::ConstantFP::get( context.builder().getDoubleTy(), llvm_val)); } -auto HandleReturn(FunctionContext& context, SemIR::NodeId /*node_id*/, - SemIR::Return /*node*/) -> void { +auto HandleReturn(FunctionContext& context, SemIR::InstId /*inst_id*/, + SemIR::Return /*inst*/) -> void { context.builder().CreateRetVoid(); } -auto HandleReturnExpression(FunctionContext& context, SemIR::NodeId /*node_id*/, - SemIR::ReturnExpression node) -> void { +auto HandleReturnExpression(FunctionContext& context, SemIR::InstId /*inst_id*/, + SemIR::ReturnExpression inst) -> void { switch (SemIR::GetInitializingRepresentation( context.sem_ir(), - context.sem_ir().nodes().Get(node.expr_id).type_id()) + context.sem_ir().insts().Get(inst.expr_id).type_id()) .kind) { case SemIR::InitializingRepresentation::None: case SemIR::InitializingRepresentation::InPlace: @@ -372,41 +372,41 @@ auto HandleReturnExpression(FunctionContext& context, SemIR::NodeId /*node_id*/, return; case SemIR::InitializingRepresentation::ByCopy: // The expression produces the value representation for the type. - context.builder().CreateRet(context.GetLocal(node.expr_id)); + context.builder().CreateRet(context.GetLocal(inst.expr_id)); return; } } auto HandleSelfParameter(FunctionContext& /*context*/, - SemIR::NodeId /*node_id*/, - SemIR::SelfParameter /*node*/) -> void { + SemIR::InstId /*inst_id*/, + SemIR::SelfParameter /*inst*/) -> void { CARBON_FATAL() << "Parameters should be lowered by `BuildFunctionDefinition`"; } -auto HandleSpliceBlock(FunctionContext& context, SemIR::NodeId node_id, - SemIR::SpliceBlock node) -> void { - context.LowerBlock(node.block_id); - context.SetLocal(node_id, context.GetLocal(node.result_id)); +auto HandleSpliceBlock(FunctionContext& context, SemIR::InstId inst_id, + SemIR::SpliceBlock inst) -> void { + context.LowerBlock(inst.block_id); + context.SetLocal(inst_id, context.GetLocal(inst.result_id)); } auto HandleStringLiteral(FunctionContext& /*context*/, - SemIR::NodeId /*node_id*/, SemIR::StringLiteral node) + SemIR::InstId /*inst_id*/, SemIR::StringLiteral inst) -> void { - CARBON_FATAL() << "TODO: Add support: " << node; + CARBON_FATAL() << "TODO: Add support: " << inst; } -auto HandleStructAccess(FunctionContext& context, SemIR::NodeId node_id, - SemIR::StructAccess node) -> void { - auto struct_type_id = context.sem_ir().nodes().Get(node.struct_id).type_id(); +auto HandleStructAccess(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( - node_id, GetAggregateElement( - context, node.struct_id, node.index, node.type_id, - GetStructFieldName(context, struct_type_id, node.index))); + inst_id, GetAggregateElement( + context, inst.struct_id, inst.index, inst.type_id, + GetStructFieldName(context, struct_type_id, inst.index))); } auto HandleStructLiteral(FunctionContext& /*context*/, - SemIR::NodeId /*node_id*/, - SemIR::StructLiteral /*node*/) -> void { + SemIR::InstId /*inst_id*/, + SemIR::StructLiteral /*inst*/) -> void { // A StructLiteral should always be converted to a StructInit or StructValue // if its value is needed. } @@ -415,7 +415,7 @@ auto HandleStructLiteral(FunctionContext& /*context*/, // contents of `refs_id`. auto EmitStructOrTupleValueRepresentation(FunctionContext& context, SemIR::TypeId type_id, - SemIR::NodeBlockId refs_id, + SemIR::InstBlockId refs_id, llvm::Twine name) -> llvm::Value* { auto value_rep = SemIR::GetValueRepresentation(context.sem_ir(), type_id); switch (value_rep.kind) { @@ -427,7 +427,7 @@ auto EmitStructOrTupleValueRepresentation(FunctionContext& context, return llvm::PoisonValue::get(context.GetType(value_rep.type_id)); case SemIR::ValueRepresentation::Copy: { - auto refs = context.sem_ir().node_blocks().Get(refs_id); + auto refs = context.sem_ir().inst_blocks().Get(refs_id); CARBON_CHECK(refs.size() == 1) << "Unexpected size for aggregate with by-copy value representation"; // TODO: Remove the LLVM StructType wrapper in this case, so we don't @@ -447,7 +447,7 @@ auto EmitStructOrTupleValueRepresentation(FunctionContext& context, context.builder().CreateAlloca(llvm_value_rep_type, /*ArraySize=*/nullptr, name); for (auto [i, ref] : - llvm::enumerate(context.sem_ir().node_blocks().Get(refs_id))) { + llvm::enumerate(context.sem_ir().inst_blocks().Get(refs_id))) { context.builder().CreateStore( context.GetLocal(ref), context.builder().CreateStructGEP(llvm_value_rep_type, alloca, i)); @@ -461,107 +461,107 @@ auto EmitStructOrTupleValueRepresentation(FunctionContext& context, } } -auto HandleStructInit(FunctionContext& context, SemIR::NodeId node_id, - SemIR::StructInit node) -> void { - auto* llvm_type = context.GetType(node.type_id); +auto HandleStructInit(FunctionContext& context, SemIR::InstId inst_id, + SemIR::StructInit inst) -> void { + auto* llvm_type = context.GetType(inst.type_id); - switch (SemIR::GetInitializingRepresentation(context.sem_ir(), node.type_id) + switch (SemIR::GetInitializingRepresentation(context.sem_ir(), inst.type_id) .kind) { case SemIR::InitializingRepresentation::None: case SemIR::InitializingRepresentation::InPlace: // TODO: Add a helper to poison a value slot. - context.SetLocal(node_id, llvm::PoisonValue::get(llvm_type)); + context.SetLocal(inst_id, llvm::PoisonValue::get(llvm_type)); break; case SemIR::InitializingRepresentation::ByCopy: { context.SetLocal( - node_id, EmitStructOrTupleValueRepresentation( - context, node.type_id, node.elements_id, "struct.init")); + inst_id, EmitStructOrTupleValueRepresentation( + context, inst.type_id, inst.elements_id, "struct.init")); break; } } } -auto HandleStructValue(FunctionContext& context, SemIR::NodeId node_id, - SemIR::StructValue node) -> void { - context.SetLocal(node_id, +auto HandleStructValue(FunctionContext& context, SemIR::InstId inst_id, + SemIR::StructValue inst) -> void { + context.SetLocal(inst_id, EmitStructOrTupleValueRepresentation( - context, node.type_id, node.elements_id, "struct")); + context, inst.type_id, inst.elements_id, "struct")); } auto HandleStructTypeField(FunctionContext& /*context*/, - SemIR::NodeId /*node_id*/, - SemIR::StructTypeField /*node*/) -> void { + SemIR::InstId /*inst_id*/, + SemIR::StructTypeField /*inst*/) -> void { // No action to take. } -auto HandleTupleAccess(FunctionContext& context, SemIR::NodeId node_id, - SemIR::TupleAccess node) -> void { - context.SetLocal(node_id, - GetAggregateElement(context, node.tuple_id, node.index, - node.type_id, "tuple.elem")); +auto HandleTupleAccess(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::NodeId node_id, - SemIR::TupleIndex node) -> void { - auto index_node = - context.sem_ir().nodes().GetAs(node.index_id); +auto HandleTupleIndex(FunctionContext& context, SemIR::InstId inst_id, + SemIR::TupleIndex inst) -> void { + auto index_inst = + context.sem_ir().insts().GetAs(inst.index_id); auto index = - context.sem_ir().integers().Get(index_node.integer_id).getZExtValue(); - context.SetLocal(node_id, GetAggregateElement(context, node.tuple_id, + context.sem_ir().integers().Get(index_inst.integer_id).getZExtValue(); + context.SetLocal(inst_id, GetAggregateElement(context, inst.tuple_id, SemIR::MemberIndex(index), - node.type_id, "tuple.index")); + inst.type_id, "tuple.index")); } -auto HandleTupleLiteral(FunctionContext& /*context*/, SemIR::NodeId /*node_id*/, - SemIR::TupleLiteral /*node*/) -> void { +auto HandleTupleLiteral(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::NodeId node_id, - SemIR::TupleInit node) -> void { - auto* llvm_type = context.GetType(node.type_id); +auto HandleTupleInit(FunctionContext& context, SemIR::InstId inst_id, + SemIR::TupleInit inst) -> void { + auto* llvm_type = context.GetType(inst.type_id); - switch (SemIR::GetInitializingRepresentation(context.sem_ir(), node.type_id) + switch (SemIR::GetInitializingRepresentation(context.sem_ir(), inst.type_id) .kind) { case SemIR::InitializingRepresentation::None: case SemIR::InitializingRepresentation::InPlace: // TODO: Add a helper to poison a value slot. - context.SetLocal(node_id, llvm::PoisonValue::get(llvm_type)); + context.SetLocal(inst_id, llvm::PoisonValue::get(llvm_type)); break; case SemIR::InitializingRepresentation::ByCopy: { context.SetLocal( - node_id, EmitStructOrTupleValueRepresentation( - context, node.type_id, node.elements_id, "tuple.init")); + inst_id, EmitStructOrTupleValueRepresentation( + context, inst.type_id, inst.elements_id, "tuple.init")); break; } } } -auto HandleTupleValue(FunctionContext& context, SemIR::NodeId node_id, - SemIR::TupleValue node) -> void { +auto HandleTupleValue(FunctionContext& context, SemIR::InstId inst_id, + SemIR::TupleValue inst) -> void { context.SetLocal( - node_id, EmitStructOrTupleValueRepresentation(context, node.type_id, - node.elements_id, "tuple")); + inst_id, EmitStructOrTupleValueRepresentation(context, inst.type_id, + inst.elements_id, "tuple")); } -auto HandleUnaryOperatorNot(FunctionContext& context, SemIR::NodeId node_id, - SemIR::UnaryOperatorNot node) -> void { +auto HandleUnaryOperatorNot(FunctionContext& context, SemIR::InstId inst_id, + SemIR::UnaryOperatorNot inst) -> void { context.SetLocal( - node_id, context.builder().CreateNot(context.GetLocal(node.operand_id))); + inst_id, context.builder().CreateNot(context.GetLocal(inst.operand_id))); } -auto HandleVarStorage(FunctionContext& context, SemIR::NodeId node_id, - SemIR::VarStorage node) -> void { +auto HandleVarStorage(FunctionContext& context, SemIR::InstId inst_id, + SemIR::VarStorage inst) -> void { // TODO: Eventually this name will be optional, and we'll want to provide // something like `var` as a default. However, that's not possible right now // so cannot be tested. - auto name = context.sem_ir().strings().Get(node.name_id); - auto* alloca = context.builder().CreateAlloca(context.GetType(node.type_id), + auto name = context.sem_ir().strings().Get(inst.name_id); + auto* alloca = context.builder().CreateAlloca(context.GetType(inst.type_id), /*ArraySize=*/nullptr, name); - context.SetLocal(node_id, alloca); + context.SetLocal(inst_id, alloca); } } // namespace Carbon::Lower diff --git a/toolchain/lower/handle_expression_category.cpp b/toolchain/lower/handle_expression_category.cpp index 32356e81732b..520f56945df8 100644 --- a/toolchain/lower/handle_expression_category.cpp +++ b/toolchain/lower/handle_expression_category.cpp @@ -7,10 +7,10 @@ namespace Carbon::Lower { -auto HandleBindValue(FunctionContext& context, SemIR::NodeId node_id, - SemIR::BindValue node) -> void { +auto HandleBindValue(FunctionContext& context, SemIR::InstId inst_id, + SemIR::BindValue inst) -> void { switch (auto rep = - SemIR::GetValueRepresentation(context.sem_ir(), node.type_id); + SemIR::GetValueRepresentation(context.sem_ir(), inst.type_id); rep.kind) { case SemIR::ValueRepresentation::Unknown: CARBON_FATAL() @@ -19,56 +19,56 @@ auto HandleBindValue(FunctionContext& context, SemIR::NodeId node_id, // Nothing should use this value, but StubReference needs a value to // propagate. // TODO: Remove this now the StubReferences are gone. - context.SetLocal(node_id, - llvm::PoisonValue::get(context.GetType(node.type_id))); + context.SetLocal(inst_id, + llvm::PoisonValue::get(context.GetType(inst.type_id))); break; case SemIR::ValueRepresentation::Copy: - context.SetLocal(node_id, context.builder().CreateLoad( - context.GetType(node.type_id), - context.GetLocal(node.value_id))); + context.SetLocal(inst_id, context.builder().CreateLoad( + context.GetType(inst.type_id), + context.GetLocal(inst.value_id))); break; case SemIR::ValueRepresentation::Pointer: - context.SetLocal(node_id, context.GetLocal(node.value_id)); + context.SetLocal(inst_id, context.GetLocal(inst.value_id)); break; case SemIR::ValueRepresentation::Custom: CARBON_FATAL() << "TODO: Add support for BindValue with custom value rep"; } } -auto HandleTemporary(FunctionContext& context, SemIR::NodeId node_id, - SemIR::Temporary node) -> void { - context.FinishInitialization(node.type_id, node.storage_id, node.init_id); - context.SetLocal(node_id, context.GetLocal(node.storage_id)); +auto HandleTemporary(FunctionContext& context, SemIR::InstId inst_id, + SemIR::Temporary inst) -> void { + context.FinishInitialization(inst.type_id, inst.storage_id, inst.init_id); + context.SetLocal(inst_id, context.GetLocal(inst.storage_id)); } -auto HandleTemporaryStorage(FunctionContext& context, SemIR::NodeId node_id, - SemIR::TemporaryStorage node) -> void { - context.SetLocal(node_id, - context.builder().CreateAlloca(context.GetType(node.type_id), +auto HandleTemporaryStorage(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 HandleValueAsReference(FunctionContext& context, SemIR::NodeId node_id, - SemIR::ValueAsReference node) -> void { - CARBON_CHECK(SemIR::GetExpressionCategory(context.sem_ir(), node.value_id) == +auto HandleValueAsReference(FunctionContext& context, SemIR::InstId inst_id, + SemIR::ValueAsReference inst) -> void { + CARBON_CHECK(SemIR::GetExpressionCategory(context.sem_ir(), inst.value_id) == SemIR::ExpressionCategory::Value); CARBON_CHECK( - SemIR::GetValueRepresentation(context.sem_ir(), node.type_id).kind == + SemIR::GetValueRepresentation(context.sem_ir(), inst.type_id).kind == SemIR::ValueRepresentation::Pointer); - context.SetLocal(node_id, context.GetLocal(node.value_id)); + context.SetLocal(inst_id, context.GetLocal(inst.value_id)); } -auto HandleValueOfInitializer(FunctionContext& context, SemIR::NodeId node_id, - SemIR::ValueOfInitializer node) -> void { - CARBON_CHECK(SemIR::GetExpressionCategory(context.sem_ir(), node.init_id) == +auto HandleValueOfInitializer(FunctionContext& context, SemIR::InstId inst_id, + SemIR::ValueOfInitializer inst) -> void { + CARBON_CHECK(SemIR::GetExpressionCategory(context.sem_ir(), inst.init_id) == SemIR::ExpressionCategory::Initializing); CARBON_CHECK( - SemIR::GetValueRepresentation(context.sem_ir(), node.type_id).kind == + SemIR::GetValueRepresentation(context.sem_ir(), inst.type_id).kind == SemIR::ValueRepresentation::Copy); CARBON_CHECK( - SemIR::GetInitializingRepresentation(context.sem_ir(), node.type_id) + SemIR::GetInitializingRepresentation(context.sem_ir(), inst.type_id) .kind == SemIR::InitializingRepresentation::ByCopy); - context.SetLocal(node_id, context.GetLocal(node.init_id)); + context.SetLocal(inst_id, context.GetLocal(inst.init_id)); } } // namespace Carbon::Lower diff --git a/toolchain/lower/handle_type.cpp b/toolchain/lower/handle_type.cpp index 6a7dd033c6b0..5c028893f735 100644 --- a/toolchain/lower/handle_type.cpp +++ b/toolchain/lower/handle_type.cpp @@ -6,39 +6,39 @@ namespace Carbon::Lower { -auto HandleArrayType(FunctionContext& context, SemIR::NodeId node_id, - SemIR::ArrayType /*node*/) -> void { - context.SetLocal(node_id, context.GetTypeAsValue()); +auto HandleArrayType(FunctionContext& context, SemIR::InstId inst_id, + SemIR::ArrayType /*inst*/) -> void { + context.SetLocal(inst_id, context.GetTypeAsValue()); } -auto HandleClassType(FunctionContext& context, SemIR::NodeId node_id, - SemIR::ClassType /*node*/) -> void { - context.SetLocal(node_id, context.GetTypeAsValue()); +auto HandleClassType(FunctionContext& context, SemIR::InstId inst_id, + SemIR::ClassType /*inst*/) -> void { + context.SetLocal(inst_id, context.GetTypeAsValue()); } -auto HandleConstType(FunctionContext& context, SemIR::NodeId node_id, - SemIR::ConstType /*node*/) -> void { - context.SetLocal(node_id, context.GetTypeAsValue()); +auto HandleConstType(FunctionContext& context, SemIR::InstId inst_id, + SemIR::ConstType /*inst*/) -> void { + context.SetLocal(inst_id, context.GetTypeAsValue()); } -auto HandlePointerType(FunctionContext& context, SemIR::NodeId node_id, - SemIR::PointerType /*node*/) -> void { - context.SetLocal(node_id, context.GetTypeAsValue()); +auto HandlePointerType(FunctionContext& context, SemIR::InstId inst_id, + SemIR::PointerType /*inst*/) -> void { + context.SetLocal(inst_id, context.GetTypeAsValue()); } -auto HandleStructType(FunctionContext& context, SemIR::NodeId node_id, - SemIR::StructType /*node*/) -> void { - context.SetLocal(node_id, context.GetTypeAsValue()); +auto HandleStructType(FunctionContext& context, SemIR::InstId inst_id, + SemIR::StructType /*inst*/) -> void { + context.SetLocal(inst_id, context.GetTypeAsValue()); } -auto HandleTupleType(FunctionContext& context, SemIR::NodeId node_id, - SemIR::TupleType /*node*/) -> void { - context.SetLocal(node_id, context.GetTypeAsValue()); +auto HandleTupleType(FunctionContext& context, SemIR::InstId inst_id, + SemIR::TupleType /*inst*/) -> void { + context.SetLocal(inst_id, context.GetTypeAsValue()); } -auto HandleUnboundFieldType(FunctionContext& context, SemIR::NodeId node_id, - SemIR::UnboundFieldType /*node*/) -> void { - context.SetLocal(node_id, context.GetTypeAsValue()); +auto HandleUnboundFieldType(FunctionContext& context, SemIR::InstId inst_id, + SemIR::UnboundFieldType /*inst*/) -> void { + context.SetLocal(inst_id, context.GetTypeAsValue()); } } // namespace Carbon::Lower diff --git a/toolchain/sem_ir/BUILD b/toolchain/sem_ir/BUILD index 14512668f0dc..c842d22d272f 100644 --- a/toolchain/sem_ir/BUILD +++ b/toolchain/sem_ir/BUILD @@ -26,11 +26,11 @@ cc_library( ) cc_library( - name = "node_kind", + name = "inst_kind", srcs = ["node_kind.cpp"], hdrs = [ "node_kind.h", - "typed_nodes.h", + "typed_insts.h", ], textual_hdrs = ["node_kind.def"], deps = [ @@ -43,12 +43,12 @@ cc_library( ) cc_library( - name = "node", - srcs = ["node.cpp"], - hdrs = ["node.h"], + name = "inst", + srcs = ["inst.cpp"], + hdrs = ["inst.h"], deps = [ ":builtin_kind", - ":node_kind", + ":inst_kind", "//common:check", "//common:ostream", "//common:struct_reflection", @@ -64,8 +64,8 @@ cc_library( hdrs = ["file.h"], deps = [ ":builtin_kind", - ":node", - ":node_kind", + ":inst", + ":inst_kind", ":value_stores", "//common:check", "//toolchain/base:value_store", @@ -80,7 +80,7 @@ cc_library( hdrs = ["formatter.h"], deps = [ ":file", - ":node_kind", + ":inst_kind", "//toolchain/lex:tokenized_buffer", "//toolchain/parse:tree", "@llvm-project//llvm:Support", @@ -101,7 +101,7 @@ cc_library( name = "value_stores", hdrs = ["value_stores.h"], deps = [ - ":node", + ":inst", "//toolchain/base:value_store", "//toolchain/base:yaml", "@llvm-project//llvm:Support", @@ -109,12 +109,12 @@ cc_library( ) cc_test( - name = "typed_nodes_test", + name = "typed_insts_test", size = "small", srcs = ["typed_nodes_test.cpp"], deps = [ - ":node", - ":node_kind", + ":inst", + ":inst_kind", "//testing/base:gtest_main", "@com_google_googletest//:gtest", ], diff --git a/toolchain/sem_ir/builtin_kind.def b/toolchain/sem_ir/builtin_kind.def index 852f5b562aff..7345c04e4f23 100644 --- a/toolchain/sem_ir/builtin_kind.def +++ b/toolchain/sem_ir/builtin_kind.def @@ -40,7 +40,7 @@ // This has a deliberately self-referential type. CARBON_SEM_IR_BUILTIN_KIND(TypeType, "type") -// Used when a semantic error has been detected, and a SemanticNodeId is still +// Used when a semantic error has been detected, and a SemIR InstId is still // required. For example, when there is a type checking issue, this will be used // in the type_id. It's typically used as a cue that semantic checking doesn't // need to issue further diagnostics. diff --git a/toolchain/sem_ir/builtin_kind.h b/toolchain/sem_ir/builtin_kind.h index f97b97c834de..2ad9b9484198 100644 --- a/toolchain/sem_ir/builtin_kind.h +++ b/toolchain/sem_ir/builtin_kind.h @@ -30,7 +30,7 @@ class BuiltinKind : public CARBON_ENUM_BASE(BuiltinKind) { // constant. static const uint8_t ValidCount; - // Support conversion to and from an int32_t for SemanticNode storage. + // Support conversion to and from an int32_t for SemIR instruction storage. using EnumBase::AsInt; using EnumBase::FromInt; }; diff --git a/toolchain/sem_ir/file.cpp b/toolchain/sem_ir/file.cpp index a2ec88416275..f2b6c9857c41 100644 --- a/toolchain/sem_ir/file.cpp +++ b/toolchain/sem_ir/file.cpp @@ -10,7 +10,7 @@ #include "toolchain/base/value_store.h" #include "toolchain/base/yaml.h" #include "toolchain/sem_ir/builtin_kind.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/node_kind.h" namespace Carbon::SemIR { @@ -38,7 +38,7 @@ auto ValueRepresentation::Print(llvm::raw_ostream& out) const -> void { } auto TypeInfo::Print(llvm::raw_ostream& out) const -> void { - out << "{node: " << node_id << ", value_rep: " << value_representation << "}"; + out << "{inst: " << inst_id << ", value_rep: " << value_representation << "}"; } File::File(SharedValueStores& value_stores) @@ -47,25 +47,25 @@ File::File(SharedValueStores& value_stores) // Builtins are always the first IR, even when self-referential. cross_reference_irs_({this}), type_blocks_(allocator_), - node_blocks_(allocator_) { - // Default entry for NodeBlockId::Empty. - node_blocks_.AddDefaultValue(); + inst_blocks_(allocator_) { + // Default entry for InstBlockId::Empty. + inst_blocks_.AddDefaultValue(); - nodes_.Reserve(BuiltinKind::ValidCount); + insts_.Reserve(BuiltinKind::ValidCount); // Error uses a self-referential type so that it's not accidentally treated as // a normal type. Every other builtin is a type, including the // self-referential TypeType. #define CARBON_SEM_IR_BUILTIN_KIND(Name, ...) \ - nodes_.AddInNoBlock(Builtin{BuiltinKind::Name == BuiltinKind::Error \ + insts_.AddInNoBlock(Builtin{BuiltinKind::Name == BuiltinKind::Error \ ? TypeId::Error \ : TypeId::TypeType, \ BuiltinKind::Name}); #include "toolchain/sem_ir/builtin_kind.def" - CARBON_CHECK(nodes_.size() == BuiltinKind::ValidCount) + CARBON_CHECK(insts_.size() == BuiltinKind::ValidCount) << "Builtins should produce " << BuiltinKind::ValidCount - << " nodes, actual: " << nodes_.size(); + << " insts, actual: " << insts_.size(); } File::File(SharedValueStores& value_stores, std::string filename, @@ -75,21 +75,21 @@ File::File(SharedValueStores& value_stores, std::string filename, // Builtins are always the first IR. cross_reference_irs_({builtins}), type_blocks_(allocator_), - node_blocks_(allocator_) { + inst_blocks_(allocator_) { CARBON_CHECK(builtins != nullptr); CARBON_CHECK(builtins->cross_reference_irs_[0] == builtins) << "Not called with builtins!"; - // Default entry for NodeBlockId::Empty. - node_blocks_.AddDefaultValue(); + // Default entry for InstBlockId::Empty. + inst_blocks_.AddDefaultValue(); // Copy builtins over. - nodes_.Reserve(BuiltinKind::ValidCount); + insts_.Reserve(BuiltinKind::ValidCount); static constexpr auto BuiltinIR = CrossReferenceIRId(0); - for (auto [i, node] : llvm::enumerate(builtins->nodes_.array_ref())) { + for (auto [i, inst] : llvm::enumerate(builtins->insts_.array_ref())) { // We can reuse builtin type IDs because they're special-cased values. - nodes_.AddInNoBlock( - CrossReference{node.type_id(), BuiltinIR, SemIR::NodeId(i)}); + insts_.AddInNoBlock( + CrossReference{inst.type_id(), BuiltinIR, SemIR::InstId(i)}); } } @@ -102,22 +102,22 @@ auto File::Verify() const -> ErrorOr { // Check that every code block has a terminator sequence that appears at the // end of the block. for (const Function& function : functions_.array_ref()) { - for (NodeBlockId block_id : function.body_block_ids) { + for (InstBlockId block_id : function.body_block_ids) { TerminatorKind prior_kind = TerminatorKind::NotTerminator; - for (NodeId node_id : node_blocks().Get(block_id)) { - TerminatorKind node_kind = - nodes().Get(node_id).kind().terminator_kind(); + for (InstId inst_id : inst_blocks().Get(block_id)) { + TerminatorKind inst_kind = + insts().Get(inst_id).kind().terminator_kind(); if (prior_kind == TerminatorKind::Terminator) { - return Error(llvm::formatv("Node {0} in block {1} follows terminator", - node_id, block_id)); + return Error(llvm::formatv("Inst {0} in block {1} follows terminator", + inst_id, block_id)); } - if (prior_kind > node_kind) { + if (prior_kind > inst_kind) { return Error( - llvm::formatv("Non-terminator node {0} in block {1} follows " + llvm::formatv("Non-terminator inst {0} in block {1} follows " "terminator sequence", - node_id, block_id)); + inst_id, block_id)); } - prior_kind = node_kind; + prior_kind = inst_kind; } if (prior_kind != TerminatorKind::Terminator) { return Error(llvm::formatv("No terminator in block {0}", block_id)); @@ -125,8 +125,8 @@ auto File::Verify() const -> ErrorOr { } } - // TODO: Check that a node only references other nodes that are either global - // or that dominate it. + // TODO: Check that an instruction only references other instructions that are + // either global or that dominate it. return Success(); } @@ -141,25 +141,25 @@ auto File::OutputYaml(bool include_builtins) const -> Yaml::OutputMapping { map.Add("classes", classes_.OutputYaml()); map.Add("types", types_.OutputYaml()); map.Add("type_blocks", type_blocks_.OutputYaml()); - map.Add("nodes", + map.Add("insts", Yaml::OutputMapping([&](Yaml::OutputMapping::Map map) { int start = include_builtins ? 0 : BuiltinKind::ValidCount; - for (int i : llvm::seq(start, nodes_.size())) { - auto id = NodeId(i); + for (int i : llvm::seq(start, insts_.size())) { + auto id = InstId(i); map.Add(PrintToString(id), - Yaml::OutputScalar(nodes_.Get(id))); + Yaml::OutputScalar(insts_.Get(id))); } })); - map.Add("node_blocks", node_blocks_.OutputYaml()); + map.Add("inst_blocks", inst_blocks_.OutputYaml()); })); }); } -// Map a node kind representing a type into an integer describing the +// Map an instruction kind representing a type into an integer describing the // precedence of that type's syntax. Higher numbers correspond to higher // precedence. -static auto GetTypePrecedence(NodeKind kind) -> int { +static auto GetTypePrecedence(InstKind kind) -> int { // clang warns on unhandled enum values; clang-tidy is incorrect here. // NOLINTNEXTLINE(bugprone-switch-missing-default-case) switch (kind) { @@ -228,7 +228,7 @@ static auto GetTypePrecedence(NodeKind kind) -> int { case ValueAsReference::Kind: case ValueOfInitializer::Kind: case VarStorage::Kind: - CARBON_FATAL() << "GetTypePrecedence for non-type node kind " << kind; + CARBON_FATAL() << "GetTypePrecedence for non-type inst kind " << kind; } } @@ -238,47 +238,47 @@ auto File::StringifyType(TypeId type_id, bool in_type_context) const in_type_context); } -auto File::StringifyTypeExpression(NodeId outer_node_id, +auto File::StringifyTypeExpression(InstId outer_inst_id, bool in_type_context) const -> std::string { std::string str; llvm::raw_string_ostream out(str); struct Step { - // The node to print. - NodeId node_id; - // The index into node_id to print. Not used by all types. + // The instruction to print. + InstId inst_id; + // The index into inst_id to print. Not used by all types. int index = 0; auto Next() const -> Step { - return {.node_id = node_id, .index = index + 1}; + return {.inst_id = inst_id, .index = index + 1}; } }; - llvm::SmallVector steps = {{.node_id = outer_node_id}}; + llvm::SmallVector steps = {{.inst_id = outer_inst_id}}; while (!steps.empty()) { auto step = steps.pop_back_val(); - if (!step.node_id.is_valid()) { + if (!step.inst_id.is_valid()) { out << ""; continue; } // Builtins have designated labels. - if (step.node_id.index < BuiltinKind::ValidCount) { - out << BuiltinKind::FromInt(step.node_id.index).label(); + if (step.inst_id.index < BuiltinKind::ValidCount) { + out << BuiltinKind::FromInt(step.inst_id.index).label(); continue; } - auto node = nodes().Get(step.node_id); + auto inst = insts().Get(step.inst_id); // clang warns on unhandled enum values; clang-tidy is incorrect here. // NOLINTNEXTLINE(bugprone-switch-missing-default-case) - switch (node.kind()) { + switch (inst.kind()) { case ArrayType::Kind: { - auto array = node.As(); + auto array = inst.As(); if (step.index == 0) { out << "["; steps.push_back(step.Next()); steps.push_back( - {.node_id = GetTypeAllowBuiltinTypes(array.element_type_id)}); + {.inst_id = GetTypeAllowBuiltinTypes(array.element_type_id)}); } else if (step.index == 1) { out << "; " << GetArrayBoundValue(array.bound_id) << "]"; } @@ -286,7 +286,7 @@ auto File::StringifyTypeExpression(NodeId outer_node_id, } case ClassType::Kind: { auto class_name_id = - classes().Get(node.As().class_id).name_id; + classes().Get(inst.As().class_id).name_id; out << strings().Get(class_name_id); break; } @@ -295,36 +295,36 @@ auto File::StringifyTypeExpression(NodeId outer_node_id, out << "const "; // Add parentheses if required. - auto inner_type_node_id = - GetTypeAllowBuiltinTypes(node.As().inner_id); - if (GetTypePrecedence(nodes().Get(inner_type_node_id).kind()) < - GetTypePrecedence(node.kind())) { + auto inner_type_inst_id = + GetTypeAllowBuiltinTypes(inst.As().inner_id); + if (GetTypePrecedence(insts().Get(inner_type_inst_id).kind()) < + GetTypePrecedence(inst.kind())) { out << "("; steps.push_back(step.Next()); } - steps.push_back({.node_id = inner_type_node_id}); + steps.push_back({.inst_id = inner_type_inst_id}); } else if (step.index == 1) { out << ")"; } break; } case NameReference::Kind: { - out << strings().Get(node.As().name_id); + out << strings().Get(inst.As().name_id); break; } case PointerType::Kind: { if (step.index == 0) { steps.push_back(step.Next()); - steps.push_back({.node_id = GetTypeAllowBuiltinTypes( - node.As().pointee_id)}); + steps.push_back({.inst_id = GetTypeAllowBuiltinTypes( + inst.As().pointee_id)}); } else if (step.index == 1) { out << "*"; } break; } case StructType::Kind: { - auto refs = node_blocks().Get(node.As().fields_id); + auto refs = inst_blocks().Get(inst.As().fields_id); if (refs.empty()) { out << "{}"; break; @@ -338,18 +338,18 @@ auto File::StringifyTypeExpression(NodeId outer_node_id, } steps.push_back(step.Next()); - steps.push_back({.node_id = refs[step.index]}); + steps.push_back({.inst_id = refs[step.index]}); break; } case StructTypeField::Kind: { - auto field = node.As(); + auto field = inst.As(); out << "." << strings().Get(field.name_id) << ": "; steps.push_back( - {.node_id = GetTypeAllowBuiltinTypes(field.field_type_id)}); + {.inst_id = GetTypeAllowBuiltinTypes(field.field_type_id)}); break; } case TupleType::Kind: { - auto refs = type_blocks().Get(node.As().elements_id); + auto refs = type_blocks().Get(inst.As().elements_id); if (refs.empty()) { out << "()"; break; @@ -368,15 +368,15 @@ auto File::StringifyTypeExpression(NodeId outer_node_id, } steps.push_back(step.Next()); steps.push_back( - {.node_id = GetTypeAllowBuiltinTypes(refs[step.index])}); + {.inst_id = GetTypeAllowBuiltinTypes(refs[step.index])}); break; } case UnboundFieldType::Kind: { if (step.index == 0) { out << "().class_type_id)}); + steps.push_back({.inst_id = GetTypeAllowBuiltinTypes( + inst.As().class_type_id)}); } else { out << ">"; } @@ -429,10 +429,10 @@ auto File::StringifyTypeExpression(NodeId outer_node_id, case ValueAsReference::Kind: case ValueOfInitializer::Kind: case VarStorage::Kind: - // We don't need to handle stringification for nodes that don't show up - // in errors, but make it clear what's going on so that it's clearer - // when stringification is needed. - out << ""; + // We don't need to handle stringification for instructions that don't + // show up in errors, but make it clear what's going on so that it's + // clearer when stringification is needed. + out << ""; break; } } @@ -440,10 +440,10 @@ auto File::StringifyTypeExpression(NodeId outer_node_id, // For `{}` or any tuple type, we've printed a non-type expression, so add a // conversion to type `type` if it's not implied by the context. if (!in_type_context) { - auto outer_node = nodes().Get(outer_node_id); - if (outer_node.Is() || - (outer_node.Is() && - node_blocks().Get(outer_node.As().fields_id).empty())) { + auto outer_inst = insts().Get(outer_inst_id); + if (outer_inst.Is() || + (outer_inst.Is() && + inst_blocks().Get(outer_inst.As().fields_id).empty())) { out << " as type"; } } @@ -451,18 +451,19 @@ auto File::StringifyTypeExpression(NodeId outer_node_id, return str; } -auto GetExpressionCategory(const File& file, NodeId node_id) +auto GetExpressionCategory(const File& file, InstId inst_id) -> ExpressionCategory { const File* ir = &file; - // The overall expression category if the current node is a value expression. + // The overall expression category if the current instruction is a value + // expression. ExpressionCategory value_category = ExpressionCategory::Value; while (true) { - auto node = ir->nodes().Get(node_id); + auto inst = ir->insts().Get(inst_id); // clang warns on unhandled enum values; clang-tidy is incorrect here. // NOLINTNEXTLINE(bugprone-switch-missing-default-case) - switch (node.kind()) { + switch (inst.kind()) { case Assign::Kind: case Branch::Kind: case BranchIf::Kind: @@ -478,14 +479,14 @@ auto GetExpressionCategory(const File& file, NodeId node_id) return ExpressionCategory::NotExpression; case CrossReference::Kind: { - auto xref = node.As(); + auto xref = inst.As(); ir = &ir->GetCrossReferenceIR(xref.ir_id); - node_id = xref.node_id; + inst_id = xref.inst_id; continue; } case NameReference::Kind: { - node_id = node.As().value_id; + inst_id = inst.As().value_id; continue; } @@ -514,24 +515,24 @@ auto GetExpressionCategory(const File& file, NodeId node_id) return value_category; case Builtin::Kind: { - if (node.As().builtin_kind == BuiltinKind::Error) { + if (inst.As().builtin_kind == BuiltinKind::Error) { return ExpressionCategory::Error; } return value_category; } case BindName::Kind: { - node_id = node.As().value_id; + inst_id = inst.As().value_id; continue; } case ArrayIndex::Kind: { - node_id = node.As().array_id; + inst_id = inst.As().array_id; continue; } case ClassFieldAccess::Kind: { - node_id = node.As().base_id; + inst_id = inst.As().base_id; // A value of class type is a pointer to an object representation. // Therefore, if the base is a value, the result is an ephemeral // reference. @@ -540,22 +541,22 @@ auto GetExpressionCategory(const File& file, NodeId node_id) } case StructAccess::Kind: { - node_id = node.As().struct_id; + inst_id = inst.As().struct_id; continue; } case TupleAccess::Kind: { - node_id = node.As().tuple_id; + inst_id = inst.As().tuple_id; continue; } case TupleIndex::Kind: { - node_id = node.As().tuple_id; + inst_id = inst.As().tuple_id; continue; } case SpliceBlock::Kind: { - node_id = node.As().result_id; + inst_id = inst.As().result_id; continue; } diff --git a/toolchain/sem_ir/file.h b/toolchain/sem_ir/file.h index dd26f9550659..4c799bfe5bb4 100644 --- a/toolchain/sem_ir/file.h +++ b/toolchain/sem_ir/file.h @@ -11,7 +11,7 @@ #include "llvm/Support/FormatVariadic.h" #include "toolchain/base/value_store.h" #include "toolchain/base/yaml.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" #include "toolchain/sem_ir/value_stores.h" namespace Carbon::SemIR { @@ -39,11 +39,11 @@ struct Function : public Printable { StringId name_id; // The definition, if the function has been defined or is currently being // defined. This is a FunctionDeclaration. - NodeId definition_id = NodeId::Invalid; - // A block containing a single reference node per implicit parameter. - NodeBlockId implicit_param_refs_id; - // A block containing a single reference node per parameter. - NodeBlockId param_refs_id; + InstId definition_id = InstId::Invalid; + // A block containing a single reference instruction per implicit parameter. + InstBlockId implicit_param_refs_id; + // A block containing a single reference instruction per parameter. + InstBlockId param_refs_id; // The return type. This will be invalid if the return type wasn't specified. TypeId return_type_id; // The storage for the return value, which is a reference expression whose @@ -51,11 +51,11 @@ struct Function : public Printable { // doesn't have a return slot. If this is valid, a call to the function is // expected to have an additional final argument corresponding to the return // slot. - NodeId return_slot_id; + InstId return_slot_id; // A list of the statically reachable code blocks in the body of the // function, in lexical order. The first block is the entry block. This will // be empty for declarations that don't have a visible definition. - llvm::SmallVector body_block_ids = {}; + llvm::SmallVector body_block_ids = {}; }; // A class. @@ -77,17 +77,17 @@ struct Class : public Printable { // The class type, which is the type of `Self` in the class definition. TypeId self_type_id; // The first declaration of the class. This is a ClassDeclaration. - NodeId declaration_id = NodeId::Invalid; + InstId declaration_id = InstId::Invalid; // The following members are set at the `{` of the class definition. // The definition of the class. This is a ClassDeclaration. - NodeId definition_id = NodeId::Invalid; + InstId definition_id = InstId::Invalid; // The class scope. NameScopeId scope_id = NameScopeId::Invalid; // The first block of the class body. // TODO: Handle control flow in the class body, such as if-expressions. - NodeBlockId body_block_id = NodeBlockId::Invalid; + InstBlockId body_block_id = InstBlockId::Invalid; // The following members are set at the `}` of the class definition. @@ -152,8 +152,8 @@ struct ValueRepresentation : public Printable { struct TypeInfo : public Printable { auto Print(llvm::raw_ostream& out) const -> void; - // The node that defines this type. - NodeId node_id; + // The instruction that defines this type. + InstId inst_id; // The value representation for this type. Will be `Unknown` if the type is // not complete. ValueRepresentation value_representation = ValueRepresentation(); @@ -183,10 +183,10 @@ class File : public Printable { } auto OutputYaml(bool include_builtins) const -> Yaml::OutputMapping; - // Returns array bound value from the bound node. - auto GetArrayBoundValue(NodeId bound_id) const -> uint64_t { + // Returns array bound value from the bound instruction. + auto GetArrayBoundValue(InstId bound_id) const -> uint64_t { return integers() - .Get(nodes().GetAs(bound_id).integer_id) + .Get(insts().GetAs(bound_id).integer_id) .getZExtValue(); } @@ -209,15 +209,15 @@ class File : public Printable { complete_types_.push_back(object_type_id); } - auto GetTypeAllowBuiltinTypes(TypeId type_id) const -> NodeId { + auto GetTypeAllowBuiltinTypes(TypeId type_id) const -> InstId { if (type_id == TypeId::TypeType) { - return NodeId::BuiltinTypeType; + return InstId::BuiltinTypeType; } else if (type_id == TypeId::Error) { - return NodeId::BuiltinError; + return InstId::BuiltinError; } else if (type_id == TypeId::Invalid) { - return NodeId::Invalid; + return InstId::Invalid; } else { - return types().Get(type_id).node_id; + return types().Get(type_id).inst_id; } } @@ -239,8 +239,8 @@ class File : public Printable { // Gets the pointee type of the given type, which must be a pointer type. auto GetPointeeType(TypeId pointer_id) const -> TypeId { - return nodes() - .GetAs(types().Get(pointer_id).node_id) + return insts() + .GetAs(types().Get(pointer_id).inst_id) .pointee_id; } @@ -251,9 +251,9 @@ class File : public Printable { auto StringifyType(TypeId type_id, bool in_type_context = false) const -> std::string; - // Same as `StringifyType`, but starting with a node representing a type - // expression rather than a canonical type. - auto StringifyTypeExpression(NodeId outer_node_id, + // Same as `StringifyType`, but starting with an instruction representing a + // type expression rather than a canonical type. + auto StringifyTypeExpression(InstId outer_inst_id, bool in_type_context = false) const -> std::string; @@ -289,10 +289,10 @@ class File : public Printable { auto type_blocks() const -> const BlockValueStore& { return type_blocks_; } - auto nodes() -> NodeStore& { return nodes_; } - auto nodes() const -> const NodeStore& { return nodes_; } - auto node_blocks() -> NodeBlockStore& { return node_blocks_; } - auto node_blocks() const -> const NodeBlockStore& { return node_blocks_; } + auto insts() -> InstStore& { return insts_; } + auto insts() const -> const InstStore& { return insts_; } + auto inst_blocks() -> InstBlockStore& { return inst_blocks_; } + auto inst_blocks() const -> const InstBlockStore& { return inst_blocks_; } // A list of types that were completed in this file, in the order in which // they were completed. Earlier types in this list cannot contain instances of @@ -301,9 +301,9 @@ class File : public Printable { return complete_types_; } - auto top_node_block_id() const -> NodeBlockId { return top_node_block_id_; } - auto set_top_node_block_id(NodeBlockId block_id) -> void { - top_node_block_id_ = block_id; + auto top_inst_block_id() const -> InstBlockId { return top_inst_block_id_; } + auto set_top_inst_block_id(InstBlockId block_id) -> void { + top_inst_block_id_ = block_id; } // Returns true if there were errors creating the semantics IR. @@ -318,7 +318,7 @@ class File : public Printable { // Shared, compile-scoped values. SharedValueStores* value_stores_; - // Slab allocator, used to allocate node and type blocks. + // Slab allocator, used to allocate instruction and type blocks. llvm::BumpPtrAllocator allocator_; // The associated filename. @@ -333,7 +333,7 @@ class File : public Printable { // Related IRs. There will always be at least 2 entries, the builtin IR (used // for references of builtins) followed by the current IR (used for references - // crossing node blocks). + // crossing instruction blocks). llvm::SmallVector cross_reference_irs_; // Storage for name scopes. @@ -349,38 +349,40 @@ class File : public Printable { // the data is provided by allocator_. BlockValueStore type_blocks_; - // All nodes. The first entries will always be cross-references to builtins, - // at indices matching BuiltinKind ordering. - NodeStore nodes_; + // All instructions. The first entries will always be cross-references to + // builtins, at indices matching BuiltinKind ordering. + InstStore insts_; - // Node blocks within the IR. These reference entries in nodes_. Storage for - // the data is provided by allocator_. - NodeBlockStore node_blocks_; + // Instruction blocks within the IR. These reference entries in + // insts_. Storage for the data is provided by allocator_. + InstBlockStore inst_blocks_; - // The top node block ID. - NodeBlockId top_node_block_id_ = NodeBlockId::Invalid; + // The top instruction block ID. + InstBlockId top_inst_block_id_ = InstBlockId::Invalid; }; -// The expression category of a semantics node. See /docs/design/values.md for -// details. +// The expression category of a sem_ir instruction. See /docs/design/values.md +// for details. enum class ExpressionCategory : int8_t { - // This node does not correspond to an expression, and as such has no + // This instruction does not correspond to an expression, and as such has no // category. NotExpression, - // The category of this node is not known due to an error. + // The category of this instruction is not known due to an error. Error, - // This node represents a value expression. + // This instruction represents a value expression. Value, - // This node represents a durable reference expression, that denotes an + // This instruction represents a durable reference expression, that denotes an // object that outlives the current full expression context. DurableReference, - // This node represents an ephemeral reference expression, that denotes an + // This instruction represents an ephemeral reference expression, that denotes + // an // object that does not outlive the current full expression context. EphemeralReference, - // This node represents an initializing expression, that describes how to + // This instruction represents an initializing expression, that describes how + // to // initialize an object. Initializing, - // This node represents a syntactic combination of expressions that are + // This instruction represents a syntactic combination of expressions that are // permitted to have different expression categories. This is used for tuple // and struct literals, where the subexpressions for different elements can // have different categories. @@ -388,8 +390,8 @@ enum class ExpressionCategory : int8_t { Last = Mixed }; -// Returns the expression category for a node. -auto GetExpressionCategory(const File& file, NodeId node_id) +// Returns the expression category for an instruction. +auto GetExpressionCategory(const File& file, InstId inst_id) -> ExpressionCategory; // Returns information about the value representation to use for a type. diff --git a/toolchain/sem_ir/formatter.cpp b/toolchain/sem_ir/formatter.cpp index eaeb0677f2fb..e1f76c949d60 100644 --- a/toolchain/sem_ir/formatter.cpp +++ b/toolchain/sem_ir/formatter.cpp @@ -14,14 +14,14 @@ namespace Carbon::SemIR { namespace { -// Assigns names to nodes, blocks, and scopes in the Semantics IR. +// Assigns names to instructions, blocks, and scopes in the Semantics IR. // // TODOs / future work ideas: // - Add a documentation file for the textual format and link to the // naming section here. // - Consider representing literals as just `literal` in the IR and using the // type to distinguish. -class NodeNamer { +class InstNamer { public: // int32_t matches the input value size. // NOLINTNEXTLINE(performance-enum-size) @@ -31,18 +31,18 @@ class NodeNamer { }; static_assert(sizeof(ScopeIndex) == sizeof(FunctionId)); - NodeNamer(const Lex::TokenizedBuffer& tokenized_buffer, + InstNamer(const Lex::TokenizedBuffer& tokenized_buffer, const Parse::Tree& parse_tree, const File& sem_ir) : tokenized_buffer_(tokenized_buffer), parse_tree_(parse_tree), sem_ir_(sem_ir) { - nodes.resize(sem_ir.nodes().size()); - labels.resize(sem_ir.node_blocks().size()); + insts.resize(sem_ir.insts().size()); + labels.resize(sem_ir.inst_blocks().size()); scopes.resize(1 + sem_ir.functions().size() + sem_ir.classes().size()); // Build the file scope. GetScopeInfo(ScopeIndex::File).name = globals.AddNameUnchecked("file"); - CollectNamesInBlock(ScopeIndex::File, sem_ir.top_node_block_id()); + CollectNamesInBlock(ScopeIndex::File, sem_ir.top_inst_block_id()); // Build each function scope. for (auto [i, fn] : llvm::enumerate(sem_ir.functions().array_ref())) { @@ -57,10 +57,10 @@ class NodeNamer { CollectNamesInBlock(fn_scope, fn.implicit_param_refs_id); CollectNamesInBlock(fn_scope, fn.param_refs_id); if (fn.return_slot_id.is_valid()) { - nodes[fn.return_slot_id.index] = { + insts[fn.return_slot_id.index] = { fn_scope, - GetScopeInfo(fn_scope).nodes.AllocateName( - *this, sem_ir.nodes().Get(fn.return_slot_id).parse_node(), + GetScopeInfo(fn_scope).insts.AllocateName( + *this, sem_ir.insts().Get(fn.return_slot_id).parse_node(), "return")}; } if (!fn.body_block_ids.empty()) { @@ -118,30 +118,31 @@ class NodeNamer { return GetScopeInfo(GetScopeFor(class_id)).name.str(); } - // Returns the IR name to use for a node, when referenced from a given scope. - auto GetNameFor(ScopeIndex scope_idx, NodeId node_id) -> std::string { - if (!node_id.is_valid()) { + // Returns the IR name to use for an instruction, when referenced from a given + // scope. + auto GetNameFor(ScopeIndex scope_idx, InstId inst_id) -> std::string { + if (!inst_id.is_valid()) { return "invalid"; } // Check for a builtin. - if (node_id.index < BuiltinKind::ValidCount) { - return BuiltinKind::FromInt(node_id.index).label().str(); + if (inst_id.index < BuiltinKind::ValidCount) { + return BuiltinKind::FromInt(inst_id.index).label().str(); } - auto& [node_scope, node_name] = nodes[node_id.index]; - if (!node_name) { + auto& [inst_scope, inst_name] = insts[inst_id.index]; + if (!inst_name) { // This should not happen in valid IR. - return ""; + return ""; } - if (node_scope == scope_idx) { - return node_name.str().str(); + if (inst_scope == scope_idx) { + return inst_name.str().str(); } - return (GetScopeInfo(node_scope).name.str() + "." + node_name.str()).str(); + return (GetScopeInfo(inst_scope).name.str() + "." + inst_name.str()).str(); } // Returns the IR name to use for a label, when referenced from a given scope. - auto GetLabelFor(ScopeIndex scope_idx, NodeBlockId block_id) -> std::string { + auto GetLabelFor(ScopeIndex scope_idx, InstBlockId block_id) -> std::string { if (!block_id.is_valid()) { return "!invalid"; } @@ -149,7 +150,7 @@ class NodeNamer { auto& [label_scope, label_name] = labels[block_id.index]; if (!label_name) { // This should not happen in valid IR. - return ""; + return ""; } if (label_scope == scope_idx) { return label_name.str().str(); @@ -203,10 +204,10 @@ class NodeNamer { return Name(allocated.insert({name, NameResult()}).first); } - auto AllocateName(const NodeNamer& namer, Parse::Node node, + auto AllocateName(const InstNamer& namer, Parse::Node node, std::string name = "") -> Name { - // The best (shortest) name for this node so far, and the current name - // for it. + // The best (shortest) name for this instruction so far, and the current + // name for it. Name best; Name current; @@ -217,8 +218,8 @@ class NodeNamer { if (!added) { if (mark_ambiguous) { - // This name was allocated for a different node. Mark it as - // ambiguous and keep looking for a name for this node. + // This name was allocated for a different instruction. Mark it as + // ambiguous and keep looking for a name for this instruction. new_name.SetAmbiguous(); } } else { @@ -269,7 +270,7 @@ class NodeNamer { // A named scope that contains named entities. struct Scope { Namespace::Name name; - Namespace nodes = {.prefix = "%"}; + Namespace insts = {.prefix = "%"}; Namespace labels = {.prefix = "!"}; }; @@ -277,7 +278,7 @@ class NodeNamer { return scopes[static_cast(scope_idx)]; } - auto AddBlockLabel(ScopeIndex scope_idx, NodeBlockId block_id, + auto AddBlockLabel(ScopeIndex scope_idx, InstBlockId block_id, std::string name = "", Parse::Node parse_node = Parse::Node::Invalid) -> void { if (!block_id.is_valid() || labels[block_id.index].second) { @@ -285,9 +286,9 @@ class NodeNamer { } if (parse_node == Parse::Node::Invalid) { - if (const auto& block = sem_ir_.node_blocks().Get(block_id); + if (const auto& block = sem_ir_.inst_blocks().Get(block_id); !block.empty()) { - parse_node = sem_ir_.nodes().Get(block.front()).parse_node(); + parse_node = sem_ir_.insts().Get(block.front()).parse_node(); } } @@ -296,14 +297,14 @@ class NodeNamer { *this, parse_node, std::move(name))}; } - // Finds and adds a suitable block label for the given semantics node that + // Finds and adds a suitable block label for the given SemIR instruction that // represents some kind of branch. - auto AddBlockLabel(ScopeIndex scope_idx, NodeBlockId block_id, Node node) + auto AddBlockLabel(ScopeIndex scope_idx, InstBlockId block_id, Inst inst) -> void { llvm::StringRef name; - switch (parse_tree_.node_kind(node.parse_node())) { + switch (parse_tree_.node_kind(inst.parse_node())) { case Parse::NodeKind::IfExpressionIf: - switch (node.kind()) { + switch (inst.kind()) { case BranchIf::Kind: name = "if.expr.then"; break; @@ -319,7 +320,7 @@ class NodeNamer { break; case Parse::NodeKind::IfCondition: - switch (node.kind()) { + switch (inst.kind()) { case BranchIf::Kind: name = "if.then"; break; @@ -336,9 +337,9 @@ class NodeNamer { break; case Parse::NodeKind::ShortCircuitOperand: { - bool is_rhs = node.Is(); + bool is_rhs = inst.Is(); bool is_and = tokenized_buffer_.GetKind(parse_tree_.node_token( - node.parse_node())) == Lex::TokenKind::And; + inst.parse_node())) == Lex::TokenKind::And; name = is_and ? (is_rhs ? "and.rhs" : "and.result") : (is_rhs ? "or.rhs" : "or.result"); break; @@ -349,11 +350,11 @@ class NodeNamer { break; case Parse::NodeKind::WhileCondition: - switch (node.kind()) { - case NodeKind::BranchIf: + switch (inst.kind()) { + case InstKind::BranchIf: name = "while.body"; break; - case NodeKind::Branch: + case InstKind::Branch: name = "while.done"; break; default: @@ -365,10 +366,10 @@ class NodeNamer { break; } - AddBlockLabel(scope_idx, block_id, name.str(), node.parse_node()); + AddBlockLabel(scope_idx, block_id, name.str(), inst.parse_node()); } - auto CollectNamesInBlock(ScopeIndex scope_idx, NodeBlockId block_id) -> void { + auto CollectNamesInBlock(ScopeIndex scope_idx, InstBlockId block_id) -> void { if (!block_id.is_valid()) { return; } @@ -376,73 +377,73 @@ class NodeNamer { Scope& scope = GetScopeInfo(scope_idx); // Use bound names where available. Otherwise, assign a backup name. - for (auto node_id : sem_ir_.node_blocks().Get(block_id)) { - if (!node_id.is_valid()) { + for (auto inst_id : sem_ir_.inst_blocks().Get(block_id)) { + if (!inst_id.is_valid()) { continue; } - auto node = sem_ir_.nodes().Get(node_id); - auto add_node_name = [&](std::string name) { - nodes[node_id.index] = {scope_idx, scope.nodes.AllocateName( - *this, node.parse_node(), name)}; + auto inst = sem_ir_.insts().Get(inst_id); + auto add_inst_name = [&](std::string name) { + insts[inst_id.index] = {scope_idx, scope.insts.AllocateName( + *this, inst.parse_node(), name)}; }; - auto add_node_name_id = [&](StringId name_id, + auto add_inst_name_id = [&](StringId name_id, llvm::StringRef suffix = "") { if (name_id.is_valid()) { - add_node_name((sem_ir_.strings().Get(name_id).str() + suffix).str()); + add_inst_name((sem_ir_.strings().Get(name_id).str() + suffix).str()); } else { - add_node_name(suffix.str()); + add_inst_name(suffix.str()); } }; - switch (node.kind()) { + switch (inst.kind()) { case Branch::Kind: { - AddBlockLabel(scope_idx, node.As().target_id, node); + AddBlockLabel(scope_idx, inst.As().target_id, inst); break; } case BranchIf::Kind: { - AddBlockLabel(scope_idx, node.As().target_id, node); + AddBlockLabel(scope_idx, inst.As().target_id, inst); break; } case BranchWithArg::Kind: { - AddBlockLabel(scope_idx, node.As().target_id, node); + AddBlockLabel(scope_idx, inst.As().target_id, inst); break; } case SpliceBlock::Kind: { - CollectNamesInBlock(scope_idx, node.As().block_id); + CollectNamesInBlock(scope_idx, inst.As().block_id); break; } case BindName::Kind: { - add_node_name_id(node.As().name_id); + add_inst_name_id(inst.As().name_id); continue; } case FunctionDeclaration::Kind: { - add_node_name_id(sem_ir_.functions() - .Get(node.As().function_id) + add_inst_name_id(sem_ir_.functions() + .Get(inst.As().function_id) .name_id); continue; } case ClassType::Kind: { - add_node_name_id( - sem_ir_.classes().Get(node.As().class_id).name_id); + add_inst_name_id( + sem_ir_.classes().Get(inst.As().class_id).name_id); continue; } case NameReference::Kind: { - add_node_name_id(node.As().name_id, ".ref"); + add_inst_name_id(inst.As().name_id, ".ref"); continue; } case Parameter::Kind: { - add_node_name_id(node.As().name_id); + add_inst_name_id(inst.As().name_id); continue; } case SelfParameter::Kind: { - add_node_name(node.As().is_addr_self.index + add_inst_name(inst.As().is_addr_self.index ? "self.addr" : "self"); continue; } case VarStorage::Kind: { - add_node_name_id(node.As().name_id, ".var"); + add_inst_name_id(inst.As().name_id, ".var"); continue; } default: { @@ -451,8 +452,8 @@ class NodeNamer { } // Sequentially number all remaining values. - if (node.kind().value_kind() != NodeValueKind::None) { - add_node_name(""); + if (inst.kind().value_kind() != InstValueKind::None) { + add_inst_name(""); } } } @@ -462,7 +463,7 @@ class NodeNamer { const File& sem_ir_; Namespace globals = {.prefix = "@"}; - std::vector> nodes; + std::vector> insts; std::vector> labels; std::vector scopes; }; @@ -476,17 +477,17 @@ class Formatter { llvm::raw_ostream& out) : sem_ir_(sem_ir), out_(out), - node_namer_(tokenized_buffer, parse_tree, sem_ir) {} + inst_namer_(tokenized_buffer, parse_tree, sem_ir) {} auto Format() -> void { out_ << "file \"" << sem_ir_.filename() << "\" {\n"; // TODO: Include information from the `package` declaration, once we // fully support it. - // TODO: Handle the case where there are multiple top-level node blocks. - // For example, there may be branching in the initializer of a global or a - // type expression. - if (auto block_id = sem_ir_.top_node_block_id(); block_id.is_valid()) { - llvm::SaveAndRestore file_scope(scope_, NodeNamer::ScopeIndex::File); + // TODO: Handle the case where there are multiple top-level instruction + // blocks. For example, there may be branching in the initializer of a + // global or a type expression. + if (auto block_id = sem_ir_.top_inst_block_id(); block_id.is_valid()) { + llvm::SaveAndRestore file_scope(scope_, InstNamer::ScopeIndex::File); FormatCodeBlock(block_id); } out_ << "}\n"; @@ -506,7 +507,7 @@ class Formatter { out_ << "\nclass "; FormatClassName(id); - llvm::SaveAndRestore class_scope(scope_, node_namer_.GetScopeFor(id)); + llvm::SaveAndRestore class_scope(scope_, inst_namer_.GetScopeFor(id)); if (class_info.scope_id.is_valid()) { out_ << " {\n"; @@ -525,9 +526,9 @@ class Formatter { out_ << "\nfn "; FormatFunctionName(id); - llvm::SaveAndRestore function_scope(scope_, node_namer_.GetScopeFor(id)); + llvm::SaveAndRestore function_scope(scope_, inst_namer_.GetScopeFor(id)); - if (fn.implicit_param_refs_id != SemIR::NodeBlockId::Empty) { + if (fn.implicit_param_refs_id != SemIR::InstBlockId::Empty) { out_ << "["; FormatParameterList(fn.implicit_param_refs_id); out_ << "]"; @@ -540,7 +541,7 @@ class Formatter { if (fn.return_type_id.is_valid()) { out_ << " -> "; if (fn.return_slot_id.is_valid()) { - FormatNodeName(fn.return_slot_id); + FormatInstName(fn.return_slot_id); out_ << ": "; } FormatType(fn.return_type_id); @@ -564,27 +565,27 @@ class Formatter { } } - auto FormatParameterList(NodeBlockId param_refs_id) -> void { + auto FormatParameterList(InstBlockId param_refs_id) -> void { llvm::ListSeparator sep; - for (const NodeId param_id : sem_ir_.node_blocks().Get(param_refs_id)) { + for (const InstId param_id : sem_ir_.inst_blocks().Get(param_refs_id)) { out_ << sep; if (!param_id.is_valid()) { out_ << "invalid"; continue; } - FormatNodeName(param_id); + FormatInstName(param_id); out_ << ": "; - FormatType(sem_ir_.nodes().Get(param_id).type_id()); + FormatType(sem_ir_.insts().Get(param_id).type_id()); } } - auto FormatCodeBlock(NodeBlockId block_id) -> void { + auto FormatCodeBlock(InstBlockId block_id) -> void { if (!block_id.is_valid()) { return; } - for (const NodeId node_id : sem_ir_.node_blocks().Get(block_id)) { - FormatInstruction(node_id); + for (const InstId inst_id : sem_ir_.inst_blocks().Get(block_id)) { + FormatInstruction(inst_id); } } @@ -592,39 +593,39 @@ class Formatter { llvm::StringRef prefix) -> void { // Name scopes aren't kept in any particular order. Sort the entries before // we print them for stability and consistency. - llvm::SmallVector> entries; - for (auto [name_id, node_id] : sem_ir_.name_scopes().Get(id)) { - entries.push_back({node_id, name_id}); + llvm::SmallVector> entries; + for (auto [name_id, inst_id] : sem_ir_.name_scopes().Get(id)) { + entries.push_back({inst_id, name_id}); } llvm::sort(entries, [](auto a, auto b) { return a.first.index < b.first.index; }); llvm::ListSeparator sep(separator); - for (auto [node_id, name_id] : entries) { + for (auto [inst_id, name_id] : entries) { out_ << sep << prefix; FormatString(name_id); out_ << " = "; - FormatNodeName(node_id); + FormatInstName(inst_id); } } - auto FormatInstruction(NodeId node_id) -> void { - if (!node_id.is_valid()) { + auto FormatInstruction(InstId inst_id) -> void { + if (!inst_id.is_valid()) { Indent(); out_ << "invalid\n"; return; } - FormatInstruction(node_id, sem_ir_.nodes().Get(node_id)); + FormatInstruction(inst_id, sem_ir_.insts().Get(inst_id)); } - auto FormatInstruction(NodeId node_id, Node node) -> void { + auto FormatInstruction(InstId inst_id, Inst inst) -> void { // clang warns on unhandled enum values; clang-tidy is incorrect here. // NOLINTNEXTLINE(bugprone-switch-missing-default-case) - switch (node.kind()) { -#define CARBON_SEM_IR_NODE_KIND(NodeT) \ - case NodeT::Kind: \ - FormatInstruction(node_id, node.As()); \ + switch (inst.kind()) { +#define CARBON_SEM_IR_INST_KIND(InstT) \ + case InstT::Kind: \ + FormatInstruction(inst_id, inst.As()); \ break; #include "toolchain/sem_ir/node_kind.def" } @@ -632,21 +633,21 @@ class Formatter { auto Indent() -> void { out_.indent(indent_); } - template - auto FormatInstruction(NodeId node_id, NodeT node) -> void { + template + auto FormatInstruction(InstId inst_id, InstT inst) -> void { Indent(); - FormatInstructionLHS(node_id, node); - out_ << NodeT::Kind.ir_name(); - FormatInstructionRHS(node); + FormatInstructionLHS(inst_id, inst); + out_ << InstT::Kind.ir_name(); + FormatInstructionRHS(inst); out_ << "\n"; } - auto FormatInstructionLHS(NodeId node_id, Node node) -> void { - switch (node.kind().value_kind()) { - case NodeValueKind::Typed: - FormatNodeName(node_id); + auto FormatInstructionLHS(InstId inst_id, Inst inst) -> void { + switch (inst.kind().value_kind()) { + case InstValueKind::Typed: + FormatInstName(inst_id); out_ << ": "; - switch (GetExpressionCategory(sem_ir_, node_id)) { + switch (GetExpressionCategory(sem_ir_, inst_id)) { case ExpressionCategory::NotExpression: case ExpressionCategory::Error: case ExpressionCategory::Value: @@ -660,99 +661,99 @@ class Formatter { out_ << "init "; break; } - FormatType(node.type_id()); + FormatType(inst.type_id()); out_ << " = "; break; - case NodeValueKind::None: + case InstValueKind::None: break; } } - template - auto FormatInstructionRHS(NodeT node) -> void { + template + auto FormatInstructionRHS(InstT inst) -> void { // By default, an instruction has a comma-separated argument list. - using Info = TypedNodeArgsInfo; + using Info = TypedInstArgsInfo; if constexpr (Info::NumArgs == 2) { - FormatArgs(Info::template Get<0>(node), Info::template Get<1>(node)); + FormatArgs(Info::template Get<0>(inst), Info::template Get<1>(inst)); } else if constexpr (Info::NumArgs == 1) { - FormatArgs(Info::template Get<0>(node)); + FormatArgs(Info::template Get<0>(inst)); } else { FormatArgs(); } } - auto FormatInstructionRHS(BlockArg node) -> void { + auto FormatInstructionRHS(BlockArg inst) -> void { out_ << " "; - FormatLabel(node.block_id); + FormatLabel(inst.block_id); } - auto FormatInstruction(NodeId /*node_id*/, BranchIf node) -> void { + auto FormatInstruction(InstId /*inst_id*/, BranchIf inst) -> void { if (!in_terminator_sequence_) { Indent(); } out_ << "if "; - FormatNodeName(node.cond_id); + FormatInstName(inst.cond_id); out_ << " " << Branch::Kind.ir_name() << " "; - FormatLabel(node.target_id); + FormatLabel(inst.target_id); out_ << " else "; in_terminator_sequence_ = true; } - auto FormatInstruction(NodeId /*node_id*/, BranchWithArg node) -> void { + auto FormatInstruction(InstId /*inst_id*/, BranchWithArg inst) -> void { if (!in_terminator_sequence_) { Indent(); } out_ << BranchWithArg::Kind.ir_name() << " "; - FormatLabel(node.target_id); + FormatLabel(inst.target_id); out_ << "("; - FormatNodeName(node.arg_id); + FormatInstName(inst.arg_id); out_ << ")\n"; in_terminator_sequence_ = false; } - auto FormatInstruction(NodeId /*node_id*/, Branch node) -> void { + auto FormatInstruction(InstId /*inst_id*/, Branch inst) -> void { if (!in_terminator_sequence_) { Indent(); } out_ << Branch::Kind.ir_name() << " "; - FormatLabel(node.target_id); + FormatLabel(inst.target_id); out_ << "\n"; in_terminator_sequence_ = false; } - auto FormatInstructionRHS(ArrayInit node) -> void { + auto FormatInstructionRHS(ArrayInit inst) -> void { out_ << " "; - FormatArg(node.tuple_id); + FormatArg(inst.tuple_id); - llvm::ArrayRef inits_and_return_slot = - sem_ir_.node_blocks().Get(node.inits_and_return_slot_id); + llvm::ArrayRef inits_and_return_slot = + sem_ir_.inst_blocks().Get(inst.inits_and_return_slot_id); auto inits = inits_and_return_slot.drop_back(1); auto return_slot_id = inits_and_return_slot.back(); out_ << ", ("; llvm::ListSeparator sep; - for (auto node_id : inits) { + for (auto inst_id : inits) { out_ << sep; - FormatArg(node_id); + FormatArg(inst_id); } out_ << ')'; FormatReturnSlot(return_slot_id); } - auto FormatInstructionRHS(Call node) -> void { + auto FormatInstructionRHS(Call inst) -> void { out_ << " "; - FormatArg(node.callee_id); + FormatArg(inst.callee_id); - if (!node.args_id.is_valid()) { + if (!inst.args_id.is_valid()) { out_ << "()"; return; } - llvm::ArrayRef args = sem_ir_.node_blocks().Get(node.args_id); + llvm::ArrayRef args = sem_ir_.inst_blocks().Get(inst.args_id); bool has_return_slot = - GetInitializingRepresentation(sem_ir_, node.type_id).has_return_slot(); - NodeId return_slot_id = NodeId::Invalid; + GetInitializingRepresentation(sem_ir_, inst.type_id).has_return_slot(); + InstId return_slot_id = InstId::Invalid; if (has_return_slot) { return_slot_id = args.back(); args = args.drop_back(); @@ -760,9 +761,9 @@ class Formatter { llvm::ListSeparator sep; out_ << '('; - for (auto node_id : args) { + for (auto inst_id : args) { out_ << sep; - FormatArg(node_id); + FormatArg(inst_id); } out_ << ')'; @@ -771,24 +772,24 @@ class Formatter { } } - auto FormatInstructionRHS(InitializeFrom node) -> void { - FormatArgs(node.src_id); - FormatReturnSlot(node.dest_id); + auto FormatInstructionRHS(InitializeFrom inst) -> void { + FormatArgs(inst.src_id); + FormatReturnSlot(inst.dest_id); } - auto FormatInstructionRHS(CrossReference node) -> void { + auto FormatInstructionRHS(CrossReference inst) -> void { // TODO: Figure out a way to make this meaningful. We'll need some way to - // name cross-reference IRs, perhaps by the node ID of the import? - out_ << " " << node.ir_id << "." << node.node_id; + // name cross-reference IRs, perhaps by the instruction ID of the import? + out_ << " " << inst.ir_id << "." << inst.inst_id; } - auto FormatInstructionRHS(SpliceBlock node) -> void { - FormatArgs(node.result_id); + auto FormatInstructionRHS(SpliceBlock inst) -> void { + FormatArgs(inst.result_id); out_ << " {"; - if (!sem_ir_.node_blocks().Get(node.block_id).empty()) { + if (!sem_ir_.inst_blocks().Get(inst.block_id).empty()) { out_ << "\n"; indent_ += 2; - FormatCodeBlock(node.block_id); + FormatCodeBlock(inst.block_id); indent_ -= 2; Indent(); } @@ -796,15 +797,15 @@ class Formatter { } // StructTypeFields are formatted as part of their StructType. - auto FormatInstruction(NodeId /*node_id*/, StructTypeField /*node*/) -> void { + auto FormatInstruction(InstId /*inst_id*/, StructTypeField /*inst*/) -> void { } - auto FormatInstructionRHS(StructType node) -> void { + auto FormatInstructionRHS(StructType inst) -> void { out_ << " {"; llvm::ListSeparator sep; - for (auto field_id : sem_ir_.node_blocks().Get(node.fields_id)) { + for (auto field_id : sem_ir_.inst_blocks().Get(inst.fields_id)) { out_ << sep << "."; - auto field = sem_ir_.nodes().GetAs(field_id); + auto field = sem_ir_.insts().GetAs(field_id); FormatString(field.name_id); out_ << ": "; FormatType(field.field_type_id); @@ -841,14 +842,14 @@ class Formatter { out_ << '}'; } - auto FormatArg(NodeId id) -> void { FormatNodeName(id); } + auto FormatArg(InstId id) -> void { FormatInstName(id); } - auto FormatArg(NodeBlockId id) -> void { + auto FormatArg(InstBlockId id) -> void { out_ << '('; llvm::ListSeparator sep; - for (auto node_id : sem_ir_.node_blocks().Get(id)) { + for (auto inst_id : sem_ir_.inst_blocks().Get(id)) { out_ << sep; - FormatArg(node_id); + FormatArg(inst_id); } out_ << ')'; } @@ -878,27 +879,27 @@ class Formatter { out_ << ')'; } - auto FormatReturnSlot(NodeId dest_id) -> void { + auto FormatReturnSlot(InstId dest_id) -> void { out_ << " to "; FormatArg(dest_id); } - auto FormatNodeName(NodeId id) -> void { - out_ << node_namer_.GetNameFor(scope_, id); + auto FormatInstName(InstId id) -> void { + out_ << inst_namer_.GetNameFor(scope_, id); } - auto FormatLabel(NodeBlockId id) -> void { - out_ << node_namer_.GetLabelFor(scope_, id); + auto FormatLabel(InstBlockId id) -> void { + out_ << inst_namer_.GetLabelFor(scope_, id); } auto FormatString(StringId id) -> void { out_ << sem_ir_.strings().Get(id); } auto FormatFunctionName(FunctionId id) -> void { - out_ << node_namer_.GetNameFor(id); + out_ << inst_namer_.GetNameFor(id); } auto FormatClassName(ClassId id) -> void { - out_ << node_namer_.GetNameFor(id); + out_ << inst_namer_.GetNameFor(id); } auto FormatType(TypeId id) -> void { @@ -912,8 +913,8 @@ class Formatter { private: const File& sem_ir_; llvm::raw_ostream& out_; - NodeNamer node_namer_; - NodeNamer::ScopeIndex scope_ = NodeNamer::ScopeIndex::None; + InstNamer inst_namer_; + InstNamer::ScopeIndex scope_ = InstNamer::ScopeIndex::None; bool in_terminator_sequence_ = false; int indent_ = 2; }; diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index 60064a89e8fb..046be5c0c578 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -14,24 +14,24 @@ namespace Carbon::SemIR { -// The ID of a node. -struct NodeId : public IndexBase, public Printable { - // An explicitly invalid node ID. - static const NodeId Invalid; +// The ID of an instruction. +struct InstId : public IndexBase, public Printable { + // An explicitly invalid instruction ID. + static const InstId Invalid; -// Builtin node IDs. -#define CARBON_SEM_IR_BUILTIN_KIND_NAME(Name) static const NodeId Builtin##Name; +// Builtin instruction IDs. +#define CARBON_SEM_IR_BUILTIN_KIND_NAME(Name) static const InstId Builtin##Name; #include "toolchain/sem_ir/builtin_kind.def" - // Returns the cross-reference node ID for a builtin. This relies on File - // guarantees for builtin cross-reference placement. - static constexpr auto ForBuiltin(BuiltinKind kind) -> NodeId { - return NodeId(kind.AsInt()); + // Returns the cross-reference instruction ID for a builtin. This relies on + // File guarantees for builtin cross-reference placement. + static constexpr auto ForBuiltin(BuiltinKind kind) -> InstId { + return InstId(kind.AsInt()); } using IndexBase::IndexBase; auto Print(llvm::raw_ostream& out) const -> void { - out << "node"; + out << "inst"; if (!is_valid()) { IndexBase::Print(out); } else if (index < BuiltinKind::ValidCount) { @@ -44,11 +44,11 @@ struct NodeId : public IndexBase, public Printable { } }; -constexpr NodeId NodeId::Invalid = NodeId(NodeId::InvalidIndex); +constexpr InstId InstId::Invalid = InstId(InstId::InvalidIndex); #define CARBON_SEM_IR_BUILTIN_KIND_NAME(Name) \ - constexpr NodeId NodeId::Builtin##Name = \ - NodeId::ForBuiltin(BuiltinKind::Name); + constexpr InstId InstId::Builtin##Name = \ + InstId::ForBuiltin(BuiltinKind::Name); #include "toolchain/sem_ir/builtin_kind.def" // The ID of a function. @@ -127,16 +127,16 @@ struct NameScopeId : public IndexBase, public Printable { constexpr NameScopeId NameScopeId::Invalid = NameScopeId(NameScopeId::InvalidIndex); -// The ID of a node block. -struct NodeBlockId : public IndexBase, public Printable { - // All File instances must provide the 0th node block as empty. - static const NodeBlockId Empty; +// The ID of an instruction block. +struct InstBlockId : public IndexBase, public Printable { + // All File instances must provide the 0th instruction block as empty. + static const InstBlockId Empty; // An explicitly invalid ID. - static const NodeBlockId Invalid; + static const InstBlockId Invalid; // An ID for unreachable code. - static const NodeBlockId Unreachable; + static const InstBlockId Unreachable; using IndexBase::IndexBase; auto Print(llvm::raw_ostream& out) const -> void { @@ -149,13 +149,13 @@ struct NodeBlockId : public IndexBase, public Printable { } }; -constexpr NodeBlockId NodeBlockId::Empty = NodeBlockId(0); -constexpr NodeBlockId NodeBlockId::Invalid = - NodeBlockId(NodeBlockId::InvalidIndex); -constexpr NodeBlockId NodeBlockId::Unreachable = - NodeBlockId(NodeBlockId::InvalidIndex - 1); +constexpr InstBlockId InstBlockId::Empty = InstBlockId(0); +constexpr InstBlockId InstBlockId::Invalid = + InstBlockId(InstBlockId::InvalidIndex); +constexpr InstBlockId InstBlockId::Unreachable = + InstBlockId(InstBlockId::InvalidIndex - 1); -// The ID of a node block. +// The ID of a type. struct TypeId : public IndexBase, public Printable { // The builtin TypeType. static const TypeId TypeType; @@ -205,10 +205,10 @@ struct MemberIndex : public IndexBase, public Printable { // Support use of Id types as DenseMap/DenseSet keys. template <> -struct llvm::DenseMapInfo - : public Carbon::IndexMapInfo {}; +struct llvm::DenseMapInfo + : public Carbon::IndexMapInfo {}; template <> -struct llvm::DenseMapInfo - : public Carbon::IndexMapInfo {}; +struct llvm::DenseMapInfo + : public Carbon::IndexMapInfo {}; #endif // CARBON_TOOLCHAIN_SEM_IR_IDS_H_ diff --git a/toolchain/sem_ir/node.cpp b/toolchain/sem_ir/inst.cpp similarity index 83% rename from toolchain/sem_ir/node.cpp rename to toolchain/sem_ir/inst.cpp index 746aea8d289c..11ec5864b705 100644 --- a/toolchain/sem_ir/node.cpp +++ b/toolchain/sem_ir/inst.cpp @@ -2,11 +2,11 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::SemIR { -auto Node::Print(llvm::raw_ostream& out) const -> void { +auto Inst::Print(llvm::raw_ostream& out) const -> void { out << "{kind: " << kind_; auto print_args = [&](auto info) { @@ -22,9 +22,9 @@ auto Node::Print(llvm::raw_ostream& out) const -> void { // clang warns on unhandled enum values; clang-tidy is incorrect here. // NOLINTNEXTLINE(bugprone-switch-missing-default-case) switch (kind_) { -#define CARBON_SEM_IR_NODE_KIND(Name) \ +#define CARBON_SEM_IR_INST_KIND(Name) \ case Name::Kind: \ - print_args(TypedNodeArgsInfo()); \ + print_args(TypedInstArgsInfo()); \ break; #include "toolchain/sem_ir/node_kind.def" } diff --git a/toolchain/sem_ir/node.h b/toolchain/sem_ir/inst.h similarity index 51% rename from toolchain/sem_ir/node.h rename to toolchain/sem_ir/inst.h index 9881506c425b..3873d47d8aa0 100644 --- a/toolchain/sem_ir/node.h +++ b/toolchain/sem_ir/inst.h @@ -2,8 +2,8 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#ifndef CARBON_TOOLCHAIN_SEM_IR_NODE_H_ -#define CARBON_TOOLCHAIN_SEM_IR_NODE_H_ +#ifndef CARBON_TOOLCHAIN_SEM_IR_INST_H_ +#define CARBON_TOOLCHAIN_SEM_IR_INST_H_ #include @@ -14,98 +14,101 @@ #include "toolchain/parse/tree.h" #include "toolchain/sem_ir/builtin_kind.h" #include "toolchain/sem_ir/node_kind.h" -#include "toolchain/sem_ir/typed_nodes.h" +#include "toolchain/sem_ir/typed_insts.h" namespace Carbon::SemIR { -// Data about the arguments of a typed node, to aid in type erasure. The `KindT` -// parameter is used to check that `TypedNode` is a typed node. -template -struct TypedNodeArgsInfo { +// Data about the arguments of a typed instruction, to aid in type erasure. The +// `KindT` parameter is used to check that `TypedInst` is a typed instruction. +template +struct TypedInstArgsInfo { // A corresponding std::tuple<...> type. - using Tuple = decltype(StructReflection::AsTuple(std::declval())); + using Tuple = decltype(StructReflection::AsTuple(std::declval())); static constexpr int FirstArgField = - HasParseNode + HasTypeId; + HasParseNode + HasTypeId; static constexpr int NumArgs = std::tuple_size_v - FirstArgField; static_assert(NumArgs <= 2, - "Unsupported: typed node has more than two data fields"); + "Unsupported: typed inst has more than two data fields"); template using ArgType = std::tuple_element_t; template - static auto Get(TypedNode node) -> ArgType { - return std::get(StructReflection::AsTuple(node)); + static auto Get(TypedInst inst) -> ArgType { + return std::get(StructReflection::AsTuple(inst)); } }; -// A type-erased representation of a SemIR node, that may be constructed from -// the specific kinds of node defined in `typed_nodes.h`. This provides access -// to common fields present on most or all kinds of nodes: +// A type-erased representation of a SemIR instruction, that may be constructed +// from the specific kinds of instruction defined in `typed_insts.h`. This +// provides access to common fields present on most or all kinds of +// instructions: // // - `parse_node` for error placement. // - `kind` for run-time logic when the input Kind is unknown. // - `type_id` for quick type checking. // // In addition, kind-specific data can be accessed by casting to the specific -// kind of node: +// kind of instruction: // -// - Use `node.kind()` or `Is` to determine what kind of node it is. -// - Cast to a specific type using `node.As()` -// - Using the wrong kind in `node.As()` is a programming error, +// - Use `inst.kind()` or `Is` to determine what kind of instruction +// it is. +// - Cast to a specific type using `inst.As()` +// - Using the wrong kind in `inst.As()` is a programming error, // and will CHECK-fail in debug modes (opt may too, but it's not an API // guarantee). -// - Use `node.TryAs()` to safely access type-specific node data -// where the node's kind is not known. -class Node : public Printable { +// - Use `inst.TryAs()` to safely access type-specific instruction +// data +// where the instruction's kind is not known. +class Inst : public Printable { public: - template > + template > // NOLINTNEXTLINE(google-explicit-constructor) - Node(TypedNode typed_node) + Inst(TypedInst typed_inst) : parse_node_(Parse::Node::Invalid), - kind_(TypedNode::Kind), + kind_(TypedInst::Kind), type_id_(TypeId::Invalid), - arg0_(NodeId::InvalidIndex), - arg1_(NodeId::InvalidIndex) { - if constexpr (HasParseNode) { - parse_node_ = typed_node.parse_node; + arg0_(InstId::InvalidIndex), + arg1_(InstId::InvalidIndex) { + if constexpr (HasParseNode) { + parse_node_ = typed_inst.parse_node; } - if constexpr (HasTypeId) { - type_id_ = typed_node.type_id; + if constexpr (HasTypeId) { + type_id_ = typed_inst.type_id; } if constexpr (Info::NumArgs > 0) { - arg0_ = ToRaw(Info::template Get<0>(typed_node)); + arg0_ = ToRaw(Info::template Get<0>(typed_inst)); } if constexpr (Info::NumArgs > 1) { - arg1_ = ToRaw(Info::template Get<1>(typed_node)); + arg1_ = ToRaw(Info::template Get<1>(typed_inst)); } } - // Returns whether this node has the specified type. - template + // Returns whether this instruction has the specified type. + template auto Is() const -> bool { - return kind() == TypedNode::Kind; + return kind() == TypedInst::Kind; } - // Casts this node to the given typed node, which must match the node's kind, - // and returns the typed node. - template > - auto As() const -> TypedNode { - CARBON_CHECK(Is()) << "Casting node of kind " << kind() - << " to wrong kind " << TypedNode::Kind; + // Casts this instruction to the given typed instruction, which must match the + // instruction's kind, and returns the typed instruction. + template > + auto As() const -> TypedInst { + CARBON_CHECK(Is()) << "Casting inst of kind " << kind() + << " to wrong kind " << TypedInst::Kind; auto build_with_type_id_and_args = [&](auto... type_id_and_args) { - if constexpr (HasParseNode) { - return TypedNode{parse_node(), type_id_and_args...}; + if constexpr (HasParseNode) { + return TypedInst{parse_node(), type_id_and_args...}; } else { - return TypedNode{type_id_and_args...}; + return TypedInst{type_id_and_args...}; } }; auto build_with_args = [&](auto... args) { - if constexpr (HasTypeId) { + if constexpr (HasTypeId) { return build_with_type_id_and_args(type_id(), args...); } else { return build_with_type_id_and_args(args...); @@ -124,30 +127,30 @@ class Node : public Printable { } } - // If this node is the given kind, returns a typed node, otherwise returns - // nullopt. - template - auto TryAs() const -> std::optional { - if (Is()) { - return As(); + // If this instruction is the given kind, returns a typed instruction, + // otherwise returns nullopt. + template + auto TryAs() const -> std::optional { + if (Is()) { + return As(); } else { return std::nullopt; } } auto parse_node() const -> Parse::Node { return parse_node_; } - auto kind() const -> NodeKind { return kind_; } + auto kind() const -> InstKind { return kind_; } - // Gets the type of the value produced by evaluating this node. + // Gets the type of the value produced by evaluating this instruction. auto type_id() const -> TypeId { return type_id_; } auto Print(llvm::raw_ostream& out) const -> void; private: - friend class NodeTestHelper; + friend class InstTestHelper; // Raw constructor, used for testing. - explicit Node(NodeKind kind, Parse::Node parse_node, TypeId type_id, + explicit Inst(InstKind kind, Parse::Node parse_node, TypeId type_id, int32_t arg0, int32_t arg1) : parse_node_(parse_node), kind_(kind), @@ -172,7 +175,7 @@ class Node : public Printable { } Parse::Node parse_node_; - NodeKind kind_; + InstKind kind_; TypeId type_id_; // Use `As` to access arg0 and arg1. @@ -181,18 +184,18 @@ class Node : public Printable { }; // TODO: This is currently 20 bytes because we sometimes have 2 arguments for a -// pair of Nodes. However, NodeKind is 1 byte; if args -// were 3.5 bytes, we could potentially shrink Node by 4 bytes. This +// pair of Insts. However, InstKind is 1 byte; if args +// were 3.5 bytes, we could potentially shrink Inst by 4 bytes. This // may be worth investigating further. -static_assert(sizeof(Node) == 20, "Unexpected Node size"); +static_assert(sizeof(Inst) == 20, "Unexpected Inst size"); -// Typed nodes can be printed by converting them to nodes. -template > -inline llvm::raw_ostream& operator<<(llvm::raw_ostream& out, TypedNode node) { - Node(node).Print(out); +// Typed instructions can be printed by converting them to instructions. +template > +inline llvm::raw_ostream& operator<<(llvm::raw_ostream& out, TypedInst inst) { + Inst(inst).Print(out); return out; } } // namespace Carbon::SemIR -#endif // CARBON_TOOLCHAIN_SEM_IR_NODE_H_ +#endif // CARBON_TOOLCHAIN_SEM_IR_INST_H_ diff --git a/toolchain/sem_ir/node_kind.cpp b/toolchain/sem_ir/node_kind.cpp index 1800fceee16e..5f531baa7901 100644 --- a/toolchain/sem_ir/node_kind.cpp +++ b/toolchain/sem_ir/node_kind.cpp @@ -4,35 +4,35 @@ #include "toolchain/sem_ir/node_kind.h" -#include "toolchain/sem_ir/typed_nodes.h" +#include "toolchain/sem_ir/typed_insts.h" namespace Carbon::SemIR { -CARBON_DEFINE_ENUM_CLASS_NAMES(NodeKind) = { -#define CARBON_SEM_IR_NODE_KIND(Name) CARBON_ENUM_CLASS_NAME_STRING(Name) +CARBON_DEFINE_ENUM_CLASS_NAMES(InstKind) = { +#define CARBON_SEM_IR_INST_KIND(Name) CARBON_ENUM_CLASS_NAME_STRING(Name) #include "toolchain/sem_ir/node_kind.def" }; -auto NodeKind::ir_name() const -> llvm::StringLiteral { +auto InstKind::ir_name() const -> llvm::StringLiteral { return definition().ir_name(); } -auto NodeKind::value_kind() const -> NodeValueKind { - static constexpr NodeValueKind Table[] = { -#define CARBON_SEM_IR_NODE_KIND(Name) \ - HasTypeId ? NodeValueKind::Typed : NodeValueKind::None, +auto InstKind::value_kind() const -> InstValueKind { + static constexpr InstValueKind Table[] = { +#define CARBON_SEM_IR_INST_KIND(Name) \ + HasTypeId ? InstValueKind::Typed : InstValueKind::None, #include "toolchain/sem_ir/node_kind.def" }; return Table[AsInt()]; } -auto NodeKind::terminator_kind() const -> TerminatorKind { +auto InstKind::terminator_kind() const -> TerminatorKind { return definition().terminator_kind(); } -auto NodeKind::definition() const -> const Definition& { +auto InstKind::definition() const -> const Definition& { static constexpr const Definition* Table[] = { -#define CARBON_SEM_IR_NODE_KIND(Name) &SemIR::Name::Kind, +#define CARBON_SEM_IR_INST_KIND(Name) &SemIR::Name::Kind, #include "toolchain/sem_ir/node_kind.def" }; return *Table[AsInt()]; diff --git a/toolchain/sem_ir/node_kind.def b/toolchain/sem_ir/node_kind.def index d3547d745dc3..5993ebeff707 100644 --- a/toolchain/sem_ir/node_kind.def +++ b/toolchain/sem_ir/node_kind.def @@ -8,70 +8,70 @@ // at the end of this file. // // This macro should be defined before including this header: -// - CARBON_SEM_IR_NODE_KIND(Name) -// Invoked for each kind of semantic node. +// - CARBON_SEM_IR_INST_KIND(Name) +// Invoked for each kind of semantic instruction. -#ifndef CARBON_SEM_IR_NODE_KIND +#ifndef CARBON_SEM_IR_INST_KIND #error "Must define the x-macro to use this file." #endif -// For each node kind declared here there is a matching definition in -// `typed.nodes.h`. -CARBON_SEM_IR_NODE_KIND(AddressOf) -CARBON_SEM_IR_NODE_KIND(ArrayIndex) -CARBON_SEM_IR_NODE_KIND(ArrayInit) -CARBON_SEM_IR_NODE_KIND(ArrayType) -CARBON_SEM_IR_NODE_KIND(Assign) -CARBON_SEM_IR_NODE_KIND(BinaryOperatorAdd) -CARBON_SEM_IR_NODE_KIND(BindName) -CARBON_SEM_IR_NODE_KIND(BindValue) -CARBON_SEM_IR_NODE_KIND(BlockArg) -CARBON_SEM_IR_NODE_KIND(BoolLiteral) -CARBON_SEM_IR_NODE_KIND(BoundMethod) -CARBON_SEM_IR_NODE_KIND(Branch) -CARBON_SEM_IR_NODE_KIND(BranchIf) -CARBON_SEM_IR_NODE_KIND(BranchWithArg) -CARBON_SEM_IR_NODE_KIND(Builtin) -CARBON_SEM_IR_NODE_KIND(Call) -CARBON_SEM_IR_NODE_KIND(ClassDeclaration) -CARBON_SEM_IR_NODE_KIND(ClassFieldAccess) -CARBON_SEM_IR_NODE_KIND(ClassType) -CARBON_SEM_IR_NODE_KIND(ConstType) -CARBON_SEM_IR_NODE_KIND(CrossReference) -CARBON_SEM_IR_NODE_KIND(Dereference) -CARBON_SEM_IR_NODE_KIND(Field) -CARBON_SEM_IR_NODE_KIND(FunctionDeclaration) -CARBON_SEM_IR_NODE_KIND(InitializeFrom) -CARBON_SEM_IR_NODE_KIND(IntegerLiteral) -CARBON_SEM_IR_NODE_KIND(NameReference) -CARBON_SEM_IR_NODE_KIND(Namespace) -CARBON_SEM_IR_NODE_KIND(NoOp) -CARBON_SEM_IR_NODE_KIND(Parameter) -CARBON_SEM_IR_NODE_KIND(PointerType) -CARBON_SEM_IR_NODE_KIND(RealLiteral) -CARBON_SEM_IR_NODE_KIND(ReturnExpression) -CARBON_SEM_IR_NODE_KIND(Return) -CARBON_SEM_IR_NODE_KIND(SelfParameter) -CARBON_SEM_IR_NODE_KIND(SpliceBlock) -CARBON_SEM_IR_NODE_KIND(StringLiteral) -CARBON_SEM_IR_NODE_KIND(StructAccess) -CARBON_SEM_IR_NODE_KIND(StructInit) -CARBON_SEM_IR_NODE_KIND(StructLiteral) -CARBON_SEM_IR_NODE_KIND(StructTypeField) -CARBON_SEM_IR_NODE_KIND(StructType) -CARBON_SEM_IR_NODE_KIND(StructValue) -CARBON_SEM_IR_NODE_KIND(TemporaryStorage) -CARBON_SEM_IR_NODE_KIND(Temporary) -CARBON_SEM_IR_NODE_KIND(TupleAccess) -CARBON_SEM_IR_NODE_KIND(TupleIndex) -CARBON_SEM_IR_NODE_KIND(TupleInit) -CARBON_SEM_IR_NODE_KIND(TupleLiteral) -CARBON_SEM_IR_NODE_KIND(TupleType) -CARBON_SEM_IR_NODE_KIND(TupleValue) -CARBON_SEM_IR_NODE_KIND(UnaryOperatorNot) -CARBON_SEM_IR_NODE_KIND(UnboundFieldType) -CARBON_SEM_IR_NODE_KIND(ValueAsReference) -CARBON_SEM_IR_NODE_KIND(ValueOfInitializer) -CARBON_SEM_IR_NODE_KIND(VarStorage) +// For each instruction kind declared here there is a matching definition in +// `typed_insts.h`. +CARBON_SEM_IR_INST_KIND(AddressOf) +CARBON_SEM_IR_INST_KIND(ArrayIndex) +CARBON_SEM_IR_INST_KIND(ArrayInit) +CARBON_SEM_IR_INST_KIND(ArrayType) +CARBON_SEM_IR_INST_KIND(Assign) +CARBON_SEM_IR_INST_KIND(BinaryOperatorAdd) +CARBON_SEM_IR_INST_KIND(BindName) +CARBON_SEM_IR_INST_KIND(BindValue) +CARBON_SEM_IR_INST_KIND(BlockArg) +CARBON_SEM_IR_INST_KIND(BoolLiteral) +CARBON_SEM_IR_INST_KIND(BoundMethod) +CARBON_SEM_IR_INST_KIND(Branch) +CARBON_SEM_IR_INST_KIND(BranchIf) +CARBON_SEM_IR_INST_KIND(BranchWithArg) +CARBON_SEM_IR_INST_KIND(Builtin) +CARBON_SEM_IR_INST_KIND(Call) +CARBON_SEM_IR_INST_KIND(ClassDeclaration) +CARBON_SEM_IR_INST_KIND(ClassFieldAccess) +CARBON_SEM_IR_INST_KIND(ClassType) +CARBON_SEM_IR_INST_KIND(ConstType) +CARBON_SEM_IR_INST_KIND(CrossReference) +CARBON_SEM_IR_INST_KIND(Dereference) +CARBON_SEM_IR_INST_KIND(Field) +CARBON_SEM_IR_INST_KIND(FunctionDeclaration) +CARBON_SEM_IR_INST_KIND(InitializeFrom) +CARBON_SEM_IR_INST_KIND(IntegerLiteral) +CARBON_SEM_IR_INST_KIND(NameReference) +CARBON_SEM_IR_INST_KIND(Namespace) +CARBON_SEM_IR_INST_KIND(NoOp) +CARBON_SEM_IR_INST_KIND(Parameter) +CARBON_SEM_IR_INST_KIND(PointerType) +CARBON_SEM_IR_INST_KIND(RealLiteral) +CARBON_SEM_IR_INST_KIND(ReturnExpression) +CARBON_SEM_IR_INST_KIND(Return) +CARBON_SEM_IR_INST_KIND(SelfParameter) +CARBON_SEM_IR_INST_KIND(SpliceBlock) +CARBON_SEM_IR_INST_KIND(StringLiteral) +CARBON_SEM_IR_INST_KIND(StructAccess) +CARBON_SEM_IR_INST_KIND(StructInit) +CARBON_SEM_IR_INST_KIND(StructLiteral) +CARBON_SEM_IR_INST_KIND(StructTypeField) +CARBON_SEM_IR_INST_KIND(StructType) +CARBON_SEM_IR_INST_KIND(StructValue) +CARBON_SEM_IR_INST_KIND(TemporaryStorage) +CARBON_SEM_IR_INST_KIND(Temporary) +CARBON_SEM_IR_INST_KIND(TupleAccess) +CARBON_SEM_IR_INST_KIND(TupleIndex) +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(UnaryOperatorNot) +CARBON_SEM_IR_INST_KIND(UnboundFieldType) +CARBON_SEM_IR_INST_KIND(ValueAsReference) +CARBON_SEM_IR_INST_KIND(ValueOfInitializer) +CARBON_SEM_IR_INST_KIND(VarStorage) -#undef CARBON_SEM_IR_NODE_KIND +#undef CARBON_SEM_IR_INST_KIND diff --git a/toolchain/sem_ir/node_kind.h b/toolchain/sem_ir/node_kind.h index 24db767269c9..7af5f0aec2c3 100644 --- a/toolchain/sem_ir/node_kind.h +++ b/toolchain/sem_ir/node_kind.h @@ -12,102 +12,105 @@ namespace Carbon::SemIR { -// Whether a node produces or represents a value, and if so, what kind of value. -enum class NodeValueKind : int8_t { - // This node doesn't produce a value, and shouldn't be referenced by other - // nodes. +// Whether an instruction produces or represents a value, and if so, what kind +// of value. +enum class InstValueKind : int8_t { + // This instruction doesn't produce a value, and shouldn't be referenced by + // other + // instructions. None, - // This node represents an expression or expression-like construct that + // This instruction represents an expression or expression-like construct that // produces a value of the type indicated by its `type_id` field. Typed, }; -// Whether a node is a terminator or part of the terminator sequence. The nodes -// in a block appear in the order NotTerminator, then TerminatorSequence, then -// Terminator, which is also the numerical order of these values. +// Whether an instruction is a terminator or part of the terminator sequence. +// The instructions in a block appear in the order NotTerminator, then +// TerminatorSequence, then Terminator, which is also the numerical order of +// these values. enum class TerminatorKind : int8_t { - // This node is not a terminator. + // This instruction is not a terminator. NotTerminator, - // This node is not itself a terminator, but forms part of a terminator + // This instruction is not itself a terminator, but forms part of a terminator // sequence. TerminatorSequence, - // This node is a terminator. + // This instruction is a terminator. Terminator, }; -CARBON_DEFINE_RAW_ENUM_CLASS(NodeKind, uint8_t) { -#define CARBON_SEM_IR_NODE_KIND(Name) CARBON_RAW_ENUM_ENUMERATOR(Name) +CARBON_DEFINE_RAW_ENUM_CLASS(InstKind, uint8_t) { +#define CARBON_SEM_IR_INST_KIND(Name) CARBON_RAW_ENUM_ENUMERATOR(Name) #include "toolchain/sem_ir/node_kind.def" }; -class NodeKind : public CARBON_ENUM_BASE(NodeKind) { +class InstKind : public CARBON_ENUM_BASE(InstKind) { public: -#define CARBON_SEM_IR_NODE_KIND(Name) CARBON_ENUM_CONSTANT_DECLARATION(Name) +#define CARBON_SEM_IR_INST_KIND(Name) CARBON_ENUM_CONSTANT_DECLARATION(Name) #include "toolchain/sem_ir/node_kind.def" using EnumBase::Create; - // Returns the name to use for this node kind in Semantics IR. + // Returns the name to use for this instruction kind in Semantics IR. [[nodiscard]] auto ir_name() const -> llvm::StringLiteral; - // Returns whether this kind of node is expected to produce a value. - [[nodiscard]] auto value_kind() const -> NodeValueKind; + // Returns whether this kind of instruction is expected to produce a value. + [[nodiscard]] auto value_kind() const -> InstValueKind; - // Returns whether this node kind is a code block terminator, such as an - // unconditional branch instruction, or part of the termination sequence, + // Returns whether this instruction kind is a code block terminator, such as + // an unconditional branch instruction, or part of the termination sequence, // such as a conditional branch instruction. The termination sequence of a // code block appears after all other instructions, and ends with a // terminator instruction. [[nodiscard]] auto terminator_kind() const -> TerminatorKind; - // Compute a fingerprint for this node kind, allowing its use as part of the - // key in a `FoldingSet`. + // Compute a fingerprint for this instruction kind, allowing its use as part + // of the key in a `FoldingSet`. void Profile(llvm::FoldingSetNodeID& id) { id.AddInteger(AsInt()); } class Definition; - // Provides a definition for this node kind. Should only be called once, to - // construct the kind as part of defining it in `typed_nodes.h`. + // Provides a definition for this instruction kind. Should only be called + // once, to construct the kind as part of defining it in `typed_insts.h`. constexpr auto Define(llvm::StringLiteral ir_name, TerminatorKind terminator_kind = TerminatorKind::NotTerminator) const -> Definition; private: - // Looks up the definition for this node kind. + // Looks up the definition for this instruction kind. [[nodiscard]] auto definition() const -> const Definition&; }; -#define CARBON_SEM_IR_NODE_KIND(Name) \ - CARBON_ENUM_CONSTANT_DEFINITION(NodeKind, Name) +#define CARBON_SEM_IR_INST_KIND(Name) \ + CARBON_ENUM_CONSTANT_DEFINITION(InstKind, Name) #include "toolchain/sem_ir/node_kind.def" -// We expect the node kind to fit compactly into 8 bits. -static_assert(sizeof(NodeKind) == 1, "Kind objects include padding!"); +// We expect the instruction kind to fit compactly into 8 bits. +static_assert(sizeof(InstKind) == 1, "Kind objects include padding!"); -// A definition of a node kind. This is a NodeKind value, plus ancillary data -// such as the name to use for the node kind in LLVM IR. These are not -// copyable, and only one instance of this type is expected to exist per node -// kind, specifically `TypedNode::Kind`. Use `NodeKind` instead as a thin -// wrapper around a node kind index. -class NodeKind::Definition : public NodeKind { +// A definition of an instruction kind. This is an InstKind value, plus +// ancillary data such as the name to use for the node kind in LLVM IR. These +// are not copyable, and only one instance of this type is expected to exist per +// instruction kind, specifically `TypedInst::Kind`. Use `InstKind` instead as a +// thin wrapper around an instruction kind index. +class InstKind::Definition : public InstKind { public: - // Returns the name to use for this node kind in Semantics IR. + // Returns the name to use for this instruction kind in Semantics IR. [[nodiscard]] constexpr auto ir_name() const -> llvm::StringLiteral { return ir_name_; } - // Returns whether this node kind is a code block terminator. See - // NodeKind::terminator_kind(). + // Returns whether this instruction kind is a code block terminator. See + // InstKind::terminator_kind(). [[nodiscard]] constexpr auto terminator_kind() const -> TerminatorKind { return terminator_kind_; } private: - friend class NodeKind; + friend class InstKind; - constexpr Definition(NodeKind kind, llvm::StringLiteral ir_name, + constexpr Definition(InstKind kind, llvm::StringLiteral ir_name, TerminatorKind terminator_kind) - : NodeKind(kind), ir_name_(ir_name), terminator_kind_(terminator_kind) {} + : InstKind(kind), ir_name_(ir_name), terminator_kind_(terminator_kind) {} // Not copyable. Definition(const Definition&) = delete; @@ -117,7 +120,7 @@ class NodeKind::Definition : public NodeKind { TerminatorKind terminator_kind_; }; -constexpr auto NodeKind::Define(llvm::StringLiteral ir_name, +constexpr auto InstKind::Define(llvm::StringLiteral ir_name, TerminatorKind terminator_kind) const -> Definition { return Definition(*this, ir_name, terminator_kind); diff --git a/toolchain/sem_ir/typed_nodes.h b/toolchain/sem_ir/typed_insts.h similarity index 58% rename from toolchain/sem_ir/typed_nodes.h rename to toolchain/sem_ir/typed_insts.h index ff3e0fb2f13e..2148c6089be9 100644 --- a/toolchain/sem_ir/typed_nodes.h +++ b/toolchain/sem_ir/typed_insts.h @@ -2,55 +2,55 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#ifndef CARBON_TOOLCHAIN_SEM_IR_TYPED_NODES_H_ -#define CARBON_TOOLCHAIN_SEM_IR_TYPED_NODES_H_ +#ifndef CARBON_TOOLCHAIN_SEM_IR_TYPED_INSTS_H_ +#define CARBON_TOOLCHAIN_SEM_IR_TYPED_INSTS_H_ #include "toolchain/parse/tree.h" #include "toolchain/sem_ir/builtin_kind.h" #include "toolchain/sem_ir/ids.h" #include "toolchain/sem_ir/node_kind.h" -// Representations for specific kinds of nodes. +// Representations for specific kinds of instructions. // // Each type should be a struct with up to four members: // -// - Optionally, a `Parse::Node parse_node;` member, for nodes with an -// associated location. Almost all nodes should have this, with exceptions -// being things that are generated internally, without any relation to source -// syntax, such as predeclared builtins. -// - Optionally, a `TypeId type_id;` member, for nodes that produce a value. -// This includes nodes that produce an abstract value, such as a `Namespace`, -// for which a placeholder type should be used. +// - Optionally, a `Parse::Node parse_node;` member, for instructions with an +// associated location. Almost all instructions should have this, with +// exceptions being things that are generated internally, without any relation +// to source syntax, such as predeclared builtins. +// - Optionally, a `TypeId type_id;` member, for instructions that produce a +// value. This includes instructions that produce an abstract value, such as a +// `Namespace`, for which a placeholder type should be used. // - Up to two `[...]Id` members describing the contents of the struct. // // The field names here matter -- the first two fields must have the names -// specified above, when present. When converting to a `SemIR::Node`, they will -// become the parse node and type associated with the type-erased node. +// specified above, when present. When converting to a `SemIR::Inst`, they will +// become the parse node and type associated with the type-erased instruction. // // In addition, each type provides a constant `Kind` that associates the type -// with a particular member of the `NodeKind` enumeration. This `Kind` -// declaration also defines the node kind by calling `NodeKind::Define` and -// specifying additional information about the node kind. This information is -// available through the member functions of the `NodeKind` value declared in -// `node_kind.h`, and includes the name used in textual IR and whether the node -// is a terminator instruction. +// with a particular member of the `InstKind` enumeration. This `Kind` +// declaration also defines the instruction kind by calling `InstKind::Define` +// and specifying additional information about the instruction kind. This +// information is available through the member functions of the `InstKind` value +// declared in `inst_kind.h`, and includes the name used in textual IR and +// whether the instruction is a terminator instruction. namespace Carbon::SemIR { struct AddressOf { - static constexpr auto Kind = NodeKind::AddressOf.Define("address_of"); + static constexpr auto Kind = InstKind::AddressOf.Define("address_of"); Parse::Node parse_node; TypeId type_id; - NodeId lvalue_id; + InstId lvalue_id; }; struct ArrayIndex { - static constexpr auto Kind = NodeKind::ArrayIndex.Define("array_index"); + static constexpr auto Kind = InstKind::ArrayIndex.Define("array_index"); Parse::Node parse_node; TypeId type_id; - NodeId array_id; - NodeId index_id; + InstId array_id; + InstId index_id; }; // Initializes an array from a tuple. `tuple_id` is the source tuple @@ -58,20 +58,20 @@ struct ArrayIndex { // element, plus a final element that is the return slot for the // initialization. struct ArrayInit { - static constexpr auto Kind = NodeKind::ArrayInit.Define("array_init"); + static constexpr auto Kind = InstKind::ArrayInit.Define("array_init"); Parse::Node parse_node; TypeId type_id; - NodeId tuple_id; - NodeBlockId inits_and_return_slot_id; + InstId tuple_id; + InstBlockId inits_and_return_slot_id; }; struct ArrayType { - static constexpr auto Kind = NodeKind::ArrayType.Define("array_type"); + static constexpr auto Kind = InstKind::ArrayType.Define("array_type"); Parse::Node parse_node; TypeId type_id; - NodeId bound_id; + InstId bound_id; TypeId element_type_id; }; @@ -79,50 +79,50 @@ struct ArrayType { // `rhs_id`. This finishes initialization of `lhs_id` in the same way as // `InitializeFrom`. struct Assign { - static constexpr auto Kind = NodeKind::Assign.Define("assign"); + static constexpr auto Kind = InstKind::Assign.Define("assign"); Parse::Node parse_node; // Assignments are statements, and so have no type. - NodeId lhs_id; - NodeId rhs_id; + InstId lhs_id; + InstId rhs_id; }; struct BinaryOperatorAdd { - static constexpr auto Kind = NodeKind::BinaryOperatorAdd.Define("add"); + static constexpr auto Kind = InstKind::BinaryOperatorAdd.Define("add"); Parse::Node parse_node; TypeId type_id; - NodeId lhs_id; - NodeId rhs_id; + InstId lhs_id; + InstId rhs_id; }; struct BindName { - static constexpr auto Kind = NodeKind::BindName.Define("bind_name"); + static constexpr auto Kind = InstKind::BindName.Define("bind_name"); Parse::Node parse_node; TypeId type_id; StringId name_id; - NodeId value_id; + InstId value_id; }; struct BindValue { - static constexpr auto Kind = NodeKind::BindValue.Define("bind_value"); + static constexpr auto Kind = InstKind::BindValue.Define("bind_value"); Parse::Node parse_node; TypeId type_id; - NodeId value_id; + InstId value_id; }; struct BlockArg { - static constexpr auto Kind = NodeKind::BlockArg.Define("block_arg"); + static constexpr auto Kind = InstKind::BlockArg.Define("block_arg"); Parse::Node parse_node; TypeId type_id; - NodeBlockId block_id; + InstBlockId block_id; }; struct BoolLiteral { - static constexpr auto Kind = NodeKind::BoolLiteral.Define("bool_literal"); + static constexpr auto Kind = InstKind::BoolLiteral.Define("bool_literal"); Parse::Node parse_node; TypeId type_id; @@ -132,48 +132,48 @@ struct BoolLiteral { // A bound method, that combines a function with the value to use for its // `self` parameter, such as `object.MethodName`. struct BoundMethod { - static constexpr auto Kind = NodeKind::BoundMethod.Define("bound_method"); + static constexpr auto Kind = InstKind::BoundMethod.Define("bound_method"); Parse::Node parse_node; TypeId type_id; // The object argument in the bound method, which will be used to initialize // `self`, or whose address will be used to initialize `self` for an `addr // self` parameter. - NodeId object_id; - NodeId function_id; + InstId object_id; + InstId function_id; }; struct Branch { static constexpr auto Kind = - NodeKind::Branch.Define("br", TerminatorKind::Terminator); + InstKind::Branch.Define("br", TerminatorKind::Terminator); Parse::Node parse_node; // Branches don't produce a value, so have no type. - NodeBlockId target_id; + InstBlockId target_id; }; struct BranchIf { static constexpr auto Kind = - NodeKind::BranchIf.Define("br", TerminatorKind::TerminatorSequence); + InstKind::BranchIf.Define("br", TerminatorKind::TerminatorSequence); Parse::Node parse_node; // Branches don't produce a value, so have no type. - NodeBlockId target_id; - NodeId cond_id; + InstBlockId target_id; + InstId cond_id; }; struct BranchWithArg { static constexpr auto Kind = - NodeKind::BranchWithArg.Define("br", TerminatorKind::Terminator); + InstKind::BranchWithArg.Define("br", TerminatorKind::Terminator); Parse::Node parse_node; // Branches don't produce a value, so have no type. - NodeBlockId target_id; - NodeId arg_id; + InstBlockId target_id; + InstId arg_id; }; struct Builtin { - static constexpr auto Kind = NodeKind::Builtin.Define("builtin"); + static constexpr auto Kind = InstKind::Builtin.Define("builtin"); // Builtins don't have a parse node associated with them. TypeId type_id; @@ -181,21 +181,21 @@ struct Builtin { }; struct Call { - static constexpr auto Kind = NodeKind::Call.Define("call"); + static constexpr auto Kind = InstKind::Call.Define("call"); Parse::Node parse_node; TypeId type_id; - NodeId callee_id; + InstId callee_id; // The arguments block contains IDs for the following arguments, in order: // - The argument for each implicit parameter. // - The argument for each explicit parameter. // - The argument for the return slot, if present. - NodeBlockId args_id; + InstBlockId args_id; }; struct ClassDeclaration { static constexpr auto Kind = - NodeKind::ClassDeclaration.Define("class_declaration"); + InstKind::ClassDeclaration.Define("class_declaration"); Parse::Node parse_node; // No type: a class declaration is not itself a value. The name of a class @@ -205,21 +205,21 @@ struct ClassDeclaration { ClassId class_id; // The declaration block, containing the class name's qualifiers and the // class's generic parameters. - NodeBlockId decl_block_id; + InstBlockId decl_block_id; }; struct ClassFieldAccess { static constexpr auto Kind = - NodeKind::ClassFieldAccess.Define("class_field_access"); + InstKind::ClassFieldAccess.Define("class_field_access"); Parse::Node parse_node; TypeId type_id; - NodeId base_id; + InstId base_id; MemberIndex index; }; struct ClassType { - static constexpr auto Kind = NodeKind::ClassType.Define("class_type"); + static constexpr auto Kind = InstKind::ClassType.Define("class_type"); Parse::Node parse_node; TypeId type_id; @@ -228,7 +228,7 @@ struct ClassType { }; struct ConstType { - static constexpr auto Kind = NodeKind::ConstType.Define("const_type"); + static constexpr auto Kind = InstKind::ConstType.Define("const_type"); Parse::Node parse_node; TypeId type_id; @@ -237,28 +237,28 @@ struct ConstType { // A cross-reference between IRs. struct CrossReference { - static constexpr auto Kind = NodeKind::CrossReference.Define("xref"); + static constexpr auto Kind = InstKind::CrossReference.Define("xref"); - // No parse node: a node's parse tree node must refer to a node in the - // current parse tree. This cannot use the cross-referenced node's parse tree - // node because it will be in a different parse tree. + // No parse node: an instruction's parse tree node must refer to a node in the + // current parse tree. This cannot use the cross-referenced instruction's + // parse tree node because it will be in a different parse tree. TypeId type_id; CrossReferenceIRId ir_id; - NodeId node_id; + InstId inst_id; }; struct Dereference { - static constexpr auto Kind = NodeKind::Dereference.Define("dereference"); + static constexpr auto Kind = InstKind::Dereference.Define("dereference"); Parse::Node parse_node; TypeId type_id; - NodeId pointer_id; + InstId pointer_id; }; // A field in a class, of the form `var field: field_type;`. The type of the -// `Field` node is an `UnboundFieldType`. +// `Field` instruction is an `UnboundFieldType`. struct Field { - static constexpr auto Kind = NodeKind::Field.Define("field"); + static constexpr auto Kind = InstKind::Field.Define("field"); Parse::Node parse_node; TypeId type_id; @@ -267,7 +267,7 @@ struct Field { }; struct FunctionDeclaration { - static constexpr auto Kind = NodeKind::FunctionDeclaration.Define("fn_decl"); + static constexpr auto Kind = InstKind::FunctionDeclaration.Define("fn_decl"); Parse::Node parse_node; TypeId type_id; @@ -279,16 +279,16 @@ struct FunctionDeclaration { // whose initialization is not in-place. struct InitializeFrom { static constexpr auto Kind = - NodeKind::InitializeFrom.Define("initialize_from"); + InstKind::InitializeFrom.Define("initialize_from"); Parse::Node parse_node; TypeId type_id; - NodeId src_id; - NodeId dest_id; + InstId src_id; + InstId dest_id; }; struct IntegerLiteral { - static constexpr auto Kind = NodeKind::IntegerLiteral.Define("int_literal"); + static constexpr auto Kind = InstKind::IntegerLiteral.Define("int_literal"); Parse::Node parse_node; TypeId type_id; @@ -296,16 +296,16 @@ struct IntegerLiteral { }; struct NameReference { - static constexpr auto Kind = NodeKind::NameReference.Define("name_reference"); + static constexpr auto Kind = InstKind::NameReference.Define("name_reference"); Parse::Node parse_node; TypeId type_id; StringId name_id; - NodeId value_id; + InstId value_id; }; struct Namespace { - static constexpr auto Kind = NodeKind::Namespace.Define("namespace"); + static constexpr auto Kind = InstKind::Namespace.Define("namespace"); Parse::Node parse_node; TypeId type_id; @@ -313,14 +313,14 @@ struct Namespace { }; struct NoOp { - static constexpr auto Kind = NodeKind::NoOp.Define("no_op"); + static constexpr auto Kind = InstKind::NoOp.Define("no_op"); Parse::Node parse_node; - // This node doesn't produce a value, so has no type. + // This instruction doesn't produce a value, so has no type. }; struct Parameter { - static constexpr auto Kind = NodeKind::Parameter.Define("parameter"); + static constexpr auto Kind = InstKind::Parameter.Define("parameter"); Parse::Node parse_node; TypeId type_id; @@ -328,7 +328,7 @@ struct Parameter { }; struct PointerType { - static constexpr auto Kind = NodeKind::PointerType.Define("ptr_type"); + static constexpr auto Kind = InstKind::PointerType.Define("ptr_type"); Parse::Node parse_node; TypeId type_id; @@ -336,7 +336,7 @@ struct PointerType { }; struct RealLiteral { - static constexpr auto Kind = NodeKind::RealLiteral.Define("real_literal"); + static constexpr auto Kind = InstKind::RealLiteral.Define("real_literal"); Parse::Node parse_node; TypeId type_id; @@ -345,7 +345,7 @@ struct RealLiteral { struct Return { static constexpr auto Kind = - NodeKind::Return.Define("return", TerminatorKind::Terminator); + InstKind::Return.Define("return", TerminatorKind::Terminator); Parse::Node parse_node; // This is a statement, so has no type. @@ -353,15 +353,15 @@ struct Return { struct ReturnExpression { static constexpr auto Kind = - NodeKind::ReturnExpression.Define("return", TerminatorKind::Terminator); + InstKind::ReturnExpression.Define("return", TerminatorKind::Terminator); Parse::Node parse_node; // This is a statement, so has no type. - NodeId expr_id; + InstId expr_id; }; struct SelfParameter { - static constexpr auto Kind = NodeKind::SelfParameter.Define("self_parameter"); + static constexpr auto Kind = InstKind::SelfParameter.Define("self_parameter"); static constexpr llvm::StringLiteral Name = "self"; Parse::Node parse_node; @@ -370,16 +370,16 @@ struct SelfParameter { }; struct SpliceBlock { - static constexpr auto Kind = NodeKind::SpliceBlock.Define("splice_block"); + static constexpr auto Kind = InstKind::SpliceBlock.Define("splice_block"); Parse::Node parse_node; TypeId type_id; - NodeBlockId block_id; - NodeId result_id; + InstBlockId block_id; + InstId result_id; }; struct StringLiteral { - static constexpr auto Kind = NodeKind::StringLiteral.Define("string_literal"); + static constexpr auto Kind = InstKind::StringLiteral.Define("string_literal"); Parse::Node parse_node; TypeId type_id; @@ -387,113 +387,114 @@ struct StringLiteral { }; struct StructAccess { - static constexpr auto Kind = NodeKind::StructAccess.Define("struct_access"); + static constexpr auto Kind = InstKind::StructAccess.Define("struct_access"); Parse::Node parse_node; TypeId type_id; - NodeId struct_id; + InstId struct_id; MemberIndex index; }; struct StructInit { - static constexpr auto Kind = NodeKind::StructInit.Define("struct_init"); + static constexpr auto Kind = InstKind::StructInit.Define("struct_init"); Parse::Node parse_node; TypeId type_id; - NodeId src_id; - NodeBlockId elements_id; + InstId src_id; + InstBlockId elements_id; }; struct StructLiteral { - static constexpr auto Kind = NodeKind::StructLiteral.Define("struct_literal"); + static constexpr auto Kind = InstKind::StructLiteral.Define("struct_literal"); Parse::Node parse_node; TypeId type_id; - NodeBlockId elements_id; + InstBlockId elements_id; }; struct StructType { - static constexpr auto Kind = NodeKind::StructType.Define("struct_type"); + static constexpr auto Kind = InstKind::StructType.Define("struct_type"); Parse::Node parse_node; TypeId type_id; - NodeBlockId fields_id; + InstBlockId fields_id; }; struct StructTypeField { static constexpr auto Kind = - NodeKind::StructTypeField.Define("struct_type_field"); + InstKind::StructTypeField.Define("struct_type_field"); Parse::Node parse_node; - // This node is an implementation detail of `StructType`, and doesn't produce - // a value, so has no type, even though it declares a field with a type. + // This instruction is an implementation detail of `StructType`, and doesn't + // produce a value, so has no type, even though it declares a field with a + // type. StringId name_id; TypeId field_type_id; }; struct StructValue { - static constexpr auto Kind = NodeKind::StructValue.Define("struct_value"); + static constexpr auto Kind = InstKind::StructValue.Define("struct_value"); Parse::Node parse_node; TypeId type_id; - NodeId src_id; - NodeBlockId elements_id; + InstId src_id; + InstBlockId elements_id; }; struct Temporary { - static constexpr auto Kind = NodeKind::Temporary.Define("temporary"); + static constexpr auto Kind = InstKind::Temporary.Define("temporary"); Parse::Node parse_node; TypeId type_id; - NodeId storage_id; - NodeId init_id; + InstId storage_id; + InstId init_id; }; struct TemporaryStorage { static constexpr auto Kind = - NodeKind::TemporaryStorage.Define("temporary_storage"); + InstKind::TemporaryStorage.Define("temporary_storage"); Parse::Node parse_node; TypeId type_id; }; struct TupleAccess { - static constexpr auto Kind = NodeKind::TupleAccess.Define("tuple_access"); + static constexpr auto Kind = InstKind::TupleAccess.Define("tuple_access"); Parse::Node parse_node; TypeId type_id; - NodeId tuple_id; + InstId tuple_id; MemberIndex index; }; struct TupleIndex { - static constexpr auto Kind = NodeKind::TupleIndex.Define("tuple_index"); + static constexpr auto Kind = InstKind::TupleIndex.Define("tuple_index"); Parse::Node parse_node; TypeId type_id; - NodeId tuple_id; - NodeId index_id; + InstId tuple_id; + InstId index_id; }; struct TupleInit { - static constexpr auto Kind = NodeKind::TupleInit.Define("tuple_init"); + static constexpr auto Kind = InstKind::TupleInit.Define("tuple_init"); Parse::Node parse_node; TypeId type_id; - NodeId src_id; - NodeBlockId elements_id; + InstId src_id; + InstBlockId elements_id; }; struct TupleLiteral { - static constexpr auto Kind = NodeKind::TupleLiteral.Define("tuple_literal"); + static constexpr auto Kind = InstKind::TupleLiteral.Define("tuple_literal"); Parse::Node parse_node; TypeId type_id; - NodeBlockId elements_id; + InstBlockId elements_id; }; struct TupleType { - static constexpr auto Kind = NodeKind::TupleType.Define("tuple_type"); + static constexpr auto Kind = InstKind::TupleType.Define("tuple_type"); Parse::Node parse_node; TypeId type_id; @@ -501,20 +502,20 @@ struct TupleType { }; struct TupleValue { - static constexpr auto Kind = NodeKind::TupleValue.Define("tuple_value"); + static constexpr auto Kind = InstKind::TupleValue.Define("tuple_value"); Parse::Node parse_node; TypeId type_id; - NodeId src_id; - NodeBlockId elements_id; + InstId src_id; + InstBlockId elements_id; }; struct UnaryOperatorNot { - static constexpr auto Kind = NodeKind::UnaryOperatorNot.Define("not"); + static constexpr auto Kind = InstKind::UnaryOperatorNot.Define("not"); Parse::Node parse_node; TypeId type_id; - NodeId operand_id; + InstId operand_id; }; // The type of an expression naming an unbound field, such as `Class.field`. @@ -522,7 +523,7 @@ struct UnaryOperatorNot { // such as `instance.(Class.field)`. struct UnboundFieldType { static constexpr auto Kind = - NodeKind::UnboundFieldType.Define("unbound_field_type"); + InstKind::UnboundFieldType.Define("unbound_field_type"); Parse::Node parse_node; TypeId type_id; @@ -534,24 +535,24 @@ struct UnboundFieldType { struct ValueAsReference { static constexpr auto Kind = - NodeKind::ValueAsReference.Define("value_as_reference"); + InstKind::ValueAsReference.Define("value_as_reference"); Parse::Node parse_node; TypeId type_id; - NodeId value_id; + InstId value_id; }; struct ValueOfInitializer { static constexpr auto Kind = - NodeKind::ValueOfInitializer.Define("value_of_initializer"); + InstKind::ValueOfInitializer.Define("value_of_initializer"); Parse::Node parse_node; TypeId type_id; - NodeId init_id; + InstId init_id; }; struct VarStorage { - static constexpr auto Kind = NodeKind::VarStorage.Define("var"); + static constexpr auto Kind = InstKind::VarStorage.Define("var"); Parse::Node parse_node; TypeId type_id; @@ -572,4 +573,4 @@ constexpr bool HasTypeId = true; } // namespace Carbon::SemIR -#endif // CARBON_TOOLCHAIN_SEM_IR_TYPED_NODES_H_ +#endif // CARBON_TOOLCHAIN_SEM_IR_TYPED_INSTS_H_ diff --git a/toolchain/sem_ir/typed_nodes_test.cpp b/toolchain/sem_ir/typed_nodes_test.cpp index ddcaa7b69cf6..7f098915368b 100644 --- a/toolchain/sem_ir/typed_nodes_test.cpp +++ b/toolchain/sem_ir/typed_nodes_test.cpp @@ -2,21 +2,20 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include "toolchain/sem_ir/typed_nodes.h" - #include #include -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" +#include "toolchain/sem_ir/typed_insts.h" namespace Carbon::SemIR { -// A friend of `SemIR::Node` that is used to pierce the abstraction. -class NodeTestHelper { +// A friend of `SemIR::Inst` that is used to pierce the abstraction. +class InstTestHelper { public: - static auto MakeNode(NodeKind node_kind, Parse::Node parse_node, - TypeId type_id, int32_t arg0, int32_t arg1) -> Node { - return Node(node_kind, parse_node, type_id, arg0, arg1); + static auto MakeInst(InstKind inst_kind, Parse::Node parse_node, + TypeId type_id, int32_t arg0, int32_t arg1) -> Inst { + return Inst(inst_kind, parse_node, type_id, arg0, arg1); } }; @@ -25,120 +24,122 @@ class NodeTestHelper { namespace Carbon::SemIR { namespace { -// Check that each node kind defines a Kind member using the correct NodeKind -// enumerator. -#define CARBON_SEM_IR_NODE_KIND(Name) \ - static_assert(Name::Kind == NodeKind::Name); +// Check that each instruction kind defines a Kind member using the correct +// InstKind enumerator. +#define CARBON_SEM_IR_INST_KIND(Name) \ + static_assert(Name::Kind == InstKind::Name); #include "toolchain/sem_ir/node_kind.def" template using TypesExceptFirst = ::testing::Types; -// Form a list of all typed node types. Use `TypesExceptFirst` and a leading -// `void` to handle the problem that we only want N-1 commas in this list. -using TypedNodeTypes = TypesExceptFirst; // Set up the test fixture. -template -class TypedNodeTest : public testing::Test {}; +template +class TypedInstTest : public testing::Test {}; -TYPED_TEST_SUITE(TypedNodeTest, TypedNodeTypes); +TYPED_TEST_SUITE(TypedInstTest, TypedInstTypes); -TYPED_TEST(TypedNodeTest, CommonFieldOrder) { - using TypedNode = TypeParam; +TYPED_TEST(TypedInstTest, CommonFieldOrder) { + using TypedInst = TypeParam; - Node node = NodeTestHelper::MakeNode(TypeParam::Kind, Parse::Node(1), + Inst inst = InstTestHelper::MakeInst(TypeParam::Kind, Parse::Node(1), TypeId(2), 3, 4); - EXPECT_EQ(node.kind(), TypeParam::Kind); - EXPECT_EQ(node.parse_node(), Parse::Node(1)); - EXPECT_EQ(node.type_id(), TypeId(2)); + EXPECT_EQ(inst.kind(), TypeParam::Kind); + EXPECT_EQ(inst.parse_node(), Parse::Node(1)); + EXPECT_EQ(inst.type_id(), TypeId(2)); - TypedNode typed = node.As(); - if constexpr (HasParseNode) { + TypedInst typed = inst.As(); + if constexpr (HasParseNode) { EXPECT_EQ(typed.parse_node, Parse::Node(1)); } - if constexpr (HasTypeId) { + if constexpr (HasTypeId) { EXPECT_EQ(typed.type_id, TypeId(2)); } } -TYPED_TEST(TypedNodeTest, RoundTrip) { - using TypedNode = TypeParam; +TYPED_TEST(TypedInstTest, RoundTrip) { + using TypedInst = TypeParam; - Node node1 = NodeTestHelper::MakeNode(TypeParam::Kind, Parse::Node(1), + Inst inst1 = InstTestHelper::MakeInst(TypeParam::Kind, Parse::Node(1), TypeId(2), 3, 4); - EXPECT_EQ(node1.kind(), TypeParam::Kind); - EXPECT_EQ(node1.parse_node(), Parse::Node(1)); - EXPECT_EQ(node1.type_id(), TypeId(2)); + EXPECT_EQ(inst1.kind(), TypeParam::Kind); + EXPECT_EQ(inst1.parse_node(), Parse::Node(1)); + EXPECT_EQ(inst1.type_id(), TypeId(2)); - TypedNode typed1 = node1.As(); - Node node2 = typed1; + TypedInst typed1 = inst1.As(); + Inst inst2 = typed1; - EXPECT_EQ(node1.kind(), node2.kind()); - if constexpr (HasParseNode) { - EXPECT_EQ(node1.parse_node(), node2.parse_node()); + EXPECT_EQ(inst1.kind(), inst2.kind()); + if constexpr (HasParseNode) { + EXPECT_EQ(inst1.parse_node(), inst2.parse_node()); } - if constexpr (HasTypeId) { - EXPECT_EQ(node1.type_id(), node2.type_id()); + if constexpr (HasTypeId) { + EXPECT_EQ(inst1.type_id(), inst2.type_id()); } - // If the typed node has no padding, we should get exactly the same thing - // if we convert back from a node. - TypedNode typed2 = node2.As(); - if constexpr (std::has_unique_object_representations_v) { - EXPECT_EQ(std::memcmp(&typed1, &typed2, sizeof(TypedNode)), 0); + // If the typed instruction has no padding, we should get exactly the same + // thing if we convert back from an instruction. + TypedInst typed2 = inst2.As(); + if constexpr (std::has_unique_object_representations_v) { + EXPECT_EQ(std::memcmp(&typed1, &typed2, sizeof(TypedInst)), 0); } - // The original node might not be identical after one round trip, because the - // fields not carried by the typed node are lost. But they should be stable - // if we round-trip again. - Node node3 = typed2; - if constexpr (std::has_unique_object_representations_v) { - EXPECT_EQ(std::memcmp(&node2, &node3, sizeof(Node)), 0); + // The original instruction might not be identical after one round trip, + // because the fields not carried by the typed instruction are lost. But they + // should be stable if we round-trip again. + Inst inst3 = typed2; + if constexpr (std::has_unique_object_representations_v) { + EXPECT_EQ(std::memcmp(&inst2, &inst3, sizeof(Inst)), 0); } } -TYPED_TEST(TypedNodeTest, StructLayout) { - using TypedNode = TypeParam; +TYPED_TEST(TypedInstTest, StructLayout) { + using TypedInst = TypeParam; - TypedNode typed = - NodeTestHelper::MakeNode(TypeParam::Kind, Parse::Node(1), TypeId(2), 3, 4) - .template As(); + TypedInst typed = + InstTestHelper::MakeInst(TypeParam::Kind, Parse::Node(1), TypeId(2), 3, 4) + .template As(); - // Check that the memory representation of the typed node is what we expect. + // Check that the memory representation of the typed instruction is what we + // expect. // TODO: Struct layout is not guaranteed, and this test could fail in some // build environment. If so, we should disable it. int32_t fields[4] = {}; int field = 0; - if constexpr (HasParseNode) { + if constexpr (HasParseNode) { fields[field++] = 1; } - if constexpr (HasTypeId) { + if constexpr (HasTypeId) { fields[field++] = 2; } fields[field++] = 3; fields[field++] = 4; - ASSERT_LE(sizeof(TypedNode), sizeof(fields)); - // We can only do this check if the typed node has no padding. - if constexpr (std::has_unique_object_representations_v) { - EXPECT_EQ(std::memcmp(&fields, &typed, sizeof(TypedNode)), 0); + ASSERT_LE(sizeof(TypedInst), sizeof(fields)); + // We can only do this check if the typed instruction has no padding. + if constexpr (std::has_unique_object_representations_v) { + EXPECT_EQ(std::memcmp(&fields, &typed, sizeof(TypedInst)), 0); } } -TYPED_TEST(TypedNodeTest, NodeKindMatches) { - using TypedNode = TypeParam; +TYPED_TEST(TypedInstTest, InstKindMatches) { + using TypedInst = TypeParam; - // TypedNode::Kind is a NodeKind::Definition that extends NodeKind, but + // TypedInst::Kind is an InstKind::Definition that extends InstKind, but // has different definitions of the `ir_name()` and `terminator_kind()` // methods. Here we test that values returned by the two different versions // of those functions match. - NodeKind as_kind = TypedNode::Kind; - EXPECT_EQ(TypedNode::Kind.ir_name(), as_kind.ir_name()); - EXPECT_EQ(TypedNode::Kind.terminator_kind(), as_kind.terminator_kind()); + InstKind as_kind = TypedInst::Kind; + EXPECT_EQ(TypedInst::Kind.ir_name(), as_kind.ir_name()); + EXPECT_EQ(TypedInst::Kind.terminator_kind(), as_kind.terminator_kind()); } } // namespace diff --git a/toolchain/sem_ir/value_stores.h b/toolchain/sem_ir/value_stores.h index d91d277ea884..f048a2948fb3 100644 --- a/toolchain/sem_ir/value_stores.h +++ b/toolchain/sem_ir/value_stores.h @@ -8,39 +8,41 @@ #include "llvm/ADT/DenseMap.h" #include "toolchain/base/value_store.h" #include "toolchain/base/yaml.h" -#include "toolchain/sem_ir/node.h" +#include "toolchain/sem_ir/inst.h" namespace Carbon::SemIR { -// Provides a ValueStore wrapper for an API specific to nodes. -class NodeStore { +// Provides a ValueStore wrapper for an API specific to instructions. +class InstStore { public: - // Adds a node to the node list, returning an ID to reference the node. Note - // that this doesn't add the node to any node block. Check::Context::AddNode - // or NodeBlockStack::AddNode should usually be used instead, to add the node - // to the current block. - auto AddInNoBlock(Node node) -> NodeId { return values_.Add(node); } + // Adds an instruction to the instruction list, returning an ID to reference + // the instruction. Note that this doesn't add the instruction to any + // instruction block. Check::Context::AddInst or InstBlockStack::AddInst + // should usually be used instead, to add the instruction to the current + // block. + auto AddInNoBlock(Inst inst) -> InstId { return values_.Add(inst); } - // Returns the requested node. - auto Get(NodeId node_id) const -> Node { return values_.Get(node_id); } + // Returns the requested instruction. + auto Get(InstId inst_id) const -> Inst { return values_.Get(inst_id); } - // Returns the requested node, which is known to have the specified type. - template - auto GetAs(NodeId node_id) const -> NodeT { - return Get(node_id).As(); + // Returns the requested instruction, which is known to have the specified + // type. + template + auto GetAs(InstId inst_id) const -> InstT { + return Get(inst_id).As(); } - // Overwrites a given node with a new value. - auto Set(NodeId node_id, Node node) -> void { values_.Get(node_id) = node; } + // Overwrites a given instruction with a new value. + auto Set(InstId inst_id, Inst inst) -> void { values_.Get(inst_id) = inst; } // Reserves space. auto Reserve(size_t size) -> void { values_.Reserve(size); } - auto array_ref() const -> llvm::ArrayRef { return values_.array_ref(); } + auto array_ref() const -> llvm::ArrayRef { return values_.array_ref(); } auto size() const -> int { return values_.size(); } private: - ValueStore values_; + ValueStore values_; }; // Provides a ValueStore wrapper for an API specific to name scopes. @@ -51,19 +53,19 @@ class NameScopeStore { // Adds an entry to a name scope. Returns true on success, false on // duplicates. - auto AddEntry(NameScopeId scope_id, StringId name_id, NodeId target_id) + auto AddEntry(NameScopeId scope_id, StringId name_id, InstId target_id) -> bool { return values_.Get(scope_id).insert({name_id, target_id}).second; } // Returns the requested name scope. auto Get(NameScopeId scope_id) const - -> const llvm::DenseMap& { + -> const llvm::DenseMap& { return values_.Get(scope_id); } private: - ValueStore> values_; + ValueStore> values_; }; // Provides a block-based ValueStore, which uses slab allocation of added @@ -109,17 +111,17 @@ class BlockValueStore : public Yaml::Printable> { protected: // Reserves and returns a block ID. The contents of the block // should be specified by calling Set, or similar. - auto AddDefaultValue() -> NodeBlockId { return values_.AddDefaultValue(); } + auto AddDefaultValue() -> InstBlockId { return values_.AddDefaultValue(); } // Adds an uninitialized block of the given size. - auto AddUninitialized(size_t size) -> NodeBlockId { + auto AddUninitialized(size_t size) -> InstBlockId { return values_.Add(AllocateUninitialized(size)); } // Sets the contents of an empty block to the given content. - auto Set(NodeBlockId block_id, llvm::ArrayRef content) -> void { + auto Set(InstBlockId block_id, llvm::ArrayRef content) -> void { CARBON_CHECK(Get(block_id).empty()) - << "node block content set more than once"; + << "inst block content set more than once"; values_.Get(block_id) = AllocateCopy(content); } @@ -147,18 +149,18 @@ class BlockValueStore : public Yaml::Printable> { ValueStore> values_; }; -// Adapts BlockValueStore for node blocks. -class NodeBlockStore : public BlockValueStore { +// Adapts BlockValueStore for instruction blocks. +class InstBlockStore : public BlockValueStore { public: - using BaseType = BlockValueStore; + using BaseType = BlockValueStore; using BaseType::AddDefaultValue; using BaseType::AddUninitialized; using BaseType::BaseType; - auto Set(NodeBlockId block_id, llvm::ArrayRef content) -> void { - CARBON_CHECK(block_id != NodeBlockId::Unreachable); - BlockValueStore::Set(block_id, content); + auto Set(InstBlockId block_id, llvm::ArrayRef content) -> void { + CARBON_CHECK(block_id != InstBlockId::Unreachable); + BlockValueStore::Set(block_id, content); } }; diff --git a/toolchain/sem_ir/yaml_test.cpp b/toolchain/sem_ir/yaml_test.cpp index d225ac282882..fa854070c251 100644 --- a/toolchain/sem_ir/yaml_test.cpp +++ b/toolchain/sem_ir/yaml_test.cpp @@ -38,14 +38,14 @@ TEST(SemIRTest, YAML) { d.RunCommand( {"compile", "--phase=check", "--dump-raw-sem-ir", "test.carbon"}); - // Matches the ID of a node. The numbers may change because of builtin + // Matches the ID of an instruction. The numbers may change because of builtin // cross-references, so this code is only doing loose structural checks. auto integer_id = Yaml::Scalar(MatchesRegex(R"(int\d+)")); - auto node_id = Yaml::Scalar(MatchesRegex(R"(node\+\d+)")); - auto node_builtin = Yaml::Scalar(MatchesRegex(R"(node\w+)")); + auto inst_id = Yaml::Scalar(MatchesRegex(R"(inst\+\d+)")); + auto inst_builtin = Yaml::Scalar(MatchesRegex(R"(inst\w+)")); auto type_id = Yaml::Scalar(MatchesRegex(R"(type\d+)")); auto type_builtin = Pair( - type_id, Yaml::Mapping(ElementsAre(Pair("node", node_builtin), + type_id, Yaml::Mapping(ElementsAre(Pair("inst", inst_builtin), Pair("value_rep", Yaml::Mapping(_))))); auto file = Yaml::Mapping(ElementsAre( @@ -54,30 +54,30 @@ TEST(SemIRTest, YAML) { Pair("classes", Yaml::Mapping(SizeIs(0))), Pair("types", Yaml::Mapping(Each(type_builtin))), Pair("type_blocks", Yaml::Mapping(IsEmpty())), - Pair("nodes", + Pair("insts", Yaml::Mapping(AllOf( - Each(Key(node_id)), + Each(Key(inst_id)), // kind is required, other parts are optional. Each(Pair(_, Yaml::Mapping(Contains(Pair("kind", _))))), - // A 0-arg node. + // A 0-arg instruction. Contains( Pair(_, Yaml::Mapping(ElementsAre(Pair("kind", "Return"))))), - // A 1-arg node. + // A 1-arg instruction. Contains(Pair( _, Yaml::Mapping(ElementsAre(Pair("kind", "IntegerLiteral"), Pair("arg0", integer_id), Pair("type", type_id))))), - // A 2-arg node. + // A 2-arg instruction. Contains(Pair( _, Yaml::Mapping(ElementsAre(Pair("kind", "Assign"), - Pair("arg0", node_id), - Pair("arg1", node_id)))))))), - // This production has only two node blocks. - Pair("node_blocks", + Pair("arg0", inst_id), + Pair("arg1", inst_id)))))))), + // This production has only two instruction blocks. + Pair("inst_blocks", Yaml::Mapping(ElementsAre( Pair("block0", Yaml::Mapping(IsEmpty())), - Pair("block1", Yaml::Mapping(Each(Pair(_, node_id)))), - Pair("block2", Yaml::Mapping(Each(Pair(_, node_id))))))))); + Pair("block1", Yaml::Mapping(Each(Pair(_, inst_id)))), + Pair("block2", Yaml::Mapping(Each(Pair(_, inst_id))))))))); auto root = Yaml::Sequence(ElementsAre(Yaml::Mapping( ElementsAre(Pair("filename", "test.carbon"), Pair("sem_ir", file)))));