aboutsummaryrefslogtreecommitdiff
path: root/src/arch/wasm/CodeGen.zig
diff options
context:
space:
mode:
authorMatthew Lugg <mlugg@mlugg.co.uk>2024-08-27 06:10:56 +0100
committerGitHub <noreply@github.com>2024-08-27 06:10:56 +0100
commitd3c6f7179c7a6086ab9cdbaed231da9a1f0b4dee (patch)
treea75bc8abc129a679fce0673165e04fa7283f2823 /src/arch/wasm/CodeGen.zig
parentd9147b91a601ad2442aaa43f4dba2d01b25d803d (diff)
parent4c0f021c2e4270c7392df7250a5d8f2431dcc54f (diff)
downloadzig-d3c6f7179c7a6086ab9cdbaed231da9a1f0b4dee.tar.gz
zig-d3c6f7179c7a6086ab9cdbaed231da9a1f0b4dee.zip
Merge pull request #21214 from mlugg/branch-hint-and-export
Implement `@branchHint` and new `@export` usage
Diffstat (limited to 'src/arch/wasm/CodeGen.zig')
-rw-r--r--src/arch/wasm/CodeGen.zig36
1 files changed, 16 insertions, 20 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index f36df7c444..fbe63925dc 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -1913,7 +1913,9 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
.get_union_tag => func.airGetUnionTag(inst),
.@"try" => func.airTry(inst),
+ .try_cold => func.airTry(inst),
.try_ptr => func.airTryPtr(inst),
+ .try_ptr_cold => func.airTryPtr(inst),
.dbg_stmt => func.airDbgStmt(inst),
.dbg_inline_block => func.airDbgInlineBlock(inst),
@@ -4041,37 +4043,31 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
const zcu = pt.zcu;
// result type is always 'noreturn'
const blocktype = wasm.block_empty;
- const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
- const target = try func.resolveInst(pl_op.operand);
- const target_ty = func.typeOf(pl_op.operand);
- const switch_br = func.air.extraData(Air.SwitchBr, pl_op.payload);
- const liveness = try func.liveness.getSwitchBr(func.gpa, inst, switch_br.data.cases_len + 1);
+ const switch_br = func.air.unwrapSwitch(inst);
+ const target = try func.resolveInst(switch_br.operand);
+ const target_ty = func.typeOf(switch_br.operand);
+ const liveness = try func.liveness.getSwitchBr(func.gpa, inst, switch_br.cases_len + 1);
defer func.gpa.free(liveness.deaths);
- var extra_index: usize = switch_br.end;
- var case_i: u32 = 0;
-
// a list that maps each value with its value and body based on the order inside the list.
const CaseValue = struct { integer: i32, value: Value };
var case_list = try std.ArrayList(struct {
values: []const CaseValue,
body: []const Air.Inst.Index,
- }).initCapacity(func.gpa, switch_br.data.cases_len);
+ }).initCapacity(func.gpa, switch_br.cases_len);
defer for (case_list.items) |case| {
func.gpa.free(case.values);
} else case_list.deinit();
var lowest_maybe: ?i32 = null;
var highest_maybe: ?i32 = null;
- while (case_i < switch_br.data.cases_len) : (case_i += 1) {
- const case = func.air.extraData(Air.SwitchBr.Case, extra_index);
- const items: []const Air.Inst.Ref = @ptrCast(func.air.extra[case.end..][0..case.data.items_len]);
- const case_body: []const Air.Inst.Index = @ptrCast(func.air.extra[case.end + items.len ..][0..case.data.body_len]);
- extra_index = case.end + items.len + case_body.len;
- const values = try func.gpa.alloc(CaseValue, items.len);
+
+ var it = switch_br.iterateCases();
+ while (it.next()) |case| {
+ const values = try func.gpa.alloc(CaseValue, case.items.len);
errdefer func.gpa.free(values);
- for (items, 0..) |ref, i| {
+ for (case.items, 0..) |ref, i| {
const item_val = (try func.air.value(ref, pt)).?;
const int_val = func.valueAsI32(item_val);
if (lowest_maybe == null or int_val < lowest_maybe.?) {
@@ -4083,7 +4079,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
values[i] = .{ .integer = int_val, .value = item_val };
}
- case_list.appendAssumeCapacity(.{ .values = values, .body = case_body });
+ case_list.appendAssumeCapacity(.{ .values = values, .body = case.body });
try func.startBlock(.block, blocktype);
}
@@ -4097,7 +4093,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
// TODO: Benchmark this to find a proper value, LLVM seems to draw the line at '40~45'.
const is_sparse = highest - lowest > 50 or target_ty.bitSize(zcu) > 32;
- const else_body: []const Air.Inst.Index = @ptrCast(func.air.extra[extra_index..][0..switch_br.data.else_body_len]);
+ const else_body = it.elseBody();
const has_else_body = else_body.len != 0;
if (has_else_body) {
try func.startBlock(.block, blocktype);
@@ -4140,11 +4136,11 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
// for errors that are not present in any branch. This is fine as this default
// case will never be hit for those cases but we do save runtime cost and size
// by using a jump table for this instead of if-else chains.
- break :blk if (has_else_body or target_ty.zigTypeTag(zcu) == .ErrorSet) case_i else unreachable;
+ break :blk if (has_else_body or target_ty.zigTypeTag(zcu) == .ErrorSet) switch_br.cases_len else unreachable;
};
func.mir_extra.appendAssumeCapacity(idx);
} else if (has_else_body) {
- func.mir_extra.appendAssumeCapacity(case_i); // default branch
+ func.mir_extra.appendAssumeCapacity(switch_br.cases_len); // default branch
}
try func.endBlock();
}