Skip to content

Commit

Permalink
[TargetRegisterInfo, AArch64] Add target hook for isConstantPhysReg().
Browse files Browse the repository at this point in the history
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
  • Loading branch information
geoffberry committed Sep 27, 2016
1 parent 8d5df95 commit dcf371d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 1 deletion.
4 changes: 4 additions & 0 deletions include/llvm/Target/TargetRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,10 @@ class TargetRegisterInfo : public MCRegisterInfo {
/// 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).
Expand Down
6 changes: 5 additions & 1 deletion lib/CodeGen/MachineRegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions lib/Target/AArch64/AArch64RegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions lib/Target/AArch64/AArch64RegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class AArch64RegisterInfo final : public AArch64GenRegisterInfo {
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;
Expand Down
48 changes: 48 additions & 0 deletions test/CodeGen/MIR/AArch64/machine-sink-zr.mir
Original file line number Diff line number Diff line change
@@ -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
...

0 comments on commit dcf371d

Please sign in to comment.