authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-09 19:50:00+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-19 20:19:00+02:00
log8be69f41328ebc0331434fd9d4008985463188c9
tree01b6f4ae95c57f236d59ad1777324580d54f9f09
parent99422cb5284f3e15c1b5a8598a6b1622c0e7b6ca
signaturelock-open Commit is signed but in an unrecognized format.

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.

1 files changed, 30 insertions(+), 42 deletions(-)

src/arch/wasm/CodeGen.zig+30-42
...@@ -3259,9 +3259,13 @@ fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3259,9 +3259,13 @@ fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3259 .label = func.block_depth,3259 .label = func.block_depth,
3260 .value = block_result,3260 .value = block_result,
3261 });3261 });
3262
3262 try func.genBody(body);3263 try func.genBody(body);
3263 try func.endBlock();3264 try func.endBlock();
32643265
3266 const liveness = func.liveness.getBlock(inst);
3267 try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.deaths.len);
3268
3265 func.finishAir(inst, block_result, &.{});3269 func.finishAir(inst, block_result, &.{});
3266}3270}
32673271
...@@ -3316,41 +3320,27 @@ fn airCondBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3316,41 +3320,27 @@ fn airCondBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3316 try func.addLabel(.br_if, 0);3320 try func.addLabel(.br_if, 0);
33173321
3318 try func.branches.ensureUnusedCapacity(func.gpa, 2);3322 try func.branches.ensureUnusedCapacity(func.gpa, 2);
33193323 {
3320 func.branches.appendAssumeCapacity(.{});3324 func.branches.appendAssumeCapacity(.{});
3321 try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.else_deaths.len));3325 try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.else_deaths.len));
3322 try func.genBody(else_body);3326 try func.genBody(else_body);
3323 try func.endBlock();3327 try func.endBlock();
3324 var else_stack = func.branches.pop();3328 var else_stack = func.branches.pop();
3325 defer else_stack.deinit(func.gpa);3329 else_stack.deinit(func.gpa);
3330 }
33263331
3327 // Outer block that matches the condition3332 // Outer block that matches the condition
3328 func.branches.appendAssumeCapacity(.{});3333 {
3329 try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.then_deaths.len));3334 func.branches.appendAssumeCapacity(.{});
3330 try func.genBody(then_body);3335 try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.then_deaths.len));
3331 var then_stack = func.branches.pop();3336 try func.genBody(then_body);
3332 defer then_stack.deinit(func.gpa);3337 var then_stack = func.branches.pop();
33333338 then_stack.deinit(func.gpa);
3334 try func.mergeBranch(&else_stack);3339 }
3335 try func.mergeBranch(&then_stack);
33363340
3337 func.finishAir(inst, .none, &.{});3341 func.finishAir(inst, .none, &.{});
3338}3342}
33393343
3340fn mergeBranch(func: *CodeGen, branch: *const Branch) !void {
3341 const parent = func.currentBranch();
3342
3343 const target_slice = branch.values.entries.slice();
3344 const target_keys = target_slice.items(.key);
3345 const target_values = target_slice.items(.value);
3346
3347 try parent.values.ensureTotalCapacity(func.gpa, parent.values.capacity() + branch.values.count());
3348 for (target_keys, 0..) |key, index| {
3349 // TODO: process deaths from branches
3350 parent.values.putAssumeCapacity(key, target_values[index]);
3351 }
3352}
3353
3354fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) InnerError!void {3344fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) InnerError!void {
3355 const bin_op = func.air.instructions.items(.data)[inst].bin_op;3345 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
33563346
...@@ -3860,30 +3850,21 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -3860,30 +3850,21 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3860 }3850 }
3861 }3851 }
3862 func.branches.appendAssumeCapacity(.{});3852 func.branches.appendAssumeCapacity(.{});
3863
3864 try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.deaths[index].len);3853 try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.deaths[index].len);
3865 for (liveness.deaths[index]) |operand| {
3866 func.processDeath(Air.indexToRef(operand));
3867 }
3868 try func.genBody(case.body);3854 try func.genBody(case.body);
3869 try func.endBlock();3855 try func.endBlock();
3870 var case_branch = func.branches.pop();3856 var case_branch = func.branches.pop();
3871 defer case_branch.deinit(func.gpa);3857 case_branch.deinit(func.gpa);
3872 try func.mergeBranch(&case_branch);
3873 }3858 }
38743859
3875 if (has_else_body) {3860 if (has_else_body) {
3876 func.branches.appendAssumeCapacity(.{});3861 func.branches.appendAssumeCapacity(.{});
3877 const else_deaths = liveness.deaths.len - 1;3862 const else_deaths = liveness.deaths.len - 1;
3878 try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.deaths[else_deaths].len);3863 try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.deaths[else_deaths].len);
3879 for (liveness.deaths[else_deaths]) |operand| {
3880 func.processDeath(Air.indexToRef(operand));
3881 }
3882 try func.genBody(else_body);3864 try func.genBody(else_body);
3883 try func.endBlock();3865 try func.endBlock();
3884 var else_branch = func.branches.pop();3866 var else_branch = func.branches.pop();
3885 defer else_branch.deinit(func.gpa);3867 else_branch.deinit(func.gpa);
3886 try func.mergeBranch(&else_branch);
3887 }3868 }
3888 func.finishAir(inst, .none, &.{});3869 func.finishAir(inst, .none, &.{});
3889}3870}
...@@ -5992,7 +5973,7 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -5992,7 +5973,7 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5992 const extra = func.air.extraData(Air.Try, pl_op.payload);5973 const extra = func.air.extraData(Air.Try, pl_op.payload);
5993 const body = func.air.extra[extra.end..][0..extra.data.body_len];5974 const body = func.air.extra[extra.end..][0..extra.data.body_len];
5994 const err_union_ty = func.air.typeOf(pl_op.operand);5975 const err_union_ty = func.air.typeOf(pl_op.operand);
5995 const result = try lowerTry(func, err_union, body, err_union_ty, false);5976 const result = try lowerTry(func, inst, err_union, body, err_union_ty, false);
5996 func.finishAir(inst, result, &.{pl_op.operand});5977 func.finishAir(inst, result, &.{pl_op.operand});
5997}5978}
59985979
...@@ -6002,12 +5983,13 @@ fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -6002,12 +5983,13 @@ fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6002 const err_union_ptr = try func.resolveInst(extra.data.ptr);5983 const err_union_ptr = try func.resolveInst(extra.data.ptr);
6003 const body = func.air.extra[extra.end..][0..extra.data.body_len];5984 const body = func.air.extra[extra.end..][0..extra.data.body_len];
6004 const err_union_ty = func.air.typeOf(extra.data.ptr).childType();5985 const err_union_ty = func.air.typeOf(extra.data.ptr).childType();
6005 const result = try lowerTry(func, err_union_ptr, body, err_union_ty, true);5986 const result = try lowerTry(func, inst, err_union_ptr, body, err_union_ty, true);
6006 func.finishAir(inst, result, &.{extra.data.ptr});5987 func.finishAir(inst, result, &.{extra.data.ptr});
6007}5988}
60085989
6009fn lowerTry(5990fn lowerTry(
6010 func: *CodeGen,5991 func: *CodeGen,
5992 inst: Air.Inst.Index,
6011 err_union: WValue,5993 err_union: WValue,
6012 body: []const Air.Inst.Index,5994 body: []const Air.Inst.Index,
6013 err_union_ty: Type,5995 err_union_ty: Type,
...@@ -6035,8 +6017,14 @@ fn lowerTry(...@@ -6035,8 +6017,14 @@ fn lowerTry(
6035 }6017 }
6036 try func.addTag(.i32_eqz);6018 try func.addTag(.i32_eqz);
6037 try func.addLabel(.br_if, 0); // jump out of block when error is '0'6019 try func.addLabel(.br_if, 0); // jump out of block when error is '0'
6020
6021 const liveness = func.liveness.getCondBr(inst);
6022 try func.branches.append(func.gpa, .{});
6023 try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.else_deaths.len + liveness.then_deaths.len);
6038 try func.genBody(body);6024 try func.genBody(body);
6039 try func.endBlock();6025 try func.endBlock();
6026 var branch = func.branches.pop();
6027 branch.deinit(func.gpa);
6040 }6028 }
60416029
6042 // if we reach here it means error was not set, and we want the payload6030 // if we reach here it means error was not set, and we want the payload