summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeoff Berry <gberry@codeaurora.org>2016-09-27 22:17:27 +0000
committerGeoff Berry <gberry@codeaurora.org>2016-09-27 22:17:27 +0000
commitb124331db7eda09e613d86f68376fcc67c677937 (patch)
tree91aa88f6321c028bc16aa91464451aa87dcc1523
parent1142147e418d0f39ba1717ec96dd23b7f748892c (diff)
downloadbcm5719-llvm-b124331db7eda09e613d86f68376fcc67c677937.tar.gz
bcm5719-llvm-b124331db7eda09e613d86f68376fcc67c677937.zip
[TargetRegisterInfo, AArch64] Add target hook for isConstantPhysReg().
Summary: The current implementation of isConstantPhysReg() checks for defs of physical registers to determine if they are constant. Some architectures (e.g. AArch64 XZR/WZR) have registers that are constant and may be used as destinations to indicate the generated value is discarded, preventing isConstantPhysReg() from returning true. This change adds a TargetRegisterInfo hook that overrides the no defs check for cases such as this. Reviewers: MatzeB, qcolombet, t.p.northover, jmolloy Subscribers: junbuml, aemerson, mcrosier, rengolin Differential Revision: https://reviews.llvm.org/D24570 llvm-svn: 282543
-rw-r--r--llvm/include/llvm/Target/TargetRegisterInfo.h4
-rw-r--r--llvm/lib/CodeGen/MachineRegisterInfo.cpp6
-rw-r--r--llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp4
-rw-r--r--llvm/lib/Target/AArch64/AArch64RegisterInfo.h1
-rw-r--r--llvm/test/CodeGen/MIR/AArch64/machine-sink-zr.mir48
5 files changed, 62 insertions, 1 deletions
diff --git a/llvm/include/llvm/Target/TargetRegisterInfo.h b/llvm/include/llvm/Target/TargetRegisterInfo.h
index e5642493928..5eb4fe8ae69 100644
--- a/llvm/include/llvm/Target/TargetRegisterInfo.h
+++ b/llvm/include/llvm/Target/TargetRegisterInfo.h
@@ -495,6 +495,10 @@ public:
/// used by register scavenger to determine what registers are free.
virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
+ /// Returns true if PhysReg is unallocatable and constant throughout the
+ /// function. Used by MachineRegisterInfo::isConstantPhysReg().
+ virtual bool isConstantPhysReg(unsigned PhysReg) const { return false; }
+
/// Prior to adding the live-out mask to a stackmap or patchpoint
/// instruction, provide the target the opportunity to adjust it (mainly to
/// remove pseudo-registers that should be ignored).
diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
index 55306dd6727..6693ccacb77 100644
--- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
@@ -468,9 +468,13 @@ bool MachineRegisterInfo::isConstantPhysReg(unsigned PhysReg,
const MachineFunction &MF) const {
assert(TargetRegisterInfo::isPhysicalRegister(PhysReg));
+ const TargetRegisterInfo *TRI = getTargetRegisterInfo();
+ if (TRI->isConstantPhysReg(PhysReg))
+ return true;
+
// Check if any overlapping register is modified, or allocatable so it may be
// used later.
- for (MCRegAliasIterator AI(PhysReg, getTargetRegisterInfo(), true);
+ for (MCRegAliasIterator AI(PhysReg, TRI, true);
AI.isValid(); ++AI)
if (!def_empty(*AI) || isAllocatable(*AI))
return false;
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index 1162da8cdc7..cd57a628ea0 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -167,6 +167,10 @@ bool AArch64RegisterInfo::isReservedReg(const MachineFunction &MF,
return false;
}
+bool AArch64RegisterInfo::isConstantPhysReg(unsigned PhysReg) const {
+ return PhysReg == AArch64::WZR || PhysReg == AArch64::XZR;
+}
+
const TargetRegisterClass *
AArch64RegisterInfo::getPointerRegClass(const MachineFunction &MF,
unsigned Kind) const {
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
index a2412529f02..f076b4ea365 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
@@ -62,6 +62,7 @@ public:
CallingConv::ID) const;
BitVector getReservedRegs(const MachineFunction &MF) const override;
+ bool isConstantPhysReg(unsigned PhysReg) const override;
const TargetRegisterClass *
getPointerRegClass(const MachineFunction &MF,
unsigned Kind = 0) const override;
diff --git a/llvm/test/CodeGen/MIR/AArch64/machine-sink-zr.mir b/llvm/test/CodeGen/MIR/AArch64/machine-sink-zr.mir
new file mode 100644
index 00000000000..535fba0dc63
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/AArch64/machine-sink-zr.mir
@@ -0,0 +1,48 @@
+# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass machine-sink -o - %s | FileCheck %s
+--- |
+ define void @sinkwzr() { ret void }
+...
+---
+name: sinkwzr
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: gpr32 }
+ - { id: 1, class: gpr32 }
+ - { id: 2, class: gpr32sp }
+ - { id: 3, class: gpr32 }
+ - { id: 4, class: gpr32 }
+body: |
+ ; Check that WZR copy is sunk into the loop preheader.
+ ; CHECK-LABEL: name: sinkwzr
+ ; CHECK-LABEL: bb.0:
+ ; CHECK-NOT: COPY %wzr
+ bb.0:
+ successors: %bb.3, %bb.1
+ liveins: %w0
+
+ %0 = COPY %w0
+ %1 = COPY %wzr
+ CBZW %0, %bb.3
+
+ ; CHECK-LABEL: bb.1:
+ ; CHECK: COPY %wzr
+
+ bb.1:
+ successors: %bb.2
+
+ B %bb.2
+
+ bb.2:
+ successors: %bb.3, %bb.2
+
+ %2 = PHI %0, %bb.1, %4, %bb.2
+ %w0 = COPY %1
+ %3 = SUBSWri %2, 1, 0, implicit-def dead %nzcv
+ %4 = COPY %3
+ CBZW %3, %bb.3
+ B %bb.2
+
+ bb.3:
+ RET_ReallyLR
+
+...
OpenPOWER on IntegriCloud