diff options
Diffstat (limited to 'llvm/lib/CodeGen/TargetRegisterInfo.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/TargetRegisterInfo.cpp | 109 |
1 files changed, 95 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp index 5fd7eef5808f..f4bb71535f7f 100644 --- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp +++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp @@ -225,6 +225,23 @@ TargetRegisterInfo::getMinimalPhysRegClass(MCRegister reg, MVT VT) const { return BestRC; } +const TargetRegisterClass * +TargetRegisterInfo::getMinimalPhysRegClassLLT(MCRegister reg, LLT Ty) const { + assert(Register::isPhysicalRegister(reg) && + "reg must be a physical register"); + + // Pick the most sub register class of the right type that contains + // this physreg. + const TargetRegisterClass *BestRC = nullptr; + for (const TargetRegisterClass *RC : regclasses()) { + if ((!Ty.isValid() || isTypeLegalForClass(*RC, Ty)) && RC->contains(reg) && + (!BestRC || BestRC->hasSubClass(RC))) + BestRC = RC; + } + + return BestRC; +} + /// getAllocatableSetForRC - Toggle the bits that represent allocatable /// registers for the specific register class. static void getAllocatableSetForRC(const MachineFunction &MF, @@ -250,8 +267,9 @@ BitVector TargetRegisterInfo::getAllocatableSet(const MachineFunction &MF, } // Mask out the reserved registers - BitVector Reserved = getReservedRegs(MF); - Allocatable &= Reserved.flip(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); + const BitVector &Reserved = MRI.getReservedRegs(); + Allocatable.reset(Reserved); return Allocatable; } @@ -461,21 +479,13 @@ bool TargetRegisterInfo::canRealignStack(const MachineFunction &MF) const { return !MF.getFunction().hasFnAttribute("no-realign-stack"); } -bool TargetRegisterInfo::needsStackRealignment( - const MachineFunction &MF) const { +bool TargetRegisterInfo::shouldRealignStack(const MachineFunction &MF) const { const MachineFrameInfo &MFI = MF.getFrameInfo(); const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); const Function &F = MF.getFunction(); - Align StackAlign = TFI->getStackAlign(); - bool requiresRealignment = ((MFI.getMaxAlign() > StackAlign) || - F.hasFnAttribute(Attribute::StackAlignment)); - if (F.hasFnAttribute("stackrealign") || requiresRealignment) { - if (canRealignStack(MF)) - return true; - LLVM_DEBUG(dbgs() << "Can't realign function's stack: " << F.getName() - << "\n"); - } - return false; + return F.hasFnAttribute("stackrealign") || + (MFI.getMaxAlign() > TFI->getStackAlign()) || + F.hasFnAttribute(Attribute::StackAlignment); } bool TargetRegisterInfo::regmaskSubsetEqual(const uint32_t *mask0, @@ -510,6 +520,77 @@ TargetRegisterInfo::getRegSizeInBits(Register Reg, return getRegSizeInBits(*RC); } +bool TargetRegisterInfo::getCoveringSubRegIndexes( + const MachineRegisterInfo &MRI, const TargetRegisterClass *RC, + LaneBitmask LaneMask, SmallVectorImpl<unsigned> &NeededIndexes) const { + SmallVector<unsigned, 8> PossibleIndexes; + unsigned BestIdx = 0; + unsigned BestCover = 0; + + for (unsigned Idx = 1, E = getNumSubRegIndices(); Idx < E; ++Idx) { + // Is this index even compatible with the given class? + if (getSubClassWithSubReg(RC, Idx) != RC) + continue; + LaneBitmask SubRegMask = getSubRegIndexLaneMask(Idx); + // Early exit if we found a perfect match. + if (SubRegMask == LaneMask) { + BestIdx = Idx; + break; + } + + // The index must not cover any lanes outside \p LaneMask. + if ((SubRegMask & ~LaneMask).any()) + continue; + + unsigned PopCount = SubRegMask.getNumLanes(); + PossibleIndexes.push_back(Idx); + if (PopCount > BestCover) { + BestCover = PopCount; + BestIdx = Idx; + } + } + + // Abort if we cannot possibly implement the COPY with the given indexes. + if (BestIdx == 0) + return 0; + + NeededIndexes.push_back(BestIdx); + + // Greedy heuristic: Keep iterating keeping the best covering subreg index + // each time. + LaneBitmask LanesLeft = LaneMask & ~getSubRegIndexLaneMask(BestIdx); + while (LanesLeft.any()) { + unsigned BestIdx = 0; + int BestCover = std::numeric_limits<int>::min(); + for (unsigned Idx : PossibleIndexes) { + LaneBitmask SubRegMask = getSubRegIndexLaneMask(Idx); + // Early exit if we found a perfect match. + if (SubRegMask == LanesLeft) { + BestIdx = Idx; + break; + } + + // Try to cover as much of the remaining lanes as possible but + // as few of the already covered lanes as possible. + int Cover = (SubRegMask & LanesLeft).getNumLanes() - + (SubRegMask & ~LanesLeft).getNumLanes(); + if (Cover > BestCover) { + BestCover = Cover; + BestIdx = Idx; + } + } + + if (BestIdx == 0) + return 0; // Impossible to handle + + NeededIndexes.push_back(BestIdx); + + LanesLeft &= ~getSubRegIndexLaneMask(BestIdx); + } + + return BestIdx; +} + Register TargetRegisterInfo::lookThruCopyLike(Register SrcReg, const MachineRegisterInfo *MRI) const { |
