[TargetRegisterInfo, AArch64] Add target hook for isConstantPhysReg().
authorGeoff Berry <gberry@codeaurora.org>
Tue, 27 Sep 2016 22:17:27 +0000 (22:17 +0000)
committerGeoff Berry <gberry@codeaurora.org>
Tue, 27 Sep 2016 22:17:27 +0000 (22:17 +0000)
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

llvm/include/llvm/Target/TargetRegisterInfo.h
llvm/lib/CodeGen/MachineRegisterInfo.cpp
llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
llvm/lib/Target/AArch64/AArch64RegisterInfo.h
llvm/test/CodeGen/MIR/AArch64/machine-sink-zr.mir [new file with mode: 0644]

index e564249..5eb4fe8 100644 (file)
@@ -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).
index 55306dd..6693cca 100644 (file)
@@ -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;
index 1162da8..cd57a62 100644 (file)
@@ -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 {
index a241252..f076b4e 100644 (file)
@@ -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 (file)
index 0000000..535fba0
--- /dev/null
@@ -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
+
+...