Index: include/llvm/CodeGen/MachineFrameInfo.h =================================================================== --- include/llvm/CodeGen/MachineFrameInfo.h +++ include/llvm/CodeGen/MachineFrameInfo.h @@ -593,7 +593,7 @@ MachineBasicBlock *getRestorePoint() const { return Restore; } void setRestorePoint(MachineBasicBlock *NewRestore) { Restore = NewRestore; } - /// Return a set of physical registers that are pristine. + /// Return a set of register units for physical registers that are pristine. /// /// Pristine registers hold a value that is useless to the current function, /// but that must be preserved - they are callee saved registers that are not @@ -601,7 +601,7 @@ /// /// Before the PrologueEpilogueInserter has placed the CSR spill code, this /// method always returns an empty set. - BitVector getPristineRegs(const MachineFunction &MF) const; + BitVector getPristineRegUnits(const MachineFunction &MF) const; /// Used by the MachineFunction printer to print information about /// stack objects. Implemented in MachineFunction.cpp. Index: lib/CodeGen/AggressiveAntiDepBreaker.cpp =================================================================== --- lib/CodeGen/AggressiveAntiDepBreaker.cpp +++ lib/CodeGen/AggressiveAntiDepBreaker.cpp @@ -162,10 +162,17 @@ // all callee-saved registers. In non-return this is any // callee-saved register that is not saved in the prolog. const MachineFrameInfo *MFI = MF.getFrameInfo(); - BitVector Pristine = MFI->getPristineRegs(MF); + BitVector Units = MFI->getPristineRegUnits(MF); + + auto HasPristineUnit = [this,&Units] (unsigned Reg) -> bool { + for (MCRegUnitIterator UI(Reg, TRI); UI.isValid(); ++UI) + if (Units.test(*UI)) + return true; + return false; + }; for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I) { unsigned Reg = *I; - if (!IsReturnBlock && !Pristine.test(Reg)) continue; + if (!IsReturnBlock && !HasPristineUnit(Reg)) continue; for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { unsigned AliasReg = *AI; State->UnionGroups(AliasReg, 0); Index: lib/CodeGen/CriticalAntiDepBreaker.cpp =================================================================== --- lib/CodeGen/CriticalAntiDepBreaker.cpp +++ lib/CodeGen/CriticalAntiDepBreaker.cpp @@ -70,9 +70,17 @@ // all callee-saved registers. In non-return this is any // callee-saved register that is not saved in the prolog. const MachineFrameInfo *MFI = MF.getFrameInfo(); - BitVector Pristine = MFI->getPristineRegs(MF); + BitVector Units = MFI->getPristineRegUnits(MF); + + auto HasPristineUnit = [this,&Units] (unsigned Reg) -> bool { + for (MCRegUnitIterator UI(Reg, TRI); UI.isValid(); ++UI) + if (Units.test(*UI)) + return true; + return false; + }; + for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I) { - if (!IsReturnBlock && !Pristine.test(*I)) continue; + if (!IsReturnBlock && !HasPristineUnit(*I)) continue; for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI) { unsigned Reg = *AI; Classes[Reg] = reinterpret_cast(-1); Index: lib/CodeGen/LivePhysRegs.cpp =================================================================== --- lib/CodeGen/LivePhysRegs.cpp +++ lib/CodeGen/LivePhysRegs.cpp @@ -13,6 +13,8 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/CodeGen/LivePhysRegs.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -137,13 +139,24 @@ static void addPristines(LivePhysRegs &LiveRegs, const MachineFunction &MF, const TargetRegisterInfo &TRI) { const MachineFrameInfo &MFI = *MF.getFrameInfo(); - if (!MFI.isCalleeSavedInfoValid()) - return; - - for (const MCPhysReg *CSR = TRI.getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR) - LiveRegs.addReg(*CSR); - for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) - LiveRegs.removeReg(Info.getReg()); + BitVector Units = MFI.getPristineRegUnits(MF); + DenseSet MaybePR; + + for (int x = Units.find_first(); x >= 0; x = Units.find_next(x)) { + unsigned U = x; + for (MCRegUnitRootIterator RI(U, &TRI); RI.isValid(); ++RI) + for (MCSuperRegIterator SI(*RI, &TRI, true); SI.isValid(); ++SI) + MaybePR.insert(*SI); + } + auto AllUnitsPristine = [&Units,&TRI] (unsigned R) -> bool { + for (MCRegUnitIterator UI(R, &TRI); UI.isValid(); ++UI) + if (!Units.test(*UI)) + return false; + return true; + }; + for (unsigned R : MaybePR) + if (AllUnitsPristine(R)) + LiveRegs.addReg(R); } void LivePhysRegs::addLiveOuts(const MachineBasicBlock *MBB, Index: lib/CodeGen/MachineFunction.cpp =================================================================== --- lib/CodeGen/MachineFunction.cpp +++ lib/CodeGen/MachineFunction.cpp @@ -595,27 +595,37 @@ return -++NumFixedObjects; } -BitVector MachineFrameInfo::getPristineRegs(const MachineFunction &MF) const { +/// Return the set of register units for the pristine physical registers. +BitVector MachineFrameInfo::getPristineRegUnits(const MachineFunction &MF) + const { const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); - BitVector BV(TRI->getNumRegs()); + BitVector Units(TRI->getNumRegUnits()); - // Before CSI is calculated, no registers are considered pristine. They can be - // freely used and PEI will make sure they are saved. + // Before CSI is calculated, no registers are considered pristine. They + // can be freely used and PEI will make sure they are saved. if (!isCalleeSavedInfoValid()) - return BV; - - for (const MCPhysReg *CSR = TRI->getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR) - BV.set(*CSR); - - // Saved CSRs are not pristine. - const std::vector &CSI = getCalleeSavedInfo(); - for (std::vector::const_iterator I = CSI.begin(), - E = CSI.end(); I != E; ++I) - BV.reset(I->getReg()); + return Units; + + auto CSR = TRI->getCalleeSavedRegs(&MF); + if (CSR == nullptr) + return Units; + + DenseSet Saved; + for (auto &I : getCalleeSavedInfo()) + for (MCRegUnitIterator UI(I.getReg(), TRI); UI.isValid(); ++UI) + Saved.insert(*UI); + + while (*CSR) { + for (MCRegUnitIterator UI(*CSR, TRI); UI.isValid(); ++UI) + if (!Saved.count(*UI)) + Units.set(*UI); + CSR++; + } - return BV; + return Units; } + unsigned MachineFrameInfo::estimateStackSize(const MachineFunction &MF) const { const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); Index: lib/CodeGen/MachineVerifier.cpp =================================================================== --- lib/CodeGen/MachineVerifier.cpp +++ lib/CodeGen/MachineVerifier.cpp @@ -704,12 +704,24 @@ const MachineFrameInfo *MFI = MF->getFrameInfo(); assert(MFI && "Function has no frame info"); - BitVector PR = MFI->getPristineRegs(*MF); - for (int I = PR.find_first(); I>0; I = PR.find_next(I)) { - for (MCSubRegIterator SubRegs(I, TRI, /*IncludeSelf=*/true); - SubRegs.isValid(); ++SubRegs) - regsLive.insert(*SubRegs); + RegSet MaybePR; + BitVector Units = MFI->getPristineRegUnits(*MF); + + for (int x = Units.find_first(); x >= 0; x = Units.find_next(x)) { + unsigned U = x; + for (MCRegUnitRootIterator RI(U, TRI); RI.isValid(); ++RI) + for (MCSuperRegIterator SI(*RI, TRI, true); SI.isValid(); ++SI) + MaybePR.insert(*SI); } + auto AllUnitsPristine = [this,&Units] (unsigned R) -> bool { + for (MCRegUnitIterator UI(R, TRI); UI.isValid(); ++UI) + if (!Units.test(*UI)) + return false; + return true; + }; + for (unsigned R : MaybePR) + if (AllUnitsPristine(R)) + regsLive.insert(R); regsKilled.clear(); regsDefined.clear(); Index: lib/CodeGen/RegisterScavenging.cpp =================================================================== --- lib/CodeGen/RegisterScavenging.cpp +++ lib/CodeGen/RegisterScavenging.cpp @@ -58,9 +58,7 @@ // Pristine CSRs are also unavailable. const MachineFunction &MF = *MBB->getParent(); - BitVector PR = MF.getFrameInfo()->getPristineRegs(MF); - for (int I = PR.find_first(); I>0; I = PR.find_next(I)) - setRegUsed(I); + RegUnitsAvailable.reset(MF.getFrameInfo()->getPristineRegUnits(MF)); } void RegScavenger::enterBasicBlock(MachineBasicBlock *mbb) { Index: lib/Target/ARM/ARMFrameLowering.cpp =================================================================== --- lib/Target/ARM/ARMFrameLowering.cpp +++ lib/Target/ARM/ARMFrameLowering.cpp @@ -755,8 +755,12 @@ // This is bad, if an interrupt is taken after the mov, sp is in an // inconsistent state. // Use the first callee-saved register as a scratch register. - assert(!MFI->getPristineRegs(MF).test(ARM::R4) && - "No scratch register to restore SP from FP!"); +#ifndef NDEBUG + BitVector PRU = MFI->getPristineRegUnits(MF); + for (MCRegUnitIterator UI(ARM::R4, RegInfo); UI.isValid(); ++UI) + assert(!PRU.test(*UI) && + "No scratch register to restore SP from FP!"); +#endif emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes, ARMCC::AL, 0, TII); AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), Index: lib/Target/ARM/Thumb1FrameLowering.cpp =================================================================== --- lib/Target/ARM/Thumb1FrameLowering.cpp +++ lib/Target/ARM/Thumb1FrameLowering.cpp @@ -363,8 +363,12 @@ // frame pointer stack slot, the target is ELF and the function has FP, or // the target uses var sized objects. if (NumBytes) { - assert(!MFI->getPristineRegs(MF).test(ARM::R4) && - "No scratch register to restore SP from FP!"); +#ifndef NDEBUG + BitVector PRU = MFI->getPristineRegUnits(MF); + for (MCRegUnitIterator UI(ARM::R4, RegInfo); UI.isValid(); ++UI) + assert(!PRU.test(*UI) && + "No scratch register to restore SP from FP!"); +#endif emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes, TII, *RegInfo); AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr),