Add GlobalInit to blocks to emit initialization instructions for globals (#3687)

`GlobalInit` block is now static block within a `SemIR` which will be
used to emit initialization instructions for variables in the `Package`
scope.

inst_block_stack now has additional methods to handle `GlobalInit` block
separately, this block can be popped without being finalized allowing to
accumulate between all instances of variables.

At the end of the `check` phase, if this block is not empty , the
function `__global_init` will be added with this block being inserted
into it.

This block is pushed to `inst_block_scope` at the end `BindName`,
allowing instruction to be emitted into it, then popped at the semicolon
(VariableDecl).

This significantly changes the `SemIR` output, that's why this commit
updates a lot of the test cases.
This commit is contained in:
Gıyaseddin Tanrıkulu
2024-02-09 16:21:57 +00:00
committed by GitHub
parent 475ecca339
commit bdff7ccf28
94 changed files with 1256 additions and 604 deletions
+13
View File
@@ -21,6 +21,11 @@ auto InstBlockStack::Push(SemIR::InstBlockId id) -> void {
++size_;
}
auto InstBlockStack::PushGlobalInit() -> void {
Push(SemIR::InstBlockId::GlobalInit);
stack_[size_ - 1].content = std::move(init_block_);
}
auto InstBlockStack::PeekOrAdd(int depth) -> SemIR::InstBlockId {
CARBON_CHECK(size() > depth) << "no such block";
int index = size() - depth - 1;
@@ -52,6 +57,14 @@ auto InstBlockStack::Pop() -> SemIR::InstBlockId {
return back.id;
}
auto InstBlockStack::PopGlobalInit() -> void {
CARBON_CHECK(stack_[size_ - 1].id == SemIR::InstBlockId::GlobalInit)
<< "Trying to pop Inits block from " << name_
<< " but a different block is present!";
init_block_ = std::move(stack_[size_ - 1].content);
PopAndDiscard();
}
auto InstBlockStack::PopAndDiscard() -> void {
CARBON_CHECK(!empty()) << "no current block";
--size_;