authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-03-04 19:19:26+01:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-03-04 23:28:14+01:00
logd486a7b81188ea1e027334c81589157efde2ad23
tree364b3c5bd98adfd2650b292f8e67c52c0cb45dba
parent7605166426527c7d169ecad89d8de6799935f5ca

stage2 ARM: generate less no-op branches

The checks detecting such no-op branches (essentially instructions that branch to the instruction immediately following the branch) were tightened to catch more of these occurrences.

9 files changed, 23 insertions(+), 25 deletions(-)

src/arch/arm/CodeGen.zig+23-12
...@@ -445,16 +445,17 @@ fn gen(self: *Self) !void {...@@ -445,16 +445,17 @@ fn gen(self: *Self) !void {
445 });445 });
446446
447 // exitlude jumps447 // exitlude jumps
448 const only_one_exitlude_jump = self.exitlude_jump_relocs.items.len == 1 and448 if (self.exitlude_jump_relocs.items.len > 0 and
449 self.exitlude_jump_relocs.items[0] == self.mir_instructions.len - 1;449 self.exitlude_jump_relocs.items[self.exitlude_jump_relocs.items.len - 1] == self.mir_instructions.len - 2)
450 if (only_one_exitlude_jump) {450 {
451 // There is only one relocation. Hence,451 // If the last Mir instruction (apart from the
452 // this relocation must be at the end of452 // dbg_epilogue_begin) is the last exitlude jump
453 // the code. Therefore, we can just delete453 // relocation (which would just jump one instruction
454 // the space initially reserved for the454 // further), it can be safely removed
455 // jump455 self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.pop());
456 self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.items[0]);456 }
457 } else for (self.exitlude_jump_relocs.items) |jmp_reloc| {457
458 for (self.exitlude_jump_relocs.items) |jmp_reloc| {
458 self.mir_instructions.set(jmp_reloc, .{459 self.mir_instructions.set(jmp_reloc, .{
459 .tag = .b,460 .tag = .b,
460 .data = .{ .inst = @intCast(u32, self.mir_instructions.len) },461 .data = .{ .inst = @intCast(u32, self.mir_instructions.len) },
...@@ -3197,7 +3198,17 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -3197,7 +3198,17 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
3197 const body = self.air.extra[extra.end..][0..extra.data.body_len];3198 const body = self.air.extra[extra.end..][0..extra.data.body_len];
3198 try self.genBody(body);3199 try self.genBody(body);
31993200
3200 for (self.blocks.getPtr(inst).?.relocs.items) |reloc| try self.performReloc(reloc);3201 // relocations for `br` instructions
3202 const relocs = &self.blocks.getPtr(inst).?.relocs;
3203 if (relocs.items.len > 0 and relocs.items[relocs.items.len - 1] == self.mir_instructions.len - 1) {
3204 // If the last Mir instruction is the last relocation (which
3205 // would just jump one instruction further), it can be safely
3206 // removed
3207 self.mir_instructions.orderedRemove(relocs.pop());
3208 }
3209 for (relocs.items) |reloc| {
3210 try self.performReloc(reloc);
3211 }
32013212
3202 const result = self.blocks.getPtr(inst).?.mcv;3213 const result = self.blocks.getPtr(inst).?.mcv;
3203 return self.finishAir(inst, result, .{ .none, .none, .none });3214 return self.finishAir(inst, result, .{ .none, .none, .none });
...@@ -3952,7 +3963,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {...@@ -3952,7 +3963,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
3952 const ptr_ty = self.air.typeOf(ty_op.operand);3963 const ptr_ty = self.air.typeOf(ty_op.operand);
3953 const ptr = try self.resolveInst(ty_op.operand);3964 const ptr = try self.resolveInst(ty_op.operand);
3954 const array_ty = ptr_ty.childType();3965 const array_ty = ptr_ty.childType();
3955 const array_len = @intCast(u32, array_ty.arrayLenIncludingSentinel());3966 const array_len = @intCast(u32, array_ty.arrayLen());
39563967
3957 const stack_offset = try self.allocMem(inst, 8, 8);3968 const stack_offset = try self.allocMem(inst, 8, 8);
3958 try self.genSetStack(ptr_ty, stack_offset + 4, ptr);3969 try self.genSetStack(ptr_ty, stack_offset + 4, ptr);
test/behavior/align.zig-1
...@@ -271,7 +271,6 @@ test "runtime known array index has best alignment possible" {...@@ -271,7 +271,6 @@ test "runtime known array index has best alignment possible" {
271 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO271 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
272 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO272 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
273 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO273 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
274 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
275274
276 // take full advantage of over-alignment275 // take full advantage of over-alignment
277 var array align(4) = [_]u8{ 1, 2, 3, 4 };276 var array align(4) = [_]u8{ 1, 2, 3, 4 };
test/behavior/cast.zig-3
...@@ -223,8 +223,6 @@ test "@intToEnum passed a comptime_int to an enum with one item" {...@@ -223,8 +223,6 @@ test "@intToEnum passed a comptime_int to an enum with one item" {
223}223}
224224
225test "@intCast to u0 and use the result" {225test "@intCast to u0 and use the result" {
226 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
227
228 const S = struct {226 const S = struct {
229 fn doTheTest(zero: u1, one: u1, bigzero: i32) !void {227 fn doTheTest(zero: u1, one: u1, bigzero: i32) !void {
230 try expect((one << @intCast(u0, bigzero)) == 1);228 try expect((one << @intCast(u0, bigzero)) == 1);
...@@ -818,7 +816,6 @@ test "peer resolution of string literals" {...@@ -818,7 +816,6 @@ test "peer resolution of string literals" {
818test "peer cast [:x]T to []T" {816test "peer cast [:x]T to []T" {
819 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;817 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
820 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO818 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
821 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
822819
823 const S = struct {820 const S = struct {
824 fn doTheTest() !void {821 fn doTheTest() !void {
test/behavior/error.zig-1
...@@ -211,7 +211,6 @@ fn testErrorSetType() !void {...@@ -211,7 +211,6 @@ fn testErrorSetType() !void {
211test "explicit error set cast" {211test "explicit error set cast" {
212 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;212 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
213 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO213 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
214 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
215 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO214 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
216 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO215 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
217216
test/behavior/floatop.zig-1
...@@ -24,7 +24,6 @@ test "floating point comparisons" {...@@ -24,7 +24,6 @@ test "floating point comparisons" {
24 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO24 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO25 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
26 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO26 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
27 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
28 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO27 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2928
30 try testFloatComparisons();29 try testFloatComparisons();
test/behavior/inttoptr.zig-1
...@@ -2,7 +2,6 @@ const builtin = @import("builtin");...@@ -2,7 +2,6 @@ const builtin = @import("builtin");
22
3test "casting integer address to function pointer" {3test "casting integer address to function pointer" {
4 if (builtin.zig_backend == .stage1) return error.SkipZigTest;4 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
5 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;5 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
76
8 addressToFunction();7 addressToFunction();
test/behavior/math.zig-3
...@@ -313,7 +313,6 @@ test "xor" {...@@ -313,7 +313,6 @@ test "xor" {
313 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO313 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
314 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO314 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
315 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO315 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
316 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
317316
318 try test_xor();317 try test_xor();
319 comptime try test_xor();318 comptime try test_xor();
...@@ -565,7 +564,6 @@ test "bit shift a u1" {...@@ -565,7 +564,6 @@ test "bit shift a u1" {
565test "truncating shift right" {564test "truncating shift right" {
566 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO565 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
567 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO566 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
568 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
569567
570 try testShrTrunc(maxInt(u16));568 try testShrTrunc(maxInt(u16));
571 comptime try testShrTrunc(maxInt(u16));569 comptime try testShrTrunc(maxInt(u16));
...@@ -735,7 +733,6 @@ test "overflow arithmetic with u0 values" {...@@ -735,7 +733,6 @@ test "overflow arithmetic with u0 values" {
735 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO733 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
736 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO734 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
737 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO735 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
738 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
739736
740 var result: u0 = undefined;737 var result: u0 = undefined;
741 try expect(!@addWithOverflow(u0, 0, 0, &result));738 try expect(!@addWithOverflow(u0, 0, 0, &result));
test/behavior/slice.zig-1
...@@ -191,7 +191,6 @@ test "comptime pointer cast array and then slice" {...@@ -191,7 +191,6 @@ test "comptime pointer cast array and then slice" {
191test "slicing zero length array" {191test "slicing zero length array" {
192 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;192 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
193 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO193 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
194 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
195 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;194 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
196195
197 const s1 = ""[0..];196 const s1 = ""[0..];
test/behavior/switch.zig-2
...@@ -190,7 +190,6 @@ test "switch with disjoint range" {...@@ -190,7 +190,6 @@ test "switch with disjoint range" {
190}190}
191191
192test "switch variable for range and multiple prongs" {192test "switch variable for range and multiple prongs" {
193 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
194 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO193 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
195194
196 const S = struct {195 const S = struct {
...@@ -358,7 +357,6 @@ fn returnsFalse() bool {...@@ -358,7 +357,6 @@ fn returnsFalse() bool {
358 }357 }
359}358}
360test "switch on const enum with var" {359test "switch on const enum with var" {
361 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
362 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO360 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
363361
364 try expect(!returnsFalse());362 try expect(!returnsFalse());