From dcf371dfad16c1b7fd645490c5b73da7e8306c7e Mon Sep 17 00:00:00 2001 From: Geoff Berry Date: Tue, 27 Sep 2016 22:17:27 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282543 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetRegisterInfo.h | 4 ++ lib/CodeGen/MachineRegisterInfo.cpp | 6 ++- lib/Target/AArch64/AArch64RegisterInfo.cpp | 4 ++ lib/Target/AArch64/AArch64RegisterInfo.h | 1 + test/CodeGen/MIR/AArch64/machine-sink-zr.mir | 48 ++++++++++++++++++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/MIR/AArch64/machine-sink-zr.mir diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index e5642493928..5eb4fe8ae69 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/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/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp index 55306dd6727..6693ccacb77 100644 --- a/lib/CodeGen/MachineRegisterInfo.cpp +++ b/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/lib/Target/AArch64/AArch64RegisterInfo.cpp b/lib/Target/AArch64/AArch64RegisterInfo.cpp index 1162da8cdc7..cd57a628ea0 100644 --- a/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/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/lib/Target/AArch64/AArch64RegisterInfo.h b/lib/Target/AArch64/AArch64RegisterInfo.h index a2412529f02..f076b4ea365 100644 --- a/lib/Target/AArch64/AArch64RegisterInfo.h +++ b/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/test/CodeGen/MIR/AArch64/machine-sink-zr.mir b/test/CodeGen/MIR/AArch64/machine-sink-zr.mir new file mode 100644 index 00000000000..535fba0dc63 --- /dev/null +++ b/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 + +...