aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Hexagon/HexagonFrameLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Hexagon/HexagonFrameLowering.cpp')
-rw-r--r--lib/Target/Hexagon/HexagonFrameLowering.cpp52
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;