mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-04 22:02:52 +01:00
Place the computation of the destination of an initialization into the return slot. (#3252)
Fix a bug where we would perform the computation of the return location in SemIR after we have already used it in some cases, leading to assertion failures during lowering. Instead, accumulate a sequence of instructions to compute the return location in a temporary block, and overwrite the return slot with those instructions when we perform initialization. StubReference is replaced by a more general SpliceBlock node, that takes a code block and a result value, executes the instructions in the block, and produces the result. This is used in the uncommon case where more than one instruction is required to compute the return slot, which can happen if we need to first emit a temporary and then index into it, or if we need to perform multiple levels of indexing before we reach an entity to initialize.
This commit is contained in:
@@ -4,15 +4,18 @@
|
||||
|
||||
#include "toolchain/lower/function_context.h"
|
||||
|
||||
#include "common/vlog.h"
|
||||
#include "toolchain/sem_ir/file.h"
|
||||
|
||||
namespace Carbon::Lower {
|
||||
|
||||
FunctionContext::FunctionContext(FileContext& file_context,
|
||||
llvm::Function* function)
|
||||
llvm::Function* function,
|
||||
llvm::raw_ostream* vlog_stream)
|
||||
: file_context_(&file_context),
|
||||
function_(function),
|
||||
builder_(file_context.llvm_context()) {}
|
||||
builder_(file_context.llvm_context()),
|
||||
vlog_stream_(vlog_stream) {}
|
||||
|
||||
auto FunctionContext::GetBlock(SemIR::NodeBlockId block_id)
|
||||
-> llvm::BasicBlock* {
|
||||
@@ -34,6 +37,22 @@ auto FunctionContext::TryToReuseBlock(SemIR::NodeBlockId block_id,
|
||||
return true;
|
||||
}
|
||||
|
||||
auto FunctionContext::LowerBlock(SemIR::NodeBlockId block_id) -> void {
|
||||
for (const auto& node_id : semantics_ir().GetNodeBlock(block_id)) {
|
||||
auto node = semantics_ir().GetNode(node_id);
|
||||
CARBON_VLOG() << "Lowering " << node_id << ": " << node << "\n";
|
||||
// clang warns on unhandled enum values; clang-tidy is incorrect here.
|
||||
// NOLINTNEXTLINE(bugprone-switch-missing-default-case)
|
||||
switch (node.kind()) {
|
||||
#define CARBON_SEMANTICS_NODE_KIND(Name) \
|
||||
case SemIR::NodeKind::Name: \
|
||||
Handle##Name(*this, node_id, node); \
|
||||
break;
|
||||
#include "toolchain/sem_ir/node_kind.def"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto FunctionContext::GetBlockArg(SemIR::NodeBlockId block_id,
|
||||
SemIR::TypeId type_id) -> llvm::PHINode* {
|
||||
llvm::BasicBlock* block = GetBlock(block_id);
|
||||
|
||||
Reference in New Issue
Block a user