aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
authorAmara Emerson <amara@apple.com>2021-10-05 17:41:21 -0700
committerAmara Emerson <amara@apple.com>2021-10-05 23:06:22 -0700
commit6bc64e24c38a42f2797ee64c78cb2d42b245b59e (patch)
tree760bda91147aa25ccf7ac7f59833fec71dd22ec2 /llvm
parentcb89d3739db746ea50eb50b7208e689126394391 (diff)
downloadllvm-6bc64e24c38a42f2797ee64c78cb2d42b245b59e.zip
llvm-6bc64e24c38a42f2797ee64c78cb2d42b245b59e.tar.gz
llvm-6bc64e24c38a42f2797ee64c78cb2d42b245b59e.tar.bz2
[GlobalISel] Clear unreachable blocks' contents after selection.
If these blocks are unreachable, then we can discard all of the instructions. However, keep the block around because it may have an address taken or the block may have a stale reference from a PHI somewhere. Instead of finding those PHIs and fixing them up, just leave the block empty. Differential Revision: https://reviews.llvm.org/D111201
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp12
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir2
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/select-unreachable-blocks.mir61
3 files changed, 73 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
index 75a8f03..77d9cd7 100644
--- a/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
@@ -130,9 +130,12 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
// Until then, keep track of the number of blocks to assert that we don't.
const size_t NumBlocks = MF.size();
#endif
+ // Keep track of selected blocks, so we can delete unreachable ones later.
+ DenseSet<MachineBasicBlock *> SelectedBlocks;
for (MachineBasicBlock *MBB : post_order(&MF)) {
ISel->CurMBB = MBB;
+ SelectedBlocks.insert(MBB);
if (MBB->empty())
continue;
@@ -205,6 +208,15 @@ bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
if (MBB.empty())
continue;
+ if (!SelectedBlocks.contains(&MBB)) {
+ // This is an unreachable block and therefore hasn't been selected, since
+ // the main selection loop above uses a postorder block traversal.
+ // We delete all the instructions in this block since it's unreachable.
+ MBB.clear();
+ // Don't delete the block in case the block has it's address taken or is
+ // still being referenced by a phi somewhere.
+ continue;
+ }
// Try to find redundant copies b/w vregs of the same register class.
bool ReachedBegin = false;
for (auto MII = std::prev(MBB.end()), Begin = MBB.begin(); !ReachedBegin;) {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir
index 0737a8e..91f0724 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-blockaddress.mir
@@ -36,7 +36,6 @@ body: |
; CHECK: STRXui [[COPY]], [[MOVaddr]], 0 :: (store (p0) into @addr)
; CHECK: BR [[MOVaddrBA]]
; CHECK: bb.1.block (address-taken):
- ; CHECK: RET_ReallyLR
; LARGE-LABEL: name: test_blockaddress
; LARGE: bb.0 (%ir-block.0):
; LARGE: [[MOVZXi:%[0-9]+]]:gpr64 = MOVZXi target-flags(aarch64-g0, aarch64-nc) blockaddress(@test_blockaddress, %ir-block.block), 0
@@ -50,7 +49,6 @@ body: |
; LARGE: STRXui [[MOVKXi2]], [[MOVKXi5]], 0 :: (store (p0) into @addr)
; LARGE: BR [[MOVKXi2]]
; LARGE: bb.1.block (address-taken):
- ; LARGE: RET_ReallyLR
bb.1 (%ir-block.0):
%0:gpr(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
%1:gpr(p0) = G_GLOBAL_VALUE @addr
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-unreachable-blocks.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-unreachable-blocks.mir
new file mode 100644
index 0000000..2ef9f84
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-unreachable-blocks.mir
@@ -0,0 +1,61 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=aarch64-unknown-unknown -o - -verify-machineinstrs -run-pass=instruction-select %s | FileCheck %s
+---
+name: test_unreachable_delete
+alignment: 4
+exposesReturnsTwice: false
+legalized: true
+regBankSelected: true
+selected: false
+tracksRegLiveness: true
+liveins:
+body: |
+ ; CHECK-LABEL: name: test_unreachable_delete
+ ; CHECK: bb.0:
+ ; CHECK-NEXT: successors: %bb.2(0x80000000)
+ ; CHECK-NEXT: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32sp = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $wzr
+ ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1
+ ; CHECK-NEXT: B %bb.2
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.1:
+ ; CHECK-NEXT: successors: %bb.2(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.2:
+ ; CHECK-NEXT: successors: %bb.3(0x80000000)
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[ADDWri:%[0-9]+]]:gpr32sp = ADDWri [[COPY]], 2, 0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: bb.3:
+ ; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32 = PHI [[ADDWri]], %bb.2
+ ; CHECK-NEXT: $w0 = COPY [[PHI]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ bb.1:
+ successors: %bb.3
+ liveins: $w0
+
+ %0:gpr(s32) = COPY $w0
+ %1:gpr(s32) = G_CONSTANT i32 0
+ %3:gpr(s32) = G_CONSTANT i32 1
+ %5:gpr(s32) = G_CONSTANT i32 2
+ G_BR %bb.3
+
+ bb.5:
+ ; This block is unreachable.
+ %unreachable_inst:gpr(s32) = G_XOR %1, %3
+ $w0 = COPY %unreachable_inst(s32)
+
+ bb.3:
+ successors: %bb.4(0x80000000)
+
+ %6:gpr(s32) = G_ADD %0, %5
+
+ bb.4:
+ %7:gpr(s32) = G_PHI %6(s32), %bb.3
+ $w0 = COPY %7(s32)
+ RET_ReallyLR implicit $w0
+
+...