diff options
Diffstat (limited to 'lib/Target/Hexagon/HexagonFrameLowering.cpp')
-rw-r--r-- | lib/Target/Hexagon/HexagonFrameLowering.cpp | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/lib/Target/Hexagon/HexagonFrameLowering.cpp b/lib/Target/Hexagon/HexagonFrameLowering.cpp index a3f6273f9f67..0e2380f4316a 100644 --- a/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -301,16 +301,30 @@ static bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR, // the frame creation/destruction instructions. if (MO.isFI()) return true; - if (!MO.isReg()) - continue; - unsigned R = MO.getReg(); - // Virtual registers will need scavenging, which then may require - // a stack slot. - if (TargetRegisterInfo::isVirtualRegister(R)) - return true; - for (MCSubRegIterator S(R, &HRI, true); S.isValid(); ++S) - if (CSR[*S]) + if (MO.isReg()) { + unsigned R = MO.getReg(); + // Virtual registers will need scavenging, which then may require + // a stack slot. + if (TargetRegisterInfo::isVirtualRegister(R)) return true; + for (MCSubRegIterator S(R, &HRI, true); S.isValid(); ++S) + if (CSR[*S]) + return true; + continue; + } + if (MO.isRegMask()) { + // A regmask would normally have all callee-saved registers marked + // as preserved, so this check would not be needed, but in case of + // ever having other regmasks (for other calling conventions), + // make sure they would be processed correctly. + const uint32_t *BM = MO.getRegMask(); + for (int x = CSR.find_first(); x >= 0; x = CSR.find_next(x)) { + unsigned R = x; + // If this regmask does not preserve a CSR, a frame will be needed. + if (!(BM[R/32] & (1u << (R%32)))) + return true; + } + } } } return false; @@ -1473,8 +1487,7 @@ bool HexagonFrameLowering::expandCopy(MachineBasicBlock &B, return false; unsigned TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass); - BuildMI(B, It, DL, HII.get(TargetOpcode::COPY), TmpR) - .addOperand(MI->getOperand(1)); + BuildMI(B, It, DL, HII.get(TargetOpcode::COPY), TmpR).add(MI->getOperand(1)); BuildMI(B, It, DL, HII.get(TargetOpcode::COPY), DstR) .addReg(TmpR, RegState::Kill); @@ -1646,8 +1659,15 @@ bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &B, LivePhysRegs LPR(&HRI); LPR.addLiveIns(B); SmallVector<std::pair<unsigned, const MachineOperand*>,2> Clobbers; - for (auto R = B.begin(); R != It; ++R) + for (auto R = B.begin(); R != It; ++R) { + Clobbers.clear(); LPR.stepForward(*R, Clobbers); + // Dead defs are recorded in Clobbers, but are not automatically removed + // from the live set. + for (auto &C : Clobbers) + if (C.second->isReg() && C.second->isDead()) + LPR.removeReg(C.first); + } DebugLoc DL = MI->getDebugLoc(); unsigned SrcR = MI->getOperand(2).getReg(); @@ -1985,9 +2005,9 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF, // class HaveRC and a new class NewRC. Return nullptr if a common class // cannot be found, otherwise return the resulting class. If HaveRC is // nullptr, assume that it is still unset. - auto getCommonRC = [&HRI] (const TargetRegisterClass *HaveRC, - const TargetRegisterClass *NewRC) - -> const TargetRegisterClass* { + auto getCommonRC = + [](const TargetRegisterClass *HaveRC, + const TargetRegisterClass *NewRC) -> const TargetRegisterClass * { if (HaveRC == nullptr || HaveRC == NewRC) return NewRC; // Different classes, both non-null. Pick the more general one. @@ -2221,7 +2241,7 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF, if (SrcRR.Reg != FoundR || SrcRR.Sub != 0) { const DebugLoc &DL = SI.getDebugLoc(); CopyIn = BuildMI(B, StartIt, DL, HII.get(TargetOpcode::COPY), FoundR) - .addOperand(SrcOp); + .add(SrcOp); } ++StartIt; |