diff options
| author | Geoff Berry <gberry@codeaurora.org> | 2016-09-27 22:17:27 +0000 |
|---|---|---|
| committer | Geoff Berry <gberry@codeaurora.org> | 2016-09-27 22:17:27 +0000 |
| commit | b124331db7eda09e613d86f68376fcc67c677937 (patch) | |
| tree | 91aa88f6321c028bc16aa91464451aa87dcc1523 | |
| parent | 1142147e418d0f39ba1717ec96dd23b7f748892c (diff) | |
| download | bcm5719-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.h | 4 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/MachineRegisterInfo.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64RegisterInfo.h | 1 | ||||
| -rw-r--r-- | llvm/test/CodeGen/MIR/AArch64/machine-sink-zr.mir | 48 |
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 + +... |

