diff options
author | Robert Lytton <robert@xmos.com> | 2014-02-18 11:21:53 +0000 |
---|---|---|
committer | Robert Lytton <robert@xmos.com> | 2014-02-18 11:21:53 +0000 |
commit | 19ed0d05b8d7ea12a2057b22534c432122a84121 (patch) | |
tree | 6810d0f0e205e86529a4f41ebc482c38f81d5dee /llvm/lib/Target/XCore/XCoreFrameLowering.cpp | |
parent | af6c256c348fab7d12222d0e71475d116493ff23 (diff) | |
download | bcm5719-llvm-19ed0d05b8d7ea12a2057b22534c432122a84121.tar.gz bcm5719-llvm-19ed0d05b8d7ea12a2057b22534c432122a84121.zip |
XCore target: addMemOperand as necessary
BuildMI instructions were not including MachineMemOperand information.
This was discovered by 'SingleSource/Benchmarks/Stanford/Oscar' failing
due to a FrameIndex load incorrectly being hoisted by postra-machine-licm.
No other tests have been found to fail.
llvm-svn: 201562
Diffstat (limited to 'llvm/lib/Target/XCore/XCoreFrameLowering.cpp')
-rw-r--r-- | llvm/lib/Target/XCore/XCoreFrameLowering.cpp | 111 |
1 files changed, 73 insertions, 38 deletions
diff --git a/llvm/lib/Target/XCore/XCoreFrameLowering.cpp b/llvm/lib/Target/XCore/XCoreFrameLowering.cpp index 8ea9788b1a8..4a0d8a4b50a 100644 --- a/llvm/lib/Target/XCore/XCoreFrameLowering.cpp +++ b/llvm/lib/Target/XCore/XCoreFrameLowering.cpp @@ -44,6 +44,21 @@ static inline bool isImmU16(unsigned val) { return val < (1 << 16); } +// Helper structure with compare function for handling stack slots. +namespace { +struct StackSlotInfo { + int FI; + int Offset; + unsigned Reg; + StackSlotInfo(int f, int o, int r) : FI(f), Offset(o), Reg(r){}; +}; +} // end anonymous namespace + +static bool CompareSSIOffset(const StackSlotInfo& a, const StackSlotInfo& b) { + return a.Offset < b.Offset; +} + + static void EmitDefCfaRegister(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, @@ -119,55 +134,73 @@ static void IfNeededLDAWSP(MachineBasicBlock &MBB, /// during the emitPrologue/emitEpilogue. /// Registers are ordered according to their frame offset. /// As offsets are negative, the largest offsets will be first. -static void GetSpillList(SmallVectorImpl<std::pair<int,unsigned> > &SpillList, +static void GetSpillList(SmallVectorImpl<StackSlotInfo> &SpillList, MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, bool fetchLR, bool fetchFP) { if (fetchLR) { int Offset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - SpillList.push_back(std::pair<int,unsigned>(Offset, XCore::LR)); + SpillList.push_back(StackSlotInfo(XFI->getLRSpillSlot(), + Offset, + XCore::LR)); } if (fetchFP) { int Offset = MFI->getObjectOffset(XFI->getFPSpillSlot()); - SpillList.push_back(std::pair<int,unsigned>(Offset, FramePtr)); + SpillList.push_back(StackSlotInfo(XFI->getFPSpillSlot(), + Offset, + FramePtr)); } - std::sort(SpillList.begin(), SpillList.end()); + std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset); } /// Creates an ordered list of EH info register 'spills'. /// These slots are only used by the unwinder and calls to llvm.eh.return(). /// Registers are ordered according to their frame offset. /// As offsets are negative, the largest offsets will be first. -static void GetEHSpillList(SmallVectorImpl<std::pair<int,unsigned> > &SpillList, +static void GetEHSpillList(SmallVectorImpl<StackSlotInfo> &SpillList, MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, const TargetLowering *TL) { assert(XFI->hasEHSpillSlot() && "There are no EH register spill slots"); const int* EHSlot = XFI->getEHSpillSlot(); - SpillList.push_back( - std::pair<int,unsigned>(MFI->getObjectOffset(EHSlot[0]), - TL->getExceptionPointerRegister())); - SpillList.push_back( - std::pair<int,unsigned>(MFI->getObjectOffset(EHSlot[1]), - TL->getExceptionSelectorRegister())); - std::sort(SpillList.begin(), SpillList.end()); + SpillList.push_back(StackSlotInfo(EHSlot[0], + MFI->getObjectOffset(EHSlot[0]), + TL->getExceptionPointerRegister())); + SpillList.push_back(StackSlotInfo(EHSlot[0], + MFI->getObjectOffset(EHSlot[1]), + TL->getExceptionSelectorRegister())); + std::sort(SpillList.begin(), SpillList.end(), CompareSSIOffset); +} + + +static MachineMemOperand * +getFrameIndexMMO(MachineBasicBlock &MBB, int FrameIndex, unsigned flags) { + MachineFunction *MF = MBB.getParent(); + const MachineFrameInfo &MFI = *MF->getFrameInfo(); + MachineMemOperand *MMO = + MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIndex), + flags, MFI.getObjectSize(FrameIndex), + MFI.getObjectAlignment(FrameIndex)); + return MMO; } + /// Restore clobbered registers with their spill slot value. /// The SP will be adjusted at the same time, thus the SpillList must be ordered /// with the largest (negative) offsets first. static void RestoreSpillList(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc dl, const TargetInstrInfo &TII, int &RemainingAdj, - SmallVectorImpl<std::pair<int,unsigned> > &SpillList) { + SmallVectorImpl<StackSlotInfo> &SpillList) { for (unsigned i = 0, e = SpillList.size(); i != e; ++i) { - unsigned SpilledReg = SpillList[i].second; - int SpillOffset = SpillList[i].first; - assert(SpillOffset % 4 == 0 && "Misaligned stack offset"); - assert(SpillOffset <= 0 && "Unexpected positive stack offset"); - int OffsetFromTop = - SpillOffset/4; + assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset"); + assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset"); + int OffsetFromTop = - SpillList[i].Offset/4; IfNeededLDAWSP(MBB, MBBI, dl, TII, OffsetFromTop, RemainingAdj); int Offset = RemainingAdj - OffsetFromTop; int Opcode = isImmU6(Offset) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; - BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpilledReg).addImm(Offset); + BuildMI(MBB, MBBI, dl, TII.get(Opcode), SpillList[i].Reg) + .addImm(Offset) + .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI, + MachineMemOperand::MOLoad)); } } @@ -203,6 +236,7 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { const AttributeSet &PAL = MF.getFunction()->getAttributes(); if (PAL.hasAttrSomewhere(Attribute::Nest)) BuildMI(MBB, MBBI, dl, TII.get(XCore::LDWSP_ru6), XCore::R11).addImm(0); + // FIX: Needs addMemOperand() but can't use getFixedStack() or getStack(). // Work out frame sizes. // We will adjust the SP in stages towards the final FrameSize. @@ -234,26 +268,27 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { } // If necessary, save LR and FP to the stack, as we EXTSP. - SmallVector<std::pair<int,unsigned>,2> SpillList; + SmallVector<StackSlotInfo,2> SpillList; GetSpillList(SpillList, MFI, XFI, saveLR, FP); // We want the nearest (negative) offsets first, so reverse list. - std::reverse(SpillList.begin(),SpillList.end()); + std::reverse(SpillList.begin(), SpillList.end()); for (unsigned i = 0, e = SpillList.size(); i != e; ++i) { - unsigned SpillReg = SpillList[i].second; - int SpillOffset = SpillList[i].first; - assert(SpillOffset % 4 == 0 && "Misaligned stack offset"); - assert(SpillOffset <= 0 && "Unexpected positive stack offset"); - int OffsetFromTop = - SpillOffset/4; + assert(SpillList[i].Offset % 4 == 0 && "Misaligned stack offset"); + assert(SpillList[i].Offset <= 0 && "Unexpected positive stack offset"); + int OffsetFromTop = - SpillList[i].Offset/4; IfNeededExtSP(MBB, MBBI, dl, TII, MMI, OffsetFromTop, Adjusted, FrameSize, emitFrameMoves); int Offset = Adjusted - OffsetFromTop; int Opcode = isImmU6(Offset) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; - MBB.addLiveIn(SpillReg); - BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addReg(SpillReg, RegState::Kill) - .addImm(Offset); + MBB.addLiveIn(SpillList[i].Reg); + BuildMI(MBB, MBBI, dl, TII.get(Opcode)) + .addReg(SpillList[i].Reg, RegState::Kill) + .addImm(Offset) + .addMemOperand(getFrameIndexMMO(MBB, SpillList[i].FI, + MachineMemOperand::MOStore)); if (emitFrameMoves) { - unsigned DRegNum = MRI->getDwarfRegNum(SpillReg, true); - EmitCfiOffset(MBB, MBBI, dl, TII, MMI, DRegNum, SpillOffset, NULL); + unsigned DRegNum = MRI->getDwarfRegNum(SpillList[i].Reg, true); + EmitCfiOffset(MBB,MBBI,dl,TII,MMI, DRegNum, SpillList[i].Offset, NULL); } } @@ -284,15 +319,15 @@ void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { if (XFI->hasEHSpillSlot()) { // The unwinder requires stack slot & CFI offsets for the exception info. // We do not save/spill these registers. - SmallVector<std::pair<int,unsigned>,2> SpillList; + SmallVector<StackSlotInfo,2> SpillList; GetEHSpillList(SpillList, MFI, XFI, MF.getTarget().getTargetLowering()); assert(SpillList.size()==2 && "Unexpected SpillList size"); EmitCfiOffset(MBB, MBBI, dl, TII, MMI, - MRI->getDwarfRegNum(SpillList[0].second,true), - SpillList[0].first, NULL); + MRI->getDwarfRegNum(SpillList[0].Reg, true), + SpillList[0].Offset, NULL); EmitCfiOffset(MBB, MBBI, dl, TII, MMI, - MRI->getDwarfRegNum(SpillList[1].second,true), - SpillList[1].first, NULL); + MRI->getDwarfRegNum(SpillList[1].Reg, true), + SpillList[1].Offset, NULL); } } } @@ -315,7 +350,7 @@ void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, if (RetOpcode == XCore::EH_RETURN) { // 'Restore' the exception info the unwinder has placed into the stack slots. - SmallVector<std::pair<int,unsigned>,2> SpillList; + SmallVector<StackSlotInfo,2> SpillList; GetEHSpillList(SpillList, MFI, XFI, MF.getTarget().getTargetLowering()); RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); @@ -339,7 +374,7 @@ void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)).addReg(FramePtr); // If necessary, restore LR and FP from the stack, as we EXTSP. - SmallVector<std::pair<int,unsigned>,2> SpillList; + SmallVector<StackSlotInfo,2> SpillList; GetSpillList(SpillList, MFI, XFI, restoreLR, FP); RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); |