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...@@ -1162,12 +1162,13 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
11621162
1163 .slice => try airSlice(f, inst),1163 .slice => try airSlice(f, inst),
11641164
1165 .cmp_eq => try airEquality(f, inst, .cmp_eq),
1166 .cmp_gt => try airBinOp(f, inst, " > "),1165 .cmp_gt => try airBinOp(f, inst, " > "),
1167 .cmp_gte => try airBinOp(f, inst, " >= "),1166 .cmp_gte => try airBinOp(f, inst, " >= "),
1168 .cmp_lt => try airBinOp(f, inst, " < "),1167 .cmp_lt => try airBinOp(f, inst, " < "),
1169 .cmp_lte => try airBinOp(f, inst, " <= "),1168 .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
1172 // bool_and and bool_or are non-short-circuit operations1173 // bool_and and bool_or are non-short-circuit operations
1173 .bool_and => try airBinOp(f, inst, " & "),1174 .bool_and => try airBinOp(f, inst, " & "),
...@@ -1908,9 +1909,13 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue...@@ -1908,9 +1909,13 @@ fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue
1908 return local;1909 return local;
1909}1910}
19101911
1911fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue {1912fn airEquality(
1912 if (f.liveness.isUnused(inst))1913 f: *Function,
1913 return CValue.none;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
1915 const bin_op = f.air.instructions.items(.data)[inst].bin_op;1920 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
1916 const lhs = try f.resolveInst(bin_op.lhs);1921 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 {...@@ -1927,7 +1932,7 @@ fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue {
1927 // (A && B) || (C && (A == B))1932 // (A && B) || (C && (A == B))
1928 // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload1933 // 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);
1931 try f.writeCValue(writer, lhs);1936 try f.writeCValue(writer, lhs);
1932 try writer.writeAll(".is_null && ");1937 try writer.writeAll(".is_null && ");
1933 try f.writeCValue(writer, rhs);1938 try f.writeCValue(writer, rhs);
...@@ -1944,9 +1949,8 @@ fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue {...@@ -1944,9 +1949,8 @@ fn airEquality(f: *Function, inst: Air.Inst.Index, op: Air.Inst.Tag) !CValue {
1944 return local;1949 return local;
1945 }1950 }
19461951
1947 const operator = if (op == .cmp_eq) "==" else "!=";
1948 try f.writeCValue(writer, lhs);1952 try f.writeCValue(writer, lhs);
1949 try writer.print("{s}", .{operator});1953 try writer.writeAll(eq_op_str);
1950 try f.writeCValue(writer, rhs);1954 try f.writeCValue(writer, rhs);
1951 try writer.writeAll(";\n");1955 try writer.writeAll(";\n");
19521956