From 19ed0d05b8d7ea12a2057b22534c432122a84121 Mon Sep 17 00:00:00 2001 From: Robert Lytton Date: Tue, 18 Feb 2014 11:21:53 +0000 Subject: 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 --- llvm/lib/Target/XCore/XCoreFrameLowering.cpp | 111 ++++++++++++++++++--------- 1 file changed, 73 insertions(+), 38 deletions(-) (limited to 'llvm/lib/Target/XCore/XCoreFrameLowering.cpp') 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 > &SpillList, +static void GetSpillList(SmallVectorImpl &SpillList, MachineFrameInfo *MFI, XCoreFunctionInfo *XFI, bool fetchLR, bool fetchFP) { if (fetchLR) { int Offset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - SpillList.push_back(std::pair(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(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 > &SpillList, +static void GetEHSpillList(SmallVectorImpl &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(MFI->getObjectOffset(EHSlot[0]), - TL->getExceptionPointerRegister())); - SpillList.push_back( - std::pair(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 > &SpillList) { + SmallVectorImpl &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,2> SpillList; + SmallVector 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,2> SpillList; + SmallVector 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,2> SpillList; + SmallVector 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,2> SpillList; + SmallVector SpillList; GetSpillList(SpillList, MFI, XFI, restoreLR, FP); RestoreSpillList(MBB, MBBI, dl, TII, RemainingAdj, SpillList); -- cgit v1.2.3