aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-01-22 16:45:09 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-01-31 21:09:22 -0700
commit588171c30b34426fbb07645aa2625e989f369eec (patch)
tree254ff4567279c496dd61a4a790c64c64a8d7e763 /src/Module.zig
parent06bb360dd296288db33844d682188e33116d7ab6 (diff)
downloadzig-588171c30b34426fbb07645aa2625e989f369eec.tar.gz
zig-588171c30b34426fbb07645aa2625e989f369eec.zip
sema: after block gets peer type resolved, insert type coercions
on the break instruction operands. This involves a new TZIR instruction, br_block_flat, which represents a break instruction where the operand is the result of a flat block. See the doc comments on the instructions for more details. How it works: when adding break instructions in semantic analysis, the underlying allocation is slightly padded so that it is the size of a br_block_flat instruction, which allows the break instruction to later be converted without removing instructions inside the parent body. The extra type coercion instructions go into the body of the br_block_flat, and backends are responsible for dispatching the instruction correctly (it should map to the same function calls for related instructions).
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 2dc84a93a9..b7967aacc5 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -671,14 +671,36 @@ pub const Scope = struct {
};
pub const Merges = struct {
- results: ArrayListUnmanaged(*Inst),
block_inst: *Inst.Block,
+ /// Separate array list from break_inst_list so that it can be passed directly
+ /// to resolvePeerTypes.
+ results: ArrayListUnmanaged(*Inst),
+ /// Keeps track of the break instructions so that the operand can be replaced
+ /// if we need to add type coercion at the end of block analysis.
+ /// Same indexes, capacity, length as `results`.
+ br_list: ArrayListUnmanaged(*Inst.Br),
};
/// For debugging purposes.
pub fn dump(self: *Block, mod: Module) void {
zir.dumpBlock(mod, self);
}
+
+ pub fn makeSubBlock(parent: *Block) Block {
+ return .{
+ .parent = parent,
+ .inst_table = parent.inst_table,
+ .func = parent.func,
+ .owner_decl = parent.owner_decl,
+ .src_decl = parent.src_decl,
+ .instructions = .{},
+ .arena = parent.arena,
+ .label = null,
+ .inlining = parent.inlining,
+ .is_comptime = parent.is_comptime,
+ .branch_quota = parent.branch_quota,
+ };
+ }
};
/// This is a temporary structure, references to it are valid only
@@ -2107,7 +2129,7 @@ pub fn addBr(
src: usize,
target_block: *Inst.Block,
operand: *Inst,
-) !*Inst {
+) !*Inst.Br {
const inst = try scope_block.arena.create(Inst.Br);
inst.* = .{
.base = .{
@@ -2119,7 +2141,7 @@ pub fn addBr(
.block = target_block,
};
try scope_block.instructions.append(self.gpa, &inst.base);
- return &inst.base;
+ return inst;
}
pub fn addCondBr(