| ... | ... | @@ -3259,9 +3259,13 @@ fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3259 | 3259 | .label = func.block_depth, |
| 3260 | 3260 | .value = block_result, |
| 3261 | 3261 | }); |
| 3262 | |
| 3262 | 3263 | try func.genBody(body); |
| 3263 | 3264 | try func.endBlock(); |
| 3264 | 3265 | |
| 3266 | const liveness = func.liveness.getBlock(inst); |
| 3267 | try func.currentBranch().values.ensureUnusedCapacity(func.gpa, liveness.deaths.len); |
| 3268 | |
| 3265 | 3269 | func.finishAir(inst, block_result, &.{}); |
| 3266 | 3270 | } |
| 3267 | 3271 | |
| ... | ... | @@ -3316,41 +3320,27 @@ fn airCondBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3316 | 3320 | try func.addLabel(.br_if, 0); |
| 3317 | 3321 | |
| 3318 | 3322 | try func.branches.ensureUnusedCapacity(func.gpa, 2); |
| 3319 | | |
| 3320 | | func.branches.appendAssumeCapacity(.{}); |
| 3321 | | try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.else_deaths.len)); |
| 3322 | | try func.genBody(else_body); |
| 3323 | | try func.endBlock(); |
| 3324 | | var else_stack = func.branches.pop(); |
| 3325 | | defer else_stack.deinit(func.gpa); |
| 3323 | { |
| 3324 | func.branches.appendAssumeCapacity(.{}); |
| 3325 | try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.else_deaths.len)); |
| 3326 | try func.genBody(else_body); |
| 3327 | try func.endBlock(); |
| 3328 | var else_stack = func.branches.pop(); |
| 3329 | else_stack.deinit(func.gpa); |
| 3330 | } |
| 3326 | 3331 | |
| 3327 | 3332 | // Outer block that matches the condition |
| 3328 | | func.branches.appendAssumeCapacity(.{}); |
| 3329 | | try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.then_deaths.len)); |
| 3330 | | try func.genBody(then_body); |
| 3331 | | var then_stack = func.branches.pop(); |
| 3332 | | defer then_stack.deinit(func.gpa); |
| 3333 | | |
| 3334 | | try func.mergeBranch(&else_stack); |
| 3335 | | try func.mergeBranch(&then_stack); |
| 3333 | { |
| 3334 | func.branches.appendAssumeCapacity(.{}); |
| 3335 | try func.currentBranch().values.ensureUnusedCapacity(func.gpa, @intCast(u32, liveness_condbr.then_deaths.len)); |
| 3336 | try func.genBody(then_body); |
| 3337 | var then_stack = func.branches.pop(); |
| 3338 | then_stack.deinit(func.gpa); |
| 3339 | } |
| 3336 | 3340 | |
| 3337 | 3341 | func.finishAir(inst, .none, &.{}); |
| 3338 | 3342 | } |
| 3339 | 3343 | |
| 3340 | | fn 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 | | |
| 3354 | 3344 | fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) InnerError!void { |
| 3355 | 3345 | const bin_op = func.air.instructions.items(.data)[inst].bin_op; |
| 3356 | 3346 | |
| ... | ... | @@ -3860,30 +3850,21 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3860 | 3850 | } |
| 3861 | 3851 | } |
| 3862 | 3852 | func.branches.appendAssumeCapacity(.{}); |
| 3863 | | |
| 3864 | 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 | 3854 | try func.genBody(case.body); |
| 3869 | 3855 | try func.endBlock(); |
| 3870 | 3856 | var case_branch = func.branches.pop(); |
| 3871 | | defer case_branch.deinit(func.gpa); |
| 3872 | | try func.mergeBranch(&case_branch); |
| 3857 | case_branch.deinit(func.gpa); |
| 3873 | 3858 | } |
| 3874 | 3859 | |
| 3875 | 3860 | if (has_else_body) { |
| 3876 | 3861 | func.branches.appendAssumeCapacity(.{}); |
| 3877 | 3862 | const else_deaths = liveness.deaths.len - 1; |
| 3878 | 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 | 3864 | try func.genBody(else_body); |
| 3883 | 3865 | try func.endBlock(); |
| 3884 | 3866 | var else_branch = func.branches.pop(); |
| 3885 | | defer else_branch.deinit(func.gpa); |
| 3886 | | try func.mergeBranch(&else_branch); |
| 3867 | else_branch.deinit(func.gpa); |
| 3887 | 3868 | } |
| 3888 | 3869 | func.finishAir(inst, .none, &.{}); |
| 3889 | 3870 | } |
| ... | ... | @@ -5992,7 +5973,7 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5992 | 5973 | const extra = func.air.extraData(Air.Try, pl_op.payload); |
| 5993 | 5974 | const body = func.air.extra[extra.end..][0..extra.data.body_len]; |
| 5994 | 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 | 5977 | func.finishAir(inst, result, &.{pl_op.operand}); |
| 5997 | 5978 | } |
| 5998 | 5979 | |
| ... | ... | @@ -6002,12 +5983,13 @@ fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6002 | 5983 | const err_union_ptr = try func.resolveInst(extra.data.ptr); |
| 6003 | 5984 | const body = func.air.extra[extra.end..][0..extra.data.body_len]; |
| 6004 | 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 | 5987 | func.finishAir(inst, result, &.{extra.data.ptr}); |
| 6007 | 5988 | } |
| 6008 | 5989 | |
| 6009 | 5990 | fn lowerTry( |
| 6010 | 5991 | func: *CodeGen, |
| 5992 | inst: Air.Inst.Index, |
| 6011 | 5993 | err_union: WValue, |
| 6012 | 5994 | body: []const Air.Inst.Index, |
| 6013 | 5995 | err_union_ty: Type, |
| ... | ... | @@ -6035,8 +6017,14 @@ fn lowerTry( |
| 6035 | 6017 | } |
| 6036 | 6018 | try func.addTag(.i32_eqz); |
| 6037 | 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 | 6024 | try func.genBody(body); |
| 6039 | 6025 | try func.endBlock(); |
| 6026 | var branch = func.branches.pop(); |
| 6027 | branch.deinit(func.gpa); |
| 6040 | 6028 | } |
| 6041 | 6029 | |
| 6042 | 6030 | // if we reach here it means error was not set, and we want the payload |