authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-23 13:54:08-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-23 13:54:08-07:00
log7ee02b5e70c99159e861cd94adac4707a3315959
tree53476730474c176f05286b814495da372a23fa62
parent2e15a404e287982b261c14240db44af9175f765a

C backend: avoid branching multiple times on AIR tag

for cmp_eq and cmp_neq.

1 files changed, 12 insertions(+), 8 deletions(-)

src/codegen/c.zig+12-8
......@@ -1162,12 +1162,13 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
11621162
11631163 .slice => try airSlice(f, inst),
11641164
1165 .cmp_eq => try airEquality(f, inst, .cmp_eq),
11661165 .cmp_gt => try airBinOp(f, inst, " > "),
11671166 .cmp_gte => try airBinOp(f, inst, " >= "),
11681167 .cmp_lt => try airBinOp(f, inst, " < "),
11691168 .cmp_lte => try airBinOp(f, inst, " <= "),
1170 .cmp_neq => try airEquality(f, inst, .cmp_neq),
1169
1170 .cmp_eq => try airEquality(f, inst, "((", "=="),
1171 .cmp_neq => try airEquality(f, inst, "!((", "!="),
11711172
11721173 // bool_and and bool_or are non-short-circuit operations
11731174 .bool_and => try airBinOp(f, inst, " & "),
......@@ -1908,9 +1909,13 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue
19081909 return local;
19091910}
19101911
1911fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue {
1912 if (f.liveness.isUnused(inst))
1913 return CValue.none;
1912fn airEquality(
1913 f: *Function,
1914 inst: Air.Inst.Index,
1915 negate_prefix: []const u8,
1916 eq_op_str: []const u8,
1917) !CValue {
1918 if (f.liveness.isUnused(inst)) return CValue.none;
19141919
19151920 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
19161921 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 {
19271932 // (A && B) || (C && (A == B))
19281933 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload
19291934
1930 try writer.writeAll(if (op == .cmp_eq) "((" else "!((");
1935 try writer.writeAll(negate_prefix);
19311936 try f.writeCValue(writer, lhs);
19321937 try writer.writeAll(".is_null && ");
19331938 try f.writeCValue(writer, rhs);
......@@ -1944,9 +1949,8 @@ fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue {
19441949 return local;
19451950 }
19461951
1947 const operator = if (op == .cmp_eq) "==" else "!=";
19481952 try f.writeCValue(writer, lhs);
1949 try writer.print("{s}", .{operator});
1953 try writer.writeAll(eq_op_str);
19501954 try f.writeCValue(writer, rhs);
19511955 try writer.writeAll(";\n");
19521956