aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-11-23 13:54:08 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-11-23 13:54:08 -0700
commit7ee02b5e70c99159e861cd94adac4707a3315959 (patch)
tree53476730474c176f05286b814495da372a23fa62 /src/codegen
parent2e15a404e287982b261c14240db44af9175f765a (diff)
downloadzig-7ee02b5e70c99159e861cd94adac4707a3315959.tar.gz
zig-7ee02b5e70c99159e861cd94adac4707a3315959.zip
C backend: avoid branching multiple times on AIR tag
for cmp_eq and cmp_neq.
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig20
1 files changed, 12 insertions, 8 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 6f857abff0..5695d22d45 100644
--- 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");