diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h index 3f576b2007137..bf133f0332bcb 100644 --- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h @@ -678,6 +678,20 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo { getMatchingSuperRegClass(const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned Idx) const; + /// Find a common register class that can accomodate both the source and + /// destination operands of a copy-like instruction: + /// + /// DefRC:DefSubReg = COPY SrcRC:SrcSubReg + /// + /// This is a generalized form of getMatchingSuperRegClass, + /// getCommonSuperRegClass, and getCommonSubClass which handles 0, 1, or 2 + /// subregister indexes. Those utilities should be preferred if the number of + /// non-0 subregister indexes is known. + const TargetRegisterClass * + findCommonRegClass(const TargetRegisterClass *DefRC, unsigned DefSubReg, + const TargetRegisterClass *SrcRC, + unsigned SrcSubReg) const; + // For a copy-like instruction that defines a register of class DefRC with // subreg index DefSubReg, reading from another source with class SrcRC and // subregister SrcSubReg return true if this is a preferable copy @@ -685,7 +699,10 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo { virtual bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, unsigned DefSubReg, const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) const; + unsigned SrcSubReg) const { + // If this source does not incur a cross register bank copy, use it. + return findCommonRegClass(DefRC, DefSubReg, SrcRC, SrcSubReg) != nullptr; + } /// Returns the largest legal sub-class of RC that /// supports the sub-register index Idx. diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp index 701a9f8d72a65..c9e46182decc2 100644 --- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp +++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp @@ -412,25 +412,21 @@ getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA, return BestRC; } -/// Check if the registers defined by the pair (RegisterClass, SubReg) -/// share the same register file. -static bool shareSameRegisterFile(const TargetRegisterInfo &TRI, - const TargetRegisterClass *DefRC, - unsigned DefSubReg, - const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) { +const TargetRegisterClass *TargetRegisterInfo::findCommonRegClass( + const TargetRegisterClass *DefRC, unsigned DefSubReg, + const TargetRegisterClass *SrcRC, unsigned SrcSubReg) const { // Same register class. // // When processing uncoalescable copies / bitcasts, it is possible we reach // here with the same register class, but mismatched subregister indices. if (DefRC == SrcRC && DefSubReg == SrcSubReg) - return true; + return DefRC; // Both operands are sub registers. Check if they share a register class. unsigned SrcIdx, DefIdx; if (SrcSubReg && DefSubReg) { - return TRI.getCommonSuperRegClass(SrcRC, SrcSubReg, DefRC, DefSubReg, - SrcIdx, DefIdx) != nullptr; + return getCommonSuperRegClass(SrcRC, SrcSubReg, DefRC, DefSubReg, SrcIdx, + DefIdx); } // At most one of the register is a sub register, make it Src to avoid @@ -442,18 +438,10 @@ static bool shareSameRegisterFile(const TargetRegisterInfo &TRI, // One of the register is a sub register, check if we can get a superclass. if (SrcSubReg) - return TRI.getMatchingSuperRegClass(SrcRC, DefRC, SrcSubReg) != nullptr; + return getMatchingSuperRegClass(SrcRC, DefRC, SrcSubReg); // Plain copy. - return TRI.getCommonSubClass(DefRC, SrcRC) != nullptr; -} - -bool TargetRegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC, - unsigned DefSubReg, - const TargetRegisterClass *SrcRC, - unsigned SrcSubReg) const { - // If this source does not incur a cross register bank copy, use it. - return shareSameRegisterFile(*this, DefRC, DefSubReg, SrcRC, SrcSubReg); + return getCommonSubClass(DefRC, SrcRC); } float TargetRegisterInfo::getSpillWeightScaleFactor( diff --git a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp index edc4858cbc974..736744569a3bd 100644 --- a/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp +++ b/llvm/lib/Target/AMDGPU/SIFoldOperands.cpp @@ -710,22 +710,9 @@ bool SIFoldOperandsImpl::updateOperand(FoldCandidate &Fold) const { // Verify the register is compatible with the operand. if (const TargetRegisterClass *OpRC = TII->getRegClass(MI->getDesc(), Fold.UseOpNo, TRI)) { - const TargetRegisterClass *OldRC = MRI->getRegClass(Old.getReg()); const TargetRegisterClass *NewRC = MRI->getRegClass(New->getReg()); - unsigned NewSubReg = New->getSubReg(); - unsigned OldSubReg = Old.getSubReg(); - - const TargetRegisterClass *ConstrainRC = OpRC; - if (NewSubReg && OldSubReg) { - unsigned PreA, PreB; - ConstrainRC = TRI->getCommonSuperRegClass(OpRC, OldSubReg, NewRC, - NewSubReg, PreA, PreB); - } else if (OldSubReg) { - ConstrainRC = TRI->getMatchingSuperRegClass(OldRC, OpRC, OldSubReg); - } else if (NewSubReg) { - ConstrainRC = TRI->getMatchingSuperRegClass(NewRC, OpRC, NewSubReg); - } - + const TargetRegisterClass *ConstrainRC = + TRI->findCommonRegClass(OpRC, Old.getSubReg(), NewRC, New->getSubReg()); if (!ConstrainRC) return false;