aboutsummaryrefslogtreecommitdiff
path: root/src/arch/wasm/CodeGen.zig
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2023-05-09 19:50:00 +0200
committerLuuk de Gram <luuk@degram.dev>2023-05-19 20:19:00 +0200
commit8be69f41328ebc0331434fd9d4008985463188c9 (patch)
tree01b6f4ae95c57f236d59ad1777324580d54f9f09 /src/arch/wasm/CodeGen.zig
parent99422cb5284f3e15c1b5a8598a6b1622c0e7b6ca (diff)
downloadzig-8be69f41328ebc0331434fd9d4008985463188c9.tar.gz
zig-8be69f41328ebc0331434fd9d4008985463188c9.zip
wasm: simplify merging of branches
Rather than adding all values that were generated in the child branch, we simply discard them as outer branches cannot refer to values produced from an inner branch.
Diffstat (limited to 'src/arch/wasm/CodeGen.zig')
-rw-r--r--src/arch/wasm/CodeGen.zig72
1 files changed, 30 insertions, 42 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index f602cf80a7..04b9b7194c 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -3259,9 +3259,13 @@ fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
.label = func.block_depth,
.value = block_result,
});
+
try func.genBody(body);
try func.endBlock();
+ const liveness = func.liveness.getBlock(inst);
+ try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.deaths.len);
+
func.finishAir(inst, block_result, &.{});
}
@@ -3316,41 +3320,27 @@ fn airCondBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
try func.addLabel(.br_if, 0);
try func.branches.ensureUnusedCapacity(func.gpa, 2);
-
- func.branches.appendAssumeCapacity(.{});
- try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.else_deaths.len));
- try func.genBody(else_body);
- try func.endBlock();
- var else_stack = func.branches.pop();
- defer else_stack.deinit(func.gpa);
+ {
+ func.branches.appendAssumeCapacity(.{});
+ try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.else_deaths.len));
+ try func.genBody(else_body);
+ try func.endBlock();
+ var else_stack = func.branches.pop();
+ else_stack.deinit(func.gpa);
+ }
// Outer block that matches the condition
- func.branches.appendAssumeCapacity(.{});
- try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.then_deaths.len));
- try func.genBody(then_body);
- var then_stack = func.branches.pop();
- defer then_stack.deinit(func.gpa);
-
- try func.mergeBranch(&else_stack);
- try func.mergeBranch(&then_stack);
+ {
+ func.branches.appendAssumeCapacity(.{});
+ try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.then_deaths.len));
+ try func.genBody(then_body);
+ var then_stack = func.branches.pop();
+ then_stack.deinit(func.gpa);
+ }
func.finishAir(inst, .none, &.{});
}
-fn mergeBranch(func: *CodeGen, branch: *const Branch) !void {
- const parent = func.currentBranch();
-
- const target_slice = branch.values.entries.slice();
- const target_keys = target_slice.items(.key);
- const target_values = target_slice.items(.value);
-
- try parent.values.ensureTotalCapacity(func.gpa, parent.values.capacity() + branch.values.count());
- for (target_keys, 0..) |key, index| {
- // TODO: process deaths from branches
- parent.values.putAssumeCapacity(key, target_values[index]);
- }
-}
-
fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
@@ -3860,30 +3850,21 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
}
}
func.branches.appendAssumeCapacity(.{});
-
try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.deaths[index].len);
- for (liveness.deaths[index]) |operand| {
- func.processDeath(Air.indexToRef(operand));
- }
try func.genBody(case.body);
try func.endBlock();
var case_branch = func.branches.pop();
- defer case_branch.deinit(func.gpa);
- try func.mergeBranch(&case_branch);
+ case_branch.deinit(func.gpa);
}
if (has_else_body) {
func.branches.appendAssumeCapacity(.{});
const else_deaths = liveness.deaths.len - 1;
try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.deaths[else_deaths].len);
- for (liveness.deaths[else_deaths]) |operand| {
- func.processDeath(Air.indexToRef(operand));
- }
try func.genBody(else_body);
try func.endBlock();
var else_branch = func.branches.pop();
- defer else_branch.deinit(func.gpa);
- try func.mergeBranch(&else_branch);
+ else_branch.deinit(func.gpa);
}
func.finishAir(inst, .none, &.{});
}
@@ -5992,7 +5973,7 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const extra = func.air.extraData(Air.Try, pl_op.payload);
const body = func.air.extra[extra.end..][0..extra.data.body_len];
const err_union_ty = func.air.typeOf(pl_op.operand);
- const result = try lowerTry(func, err_union, body, err_union_ty, false);
+ const result = try lowerTry(func, inst, err_union, body, err_union_ty, false);
func.finishAir(inst, result, &.{pl_op.operand});
}
@@ -6002,12 +5983,13 @@ fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const err_union_ptr = try func.resolveInst(extra.data.ptr);
const body = func.air.extra[extra.end..][0..extra.data.body_len];
const err_union_ty = func.air.typeOf(extra.data.ptr).childType();
- const result = try lowerTry(func, err_union_ptr, body, err_union_ty, true);
+ const result = try lowerTry(func, inst, err_union_ptr, body, err_union_ty, true);
func.finishAir(inst, result, &.{extra.data.ptr});
}
fn lowerTry(
func: *CodeGen,
+ inst: Air.Inst.Index,
err_union: WValue,
body: []const Air.Inst.Index,
err_union_ty: Type,
@@ -6035,8 +6017,14 @@ fn lowerTry(
}
try func.addTag(.i32_eqz);
try func.addLabel(.br_if, 0); // jump out of block when error is '0'
+
+ const liveness = func.liveness.getCondBr(inst);
+ try func.branches.append(func.gpa, .{});
+ try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.else_deaths.len + liveness.then_deaths.len);
try func.genBody(body);
try func.endBlock();
+ var branch = func.branches.pop();
+ branch.deinit(func.gpa);
}
// if we reach here it means error was not set, and we want the payload