diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp | 96 |
1 files changed, 75 insertions, 21 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index bfa3372d7faf..aff8e57b0a94 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -36,6 +36,7 @@ #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachinePostDominators.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/IR/Attributes.h" @@ -223,8 +224,7 @@ namespace { bool HexagonCallFrameInformation::runOnMachineFunction(MachineFunction &MF) { auto &HFI = *MF.getSubtarget<HexagonSubtarget>().getFrameLowering(); - bool NeedCFI = MF.getMMI().hasDebugInfo() || - MF.getFunction().needsUnwindTableEntry(); + bool NeedCFI = MF.needsFrameMoves(); if (!NeedCFI) return false; @@ -1363,6 +1363,7 @@ void HexagonFrameLowering::processFunctionBeforeFrameFinalized( if (!HasAlloca || !NeedsAlign) return; + SmallSet<int, 4> DealignSlots; unsigned LFS = MFI.getLocalFrameSize(); for (int i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) { if (!MFI.isSpillSlotObjectIndex(i) || MFI.isDeadObjectIndex(i)) @@ -1373,7 +1374,8 @@ void HexagonFrameLowering::processFunctionBeforeFrameFinalized( unsigned A = std::max(MFI.getObjectAlignment(i), 8U); MFI.setObjectAlignment(i, 8); LFS = alignTo(LFS+S, A); - MFI.mapLocalFrameObject(i, -LFS); + MFI.mapLocalFrameObject(i, -static_cast<int64_t>(LFS)); + DealignSlots.insert(i); } MFI.setLocalFrameSize(LFS); @@ -1383,6 +1385,38 @@ void HexagonFrameLowering::processFunctionBeforeFrameFinalized( MFI.setLocalFrameMaxAlign(Align(8)); MFI.setUseLocalStackAllocationBlock(true); + // Go over all MachineMemOperands in the code, and change the ones that + // refer to the dealigned stack slots to reflect the new alignment. + if (!DealignSlots.empty()) { + for (MachineBasicBlock &BB : MF) { + for (MachineInstr &MI : BB) { + bool KeepOld = true; + ArrayRef<MachineMemOperand*> memops = MI.memoperands(); + SmallVector<MachineMemOperand*,1> new_memops; + for (MachineMemOperand *MMO : memops) { + auto *PV = MMO->getPseudoValue(); + if (auto *FS = dyn_cast_or_null<FixedStackPseudoSourceValue>(PV)) { + int FI = FS->getFrameIndex(); + if (DealignSlots.count(FI)) { + unsigned A = MFI.getObjectAlignment(FI); + auto *NewMMO = MF.getMachineMemOperand(MMO->getPointerInfo(), + MMO->getFlags(), MMO->getSize(), A, + MMO->getAAInfo(), MMO->getRanges(), + MMO->getSyncScopeID(), MMO->getOrdering(), + MMO->getFailureOrdering()); + new_memops.push_back(NewMMO); + KeepOld = false; + continue; + } + } + new_memops.push_back(MMO); + } + if (!KeepOld) + MI.setMemRefs(MF, new_memops); + } + } + } + // Set the physical aligned-stack base address register. unsigned AP = 0; if (const MachineInstr *AI = getAlignaInstr(MF)) @@ -1750,16 +1784,21 @@ bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &B, Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi); bool IsKill = MI->getOperand(2).isKill(); int FI = MI->getOperand(0).getIndex(); + bool NeedsAligna = needsAligna(MF); unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass); unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass); unsigned HasAlign = MFI.getObjectAlignment(FI); unsigned StoreOpc; + auto UseAligned = [&] (unsigned NeedAlign, unsigned HasAlign) { + return !NeedsAligna && (NeedAlign <= HasAlign); + }; + // Store low part. if (LPR.contains(SrcLo)) { - StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai - : Hexagon::V6_vS32Ub_ai; + StoreOpc = UseAligned(NeedAlign, HasAlign) ? Hexagon::V6_vS32b_ai + : Hexagon::V6_vS32Ub_ai; BuildMI(B, It, DL, HII.get(StoreOpc)) .addFrameIndex(FI) .addImm(0) @@ -1769,8 +1808,8 @@ bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &B, // Store high part. if (LPR.contains(SrcHi)) { - StoreOpc = NeedAlign <= MinAlign(HasAlign, Size) ? Hexagon::V6_vS32b_ai - : Hexagon::V6_vS32Ub_ai; + StoreOpc = UseAligned(NeedAlign, HasAlign) ? Hexagon::V6_vS32b_ai + : Hexagon::V6_vS32Ub_ai; BuildMI(B, It, DL, HII.get(StoreOpc)) .addFrameIndex(FI) .addImm(Size) @@ -1797,23 +1836,28 @@ bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &B, Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi); Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo); int FI = MI->getOperand(1).getIndex(); + bool NeedsAligna = needsAligna(MF); unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass); unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass); unsigned HasAlign = MFI.getObjectAlignment(FI); unsigned LoadOpc; + auto UseAligned = [&] (unsigned NeedAlign, unsigned HasAlign) { + return !NeedsAligna && (NeedAlign <= HasAlign); + }; + // Load low part. - LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai - : Hexagon::V6_vL32Ub_ai; + LoadOpc = UseAligned(NeedAlign, HasAlign) ? Hexagon::V6_vL32b_ai + : Hexagon::V6_vL32Ub_ai; BuildMI(B, It, DL, HII.get(LoadOpc), DstLo) .addFrameIndex(FI) .addImm(0) .cloneMemRefs(*MI); // Load high part. - LoadOpc = NeedAlign <= MinAlign(HasAlign, Size) ? Hexagon::V6_vL32b_ai - : Hexagon::V6_vL32Ub_ai; + LoadOpc = UseAligned(NeedAlign, HasAlign) ? Hexagon::V6_vL32b_ai + : Hexagon::V6_vL32Ub_ai; BuildMI(B, It, DL, HII.get(LoadOpc), DstHi) .addFrameIndex(FI) .addImm(Size) @@ -1832,6 +1876,7 @@ bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &B, if (!MI->getOperand(0).isFI()) return false; + bool NeedsAligna = needsAligna(MF); auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); DebugLoc DL = MI->getDebugLoc(); Register SrcR = MI->getOperand(2).getReg(); @@ -1840,8 +1885,9 @@ bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &B, unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass); unsigned HasAlign = MFI.getObjectAlignment(FI); - unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai - : Hexagon::V6_vS32Ub_ai; + bool UseAligned = !NeedsAligna && (NeedAlign <= HasAlign); + unsigned StoreOpc = UseAligned ? Hexagon::V6_vS32b_ai + : Hexagon::V6_vS32Ub_ai; BuildMI(B, It, DL, HII.get(StoreOpc)) .addFrameIndex(FI) .addImm(0) @@ -1861,6 +1907,7 @@ bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &B, if (!MI->getOperand(1).isFI()) return false; + bool NeedsAligna = needsAligna(MF); auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); DebugLoc DL = MI->getDebugLoc(); Register DstR = MI->getOperand(0).getReg(); @@ -1868,8 +1915,9 @@ bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &B, unsigned NeedAlign = HRI.getSpillAlignment(Hexagon::HvxVRRegClass); unsigned HasAlign = MFI.getObjectAlignment(FI); - unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai - : Hexagon::V6_vL32Ub_ai; + bool UseAligned = !NeedsAligna && (NeedAlign <= HasAlign); + unsigned LoadOpc = UseAligned ? Hexagon::V6_vL32b_ai + : Hexagon::V6_vL32Ub_ai; BuildMI(B, It, DL, HII.get(LoadOpc), DstR) .addFrameIndex(FI) .addImm(0) @@ -1912,11 +1960,9 @@ bool HexagonFrameLowering::expandSpillMacros(MachineFunction &MF, Changed |= expandLoadVecPred(B, I, MRI, HII, NewRegs); break; case Hexagon::PS_vloadrw_ai: - case Hexagon::PS_vloadrwu_ai: Changed |= expandLoadVec2(B, I, MRI, HII, NewRegs); break; case Hexagon::PS_vstorerw_ai: - case Hexagon::PS_vstorerwu_ai: Changed |= expandStoreVec2(B, I, MRI, HII, NewRegs); break; } @@ -1961,7 +2007,15 @@ void HexagonFrameLowering::determineCalleeSaves(MachineFunction &MF, for (auto *RC : SpillRCs) { if (!needToReserveScavengingSpillSlots(MF, HRI, RC)) continue; - unsigned Num = RC == &Hexagon::IntRegsRegClass ? NumberScavengerSlots : 1; + unsigned Num = 1; + switch (RC->getID()) { + case Hexagon::IntRegsRegClassID: + Num = NumberScavengerSlots; + break; + case Hexagon::HvxQRRegClassID: + Num = 2; // Vector predicate spills also need a vector register. + break; + } unsigned S = HRI.getSpillSize(*RC), A = HRI.getSpillAlignment(*RC); for (unsigned i = 0; i < Num; i++) { int NewFI = MFI.CreateSpillStackObject(S, A); @@ -2389,9 +2443,9 @@ bool HexagonFrameLowering::needsAligna(const MachineFunction &MF) const { const MachineFrameInfo &MFI = MF.getFrameInfo(); if (!MFI.hasVarSizedObjects()) return false; - unsigned MaxA = MFI.getMaxAlignment(); - if (MaxA <= getStackAlignment()) - return false; + // Do not check for max stack object alignment here, because the stack + // may not be complete yet. Assume that we will need PS_aligna if there + // are variable-sized objects. return true; } |