From c83eea3ce2e1f135263fa5cafe76b3318cde7a8f Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Thu, 1 Jun 2023 15:10:46 -0700 Subject: [PATCH] Switch nodes to a map, and relabel as locals. (#2861) The "locals" naming is intended to reflect that I haven't really thought through how globals work, but suspect they're going to end up at least partially separated. Stepping away from the "node" naming feels like it'll reduce confusion, although maybe "values" might be better? (but values seems imperfect in the presence of globals) The map is the more important part here; I want to avoid anchoring on the prior vector approach. --- toolchain/lowering/lowering_context.cpp | 7 +++--- toolchain/lowering/lowering_context.h | 31 ++++++++++++------------- toolchain/lowering/lowering_handle.cpp | 28 +++++++++++----------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/toolchain/lowering/lowering_context.cpp b/toolchain/lowering/lowering_context.cpp index d13799eadab9..764763d5a165 100644 --- a/toolchain/lowering/lowering_context.cpp +++ b/toolchain/lowering/lowering_context.cpp @@ -19,7 +19,6 @@ LoweringContext::LoweringContext(llvm::LLVMContext& llvm_context, builder_(llvm_context), semantics_ir_(&semantics_ir), vlog_stream_(vlog_stream), - nodes_(semantics_ir_->nodes_size(), nullptr), callables_(semantics_ir_->callables_size(), nullptr) { CARBON_CHECK(!semantics_ir.has_errors()) << "Generating LLVM IR from invalid SemanticsIR is unsupported."; @@ -58,6 +57,8 @@ auto LoweringContext::LowerBlock(SemanticsNodeBlockId block_id) -> void { #include "toolchain/semantics/semantics_node_kind.def" } } + + locals_.clear(); } auto LoweringContext::BuildType(SemanticsNodeId node_id) -> llvm::Type* { @@ -102,8 +103,8 @@ auto LoweringContext::BuildType(SemanticsNodeId node_id) -> llvm::Type* { } } -auto LoweringContext::GetNodeLoaded(SemanticsNodeId node_id) -> llvm::Value* { - auto* value = GetNode(node_id); +auto LoweringContext::GetLocalLoaded(SemanticsNodeId node_id) -> llvm::Value* { + auto* value = GetLocal(node_id); if (llvm::isa(value)) { auto* load_type = GetType(semantics_ir().GetNode(node_id).type_id()); return builder().CreateLoad(load_type, value); diff --git a/toolchain/lowering/lowering_context.h b/toolchain/lowering/lowering_context.h index 3906c70262ec..20927db49f06 100644 --- a/toolchain/lowering/lowering_context.h +++ b/toolchain/lowering/lowering_context.h @@ -25,20 +25,21 @@ class LoweringContext { // the main execution loop. auto Run() -> std::unique_ptr; - // Returns a value for the given node. - auto GetNode(SemanticsNodeId node_id) -> llvm::Value* { - CARBON_CHECK(nodes_[node_id.index]) << node_id; - return nodes_[node_id.index]; + // Returns a local (versus global) value for the given node. + auto GetLocal(SemanticsNodeId node_id) -> llvm::Value* { + auto it = locals_.find(node_id); + CARBON_CHECK(it != locals_.end()) << "Missing local: " << node_id; + return it->second; } - // Returns a value for the given node in loaded state. Loads will only be - // inserted on an as-needed basis. - auto GetNodeLoaded(SemanticsNodeId node_id) -> llvm::Value*; + // Returns a local (versus global) value for the given node in loaded state. + // Loads will only be inserted on an as-needed basis. + auto GetLocalLoaded(SemanticsNodeId node_id) -> llvm::Value*; // Sets the value for the given node. - auto SetNode(SemanticsNodeId node_id, llvm::Value* value) { - CARBON_CHECK(!nodes_[node_id.index]) << node_id; - nodes_[node_id.index] = value; + auto SetLocal(SemanticsNodeId node_id, llvm::Value* value) { + bool added = locals_.insert({node_id, value}).second; + CARBON_CHECK(added) << "Duplicate local insert: " << node_id; } // Gets a callable's function. @@ -92,12 +93,10 @@ class LoweringContext { llvm::SmallVector> todo_blocks_; - // Maps nodes in SemanticsIR to a lowered value. This will have one entry per - // node, and will be non-null when lowered. It's expected to be sparse during - // execution because while expressions will have entries, statements won't. - // TODO: This is transitioning to only track global and local values, rather - // than one large map for all nodes. - llvm::SmallVector nodes_; + // Maps a function's SemanticsIR nodes to lowered values. + // TODO: Handle nested scopes. Right now this is just cleared at the end of + // every block. + llvm::DenseMap locals_; // Maps callables to lowered functions. Semantics treats callables as the // canonical form of a function, so lowering needs to do the same. diff --git a/toolchain/lowering/lowering_handle.cpp b/toolchain/lowering/lowering_handle.cpp index a1d0bfcbd8e4..7c456d98f695 100644 --- a/toolchain/lowering/lowering_handle.cpp +++ b/toolchain/lowering/lowering_handle.cpp @@ -21,8 +21,8 @@ auto LoweringHandleCrossReference(LoweringContext& /*context*/, auto LoweringHandleAssign(LoweringContext& context, SemanticsNodeId /*node_id*/, SemanticsNode node) -> void { auto [storage_id, value_id] = node.GetAsAssign(); - context.builder().CreateStore(context.GetNodeLoaded(value_id), - context.GetNode(storage_id)); + context.builder().CreateStore(context.GetLocalLoaded(value_id), + context.GetLocal(storage_id)); } auto LoweringHandleBinaryOperatorAdd(LoweringContext& /*context*/, @@ -49,11 +49,11 @@ auto LoweringHandleCall(LoweringContext& context, SemanticsNodeId node_id, auto* function = context.GetCallable(callable_id); std::vector args; for (auto ref_id : context.semantics_ir().GetNodeBlock(refs_id)) { - args.push_back(context.GetNodeLoaded(ref_id)); + args.push_back(context.GetLocalLoaded(ref_id)); } auto* value = context.builder().CreateCall(function, args, function->getName()); - context.SetNode(node_id, value); + context.SetLocal(node_id, value); } auto LoweringHandleCodeBlock(LoweringContext& /*context*/, @@ -121,7 +121,7 @@ auto LoweringHandleIntegerLiteral(LoweringContext& context, // TODO: This won't offer correct semantics, but seems close enough for now. llvm::Value* v = llvm::ConstantInt::get(context.builder().getInt32Ty(), i.getSExtValue()); - context.SetNode(node_id, v); + context.SetLocal(node_id, v); } auto LoweringHandleRealLiteral(LoweringContext& context, @@ -134,8 +134,8 @@ auto LoweringHandleRealLiteral(LoweringContext& context, real.mantissa.getSExtValue() * std::pow((real.is_decimal ? 10 : 2), real.exponent.getSExtValue()); llvm::APFloat llvm_val(val); - context.SetNode(node_id, llvm::ConstantFP::get( - context.builder().getDoubleTy(), llvm_val)); + context.SetLocal(node_id, llvm::ConstantFP::get( + context.builder().getDoubleTy(), llvm_val)); } auto LoweringHandleReturn(LoweringContext& context, SemanticsNodeId /*node_id*/, @@ -147,7 +147,7 @@ auto LoweringHandleReturnExpression(LoweringContext& context, SemanticsNodeId /*node_id*/, SemanticsNode node) -> void { SemanticsNodeId expr_id = node.GetAsReturnExpression(); - context.builder().CreateRet(context.GetNodeLoaded(expr_id)); + context.builder().CreateRet(context.GetLocalLoaded(expr_id)); } auto LoweringHandleStringLiteral(LoweringContext& /*context*/, @@ -174,8 +174,8 @@ auto LoweringHandleStructMemberAccess(LoweringContext& context, .GetAsStructTypeField()); auto* gep = context.builder().CreateStructGEP( - llvm_type, context.GetNode(struct_id), member_index.index, member_name); - context.SetNode(node_id, gep); + llvm_type, context.GetLocal(struct_id), member_index.index, member_name); + context.SetLocal(node_id, gep); } auto LoweringHandleStructType(LoweringContext& /*context*/, @@ -196,7 +196,7 @@ auto LoweringHandleStructValue(LoweringContext& context, auto* llvm_type = context.GetType(node.type_id()); auto* alloca = context.builder().CreateAlloca( llvm_type, /*ArraySize=*/nullptr, "StructLiteralValue"); - context.SetNode(node_id, alloca); + context.SetLocal(node_id, alloca); auto refs = context.semantics_ir().GetNodeBlock(node.GetAsStructValue()); // Get type information for member names. @@ -209,14 +209,14 @@ auto LoweringHandleStructValue(LoweringContext& context, context.semantics_ir().GetNode(type_refs[i]).GetAsStructTypeField()); auto* gep = context.builder().CreateStructGEP(llvm_type, alloca, i, member_name); - context.builder().CreateStore(context.GetNode(refs[i]), gep); + context.builder().CreateStore(context.GetLocal(refs[i]), gep); } } auto LoweringHandleStubReference(LoweringContext& context, SemanticsNodeId node_id, SemanticsNode node) -> void { - context.SetNode(node_id, context.GetNode(node.GetAsStubReference())); + context.SetLocal(node_id, context.GetLocal(node.GetAsStubReference())); } auto LoweringHandleVarStorage(LoweringContext& context, SemanticsNodeId node_id, @@ -229,7 +229,7 @@ auto LoweringHandleVarStorage(LoweringContext& context, SemanticsNodeId node_id, // storage? auto* alloca = context.builder().CreateAlloca(context.GetType(node.type_id()), /*ArraySize=*/nullptr, "var"); - context.SetNode(node_id, alloca); + context.SetLocal(node_id, alloca); } } // namespace Carbon