zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 7ee02b5e70c99159e861cd94adac4707a3315959 (tree)
parent 2e15a404e287982b261c14240db44af9175f765a
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Tue, 23 Nov 2021 13:54:08 -0700

C backend: avoid branching multiple times on AIR tag

for cmp_eq and cmp_neq.

Diffstat:
Msrc/codegen/c.zig | 20++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/codegen/c.zig b/src/codegen/c.zig @@ -1162,12 +1162,13 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .slice => try airSlice(f, inst), - .cmp_eq => try airEquality(f, inst, .cmp_eq), .cmp_gt => try airBinOp(f, inst, " > "), .cmp_gte => try airBinOp(f, inst, " >= "), .cmp_lt => try airBinOp(f, inst, " < "), .cmp_lte => try airBinOp(f, inst, " <= "), - .cmp_neq => try airEquality(f, inst, .cmp_neq), + + .cmp_eq => try airEquality(f, inst, "((", "=="), + .cmp_neq => try airEquality(f, inst, "!((", "!="), // bool_and and bool_or are non-short-circuit operations .bool_and => try airBinOp(f, inst, " & "), @@ -1908,9 +1909,13 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue return local; } -fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue { - if (f.liveness.isUnused(inst)) - return CValue.none; +fn airEquality( + f: *Function, + inst: Air.Inst.Index, + negate_prefix: []const u8, + eq_op_str: []const u8, +) !CValue { + if (f.liveness.isUnused(inst)) return CValue.none; const bin_op = f.air.instructions.items(.data)[inst].bin_op; const lhs = try f.resolveInst(bin_op.lhs); @@ -1927,7 +1932,7 @@ fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue { // (A && B) || (C && (A == B)) // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload - try writer.writeAll(if (op == .cmp_eq) "((" else "!(("); + try writer.writeAll(negate_prefix); try f.writeCValue(writer, lhs); try writer.writeAll(".is_null && "); try f.writeCValue(writer, rhs); @@ -1944,9 +1949,8 @@ fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue { return local; } - const operator = if (op == .cmp_eq) "==" else "!="; try f.writeCValue(writer, lhs); - try writer.print("{s}", .{operator}); + try writer.writeAll(eq_op_str); try f.writeCValue(writer, rhs); try writer.writeAll(";\n");