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 {
445445 });
446446
447447 // exitlude jumps
448 const only_one_exitlude_jump = self.exitlude_jump_relocs.items.len == 1 and
449 self.exitlude_jump_relocs.items[0] == self.mir_instructions.len - 1;
450 if (only_one_exitlude_jump) {
451 // There is only one relocation. Hence,
452 // this relocation must be at the end of
453 // the code. Therefore, we can just delete
454 // the space initially reserved for the
455 // jump
456 self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.items[0]);
457 } else for (self.exitlude_jump_relocs.items) |jmp_reloc| {
448 if (self.exitlude_jump_relocs.items.len > 0 and
449 self.exitlude_jump_relocs.items[self.exitlude_jump_relocs.items.len - 1] == self.mir_instructions.len - 2)
450 {
451 // If the last Mir instruction (apart from the
452 // dbg_epilogue_begin) is the last exitlude jump
453 // relocation (which would just jump one instruction
454 // further), it can be safely removed
455 self.mir_instructions.orderedRemove(self.exitlude_jump_relocs.pop());
456 }
457
458 for (self.exitlude_jump_relocs.items) |jmp_reloc| {
458459 self.mir_instructions.set(jmp_reloc, .{
459460 .tag = .b,
460461 .data = .{ .inst = @intCast(u32, self.mir_instructions.len) },
......@@ -3197,7 +3198,17 @@ fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
31973198 const body = self.air.extra[extra.end..][0..extra.data.body_len];
31983199 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
32023213 const result = self.blocks.getPtr(inst).?.mcv;
32033214 return self.finishAir(inst, result, .{ .none, .none, .none });
......@@ -3952,7 +3963,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
39523963 const ptr_ty = self.air.typeOf(ty_op.operand);
39533964 const ptr = try self.resolveInst(ty_op.operand);
39543965 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
39573968 const stack_offset = try self.allocMem(inst, 8, 8);
39583969 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" {
271271 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
272272 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
273273 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
274 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
275274
276275 // take full advantage of over-alignment
277276 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" {
223223}
224224
225225test "@intCast to u0 and use the result" {
226 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
227
228226 const S = struct {
229227 fn doTheTest(zero: u1, one: u1, bigzero: i32) !void {
230228 try expect((one << @intCast(u0, bigzero)) == 1);
......@@ -818,7 +816,6 @@ test "peer resolution of string literals" {
818816test "peer cast [:x]T to []T" {
819817 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
820818 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
821 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
822819
823820 const S = struct {
824821 fn doTheTest() !void {
test/behavior/error.zig-1
......@@ -211,7 +211,6 @@ fn testErrorSetType() !void {
211211test "explicit error set cast" {
212212 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
213213 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
214 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
215214 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
216215 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
217216
test/behavior/floatop.zig-1
......@@ -24,7 +24,6 @@ test "floating point comparisons" {
2424 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
2525 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
2626 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
27 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2827 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2928
3029 try testFloatComparisons();
test/behavior/inttoptr.zig-1
......@@ -2,7 +2,6 @@ const builtin = @import("builtin");
22
33test "casting integer address to function pointer" {
44 if (builtin.zig_backend == .stage1) return error.SkipZigTest;
5 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
65 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
76
87 addressToFunction();
test/behavior/math.zig-3
......@@ -313,7 +313,6 @@ test "xor" {
313313 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
314314 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
315315 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
316 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
317316
318317 try test_xor();
319318 comptime try test_xor();
......@@ -565,7 +564,6 @@ test "bit shift a u1" {
565564test "truncating shift right" {
566565 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
567566 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
568 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
569567
570568 try testShrTrunc(maxInt(u16));
571569 comptime try testShrTrunc(maxInt(u16));
......@@ -735,7 +733,6 @@ test "overflow arithmetic with u0 values" {
735733 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
736734 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
737735 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
738 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
739736
740737 var result: u0 = undefined;
741738 try expect(!@addWithOverflow(u0, 0, 0, &result));
test/behavior/slice.zig-1
......@@ -191,7 +191,6 @@ test "comptime pointer cast array and then slice" {
191191test "slicing zero length array" {
192192 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
193193 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
194 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
195194 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
196195
197196 const s1 = ""[0..];
test/behavior/switch.zig-2
......@@ -190,7 +190,6 @@ test "switch with disjoint range" {
190190}
191191
192192test "switch variable for range and multiple prongs" {
193 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
194193 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
195194
196195 const S = struct {
......@@ -358,7 +357,6 @@ fn returnsFalse() bool {
358357 }
359358}
360359test "switch on const enum with var" {
361 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
362360 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
363361
364362 try expect(!returnsFalse());