X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FTarget%2FHexagon%2FHexagonFrameLowering.cpp;h=041eb00dba7e4ea0493a3d914bf69490cc063bdb;hb=7e9a77a2aa752bd7a22141ff8e6f33243f90db1c;hp=e8a692406e080de627e64a7f83625183036a1622;hpb=79aa3417eb6f58d668aadfedf075240a41d35a26;p=oota-llvm.git diff --git a/lib/Target/Hexagon/HexagonFrameLowering.cpp b/lib/Target/Hexagon/HexagonFrameLowering.cpp index e8a692406e0..041eb00dba7 100644 --- a/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -11,28 +11,28 @@ #include "HexagonFrameLowering.h" #include "Hexagon.h" #include "HexagonInstrInfo.h" +#include "HexagonMachineFunctionInfo.h" #include "HexagonRegisterInfo.h" #include "HexagonSubtarget.h" #include "HexagonTargetMachine.h" -#include "HexagonMachineFunctionInfo.h" -#include "llvm/Function.h" -#include "llvm/Type.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" -#include "llvm/MC/MachineLocation.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Type.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MachineLocation.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Support/CommandLine.h" using namespace llvm; @@ -50,7 +50,10 @@ void HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const { unsigned FrameSize = MFI->getStackSize(); // Get the alignments provided by the target. - unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment(); + unsigned TargetAlign = MF.getTarget() + .getSubtargetImpl() + ->getFrameLowering() + ->getStackAlignment(); // Get the maximum call frame size of all the calls. unsigned maxCallFrameSize = MFI->getMaxCallFrameSize(); @@ -76,17 +79,12 @@ void HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const { void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineModuleInfo &MMI = MF.getMMI(); MachineBasicBlock::iterator MBBI = MBB.begin(); - const HexagonRegisterInfo *QRI = - static_cast(MF.getTarget().getRegisterInfo()); + const HexagonRegisterInfo *QRI = static_cast( + MF.getSubtarget().getRegisterInfo()); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); determineFrameLayout(MF); - // Check if frame moves are needed for EH. - bool needsFrameMoves = MMI.hasDebugInfo() || - !MF.getFunction()->needsUnwindTableEntry(); - // Get the number of bytes to allocate from the FrameInfo. int NumBytes = (int) MFI->getStackSize(); @@ -113,28 +111,6 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { MO.setImm(MFI->getMaxCallFrameSize()); } - std::vector &Moves = MMI.getFrameMoves(); - - if (needsFrameMoves) { - // Advance CFA. DW_CFA_def_cfa - unsigned FPReg = QRI->getFrameRegister(); - unsigned RAReg = QRI->getRARegister(); - - MachineLocation Dst(MachineLocation::VirtualFP); - MachineLocation Src(FPReg, -8); - Moves.push_back(MachineMove(0, Dst, Src)); - - // R31 = (R31 - #4) - MachineLocation LRDst(RAReg, -4); - MachineLocation LRSrc(RAReg); - Moves.push_back(MachineMove(0, LRDst, LRSrc)); - - // R30 = (R30 - #8) - MachineLocation SPDst(FPReg, -8); - MachineLocation SPSrc(FPReg); - Moves.push_back(MachineMove(0, SPDst, SPSrc)); - } - // // Only insert ALLOCFRAME if we need to. // @@ -142,7 +118,7 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { // Check for overflow. // Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used? const int ALLOCFRAME_MAX = 16384; - const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); + const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); if (NumBytes >= ALLOCFRAME_MAX) { // Emit allocframe(#0). @@ -151,7 +127,7 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const { // Subtract offset from frame pointer. BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real), HEXAGON_RESERVED_REG_1).addImm(NumBytes); - BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr), + BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::A2_sub), QRI->getStackRegister()). addReg(QRI->getStackRegister()). addReg(HEXAGON_RESERVED_REG_1); @@ -166,37 +142,63 @@ bool HexagonFrameLowering::hasTailCall(MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); unsigned RetOpcode = MBBI->getOpcode(); - return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext;} + return RetOpcode == Hexagon::TCRETURNtg || RetOpcode == Hexagon::TCRETURNtext; +} void HexagonFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { - MachineBasicBlock::iterator MBBI = prior(MBB.end()); + MachineBasicBlock::iterator MBBI = std::prev(MBB.end()); DebugLoc dl = MBBI->getDebugLoc(); // - // Only insert deallocframe if we need to. + // Only insert deallocframe if we need to. Also at -O0. See comment + // in emitPrologue above. // - if (hasFP(MF)) { - MachineBasicBlock::iterator MBBI = prior(MBB.end()); + if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) { + MachineBasicBlock::iterator MBBI = std::prev(MBB.end()); MachineBasicBlock::iterator MBBI_end = MBB.end(); - // - // For Hexagon, we don't need the frame size. - // - MachineFrameInfo *MFI = MF.getFrameInfo(); - int NumBytes = (int) MFI->getStackSize(); - - const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); + const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); + // Handle EH_RETURN. + if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) { + assert(MBBI->getOperand(0).isReg() && "Offset should be in register!"); + BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)); + BuildMI(MBB, MBBI, dl, TII.get(Hexagon::A2_add), + Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28); + return; + } // Replace 'jumpr r31' instruction with dealloc_return for V4 and higher // versions. - if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPR - && !DisableDeallocRet) { - // Remove jumpr node. - MBB.erase(MBBI); + if (MF.getTarget().getSubtarget().hasV4TOps() && + MBBI->getOpcode() == Hexagon::JMPret && !DisableDeallocRet) { + // Check for RESTORE_DEALLOC_RET_JMP_V4 call. Don't emit an extra DEALLOC + // instruction if we encounter it. + MachineBasicBlock::iterator BeforeJMPR = + MBB.begin() == MBBI ? MBBI : std::prev(MBBI); + if (BeforeJMPR != MBBI && + BeforeJMPR->getOpcode() == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) { + // Remove the JMPR node. + MBB.erase(MBBI); + return; + } + // Add dealloc_return. - BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4)) - .addImm(NumBytes); - } else { // Add deallocframe for V2 and V3. - BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)).addImm(NumBytes); + MachineInstrBuilder MIB = + BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4)); + // Transfer the function live-out registers. + MIB->copyImplicitOps(*MBB.getParent(), &*MBBI); + // Remove the JUMPR node. + MBB.erase(MBBI); + } else { // Add deallocframe for V2 and V3, and V4 tail calls. + // Check for RESTORE_DEALLOC_BEFORE_TAILCALL_V4. We don't need an extra + // DEALLOCFRAME instruction after it. + MachineBasicBlock::iterator Term = MBB.getFirstTerminator(); + MachineBasicBlock::iterator I = + Term == MBB.begin() ? MBB.end() : std::prev(Term); + if (I != MBB.end() && + I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4) + return; + + BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)); } } } @@ -209,6 +211,16 @@ bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const { FuncInfo->hasClobberLR() ); } +static inline +unsigned uniqueSuperReg(unsigned Reg, const TargetRegisterInfo *TRI) { + MCSuperRegIterator SRI(Reg, TRI); + assert(SRI.isValid() && "Expected a superreg"); + unsigned SuperReg = *SRI; + ++SRI; + assert(!SRI.isValid() && "Expected exactly one superreg"); + return SuperReg; +} + bool HexagonFrameLowering::spillCalleeSavedRegisters( MachineBasicBlock &MBB, @@ -216,7 +228,7 @@ HexagonFrameLowering::spillCalleeSavedRegisters( const std::vector &CSI, const TargetRegisterInfo *TRI) const { MachineFunction *MF = MBB.getParent(); - const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); + const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); if (CSI.empty()) { return false; @@ -235,26 +247,21 @@ HexagonFrameLowering::spillCalleeSavedRegisters( // // Check if we can use a double-word store. // - const uint16_t* SuperReg = TRI->getSuperRegisters(Reg); - - // Assume that there is exactly one superreg. - assert(SuperReg[0] && !SuperReg[1] && "Expected exactly one superreg"); + unsigned SuperReg = uniqueSuperReg(Reg, TRI); bool CanUseDblStore = false; - const TargetRegisterClass* SuperRegClass = 0; + const TargetRegisterClass* SuperRegClass = nullptr; if (ContiguousRegs && (i < CSI.size()-1)) { - const uint16_t* SuperRegNext = TRI->getSuperRegisters(CSI[i+1].getReg()); - assert(SuperRegNext[0] && !SuperRegNext[1] && - "Expected exactly one superreg"); - SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg[0]); - CanUseDblStore = (SuperRegNext[0] == SuperReg[0]); + unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI); + SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg); + CanUseDblStore = (SuperRegNext == SuperReg); } if (CanUseDblStore) { - TII.storeRegToStackSlot(MBB, MI, SuperReg[0], true, + TII.storeRegToStackSlot(MBB, MI, SuperReg, true, CSI[i+1].getFrameIdx(), SuperRegClass, TRI); - MBB.addLiveIn(SuperReg[0]); + MBB.addLiveIn(SuperReg); ++i; } else { // Cannot use a double-word store. @@ -276,7 +283,7 @@ bool HexagonFrameLowering::restoreCalleeSavedRegisters( const TargetRegisterInfo *TRI) const { MachineFunction *MF = MBB.getParent(); - const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); + const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); if (CSI.empty()) { return false; @@ -295,25 +302,20 @@ bool HexagonFrameLowering::restoreCalleeSavedRegisters( // // Check if we can use a double-word load. // - const uint16_t* SuperReg = TRI->getSuperRegisters(Reg); - const TargetRegisterClass* SuperRegClass = 0; - - // Assume that there is exactly one superreg. - assert(SuperReg[0] && !SuperReg[1] && "Expected exactly one superreg"); + unsigned SuperReg = uniqueSuperReg(Reg, TRI); + const TargetRegisterClass* SuperRegClass = nullptr; bool CanUseDblLoad = false; if (ContiguousRegs && (i < CSI.size()-1)) { - const uint16_t* SuperRegNext = TRI->getSuperRegisters(CSI[i+1].getReg()); - assert(SuperRegNext[0] && !SuperRegNext[1] && - "Expected exactly one superreg"); - SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg[0]); - CanUseDblLoad = (SuperRegNext[0] == SuperReg[0]); + unsigned SuperRegNext = uniqueSuperReg(CSI[i+1].getReg(), TRI); + SuperRegClass = TRI->getMinimalPhysRegClass(SuperReg); + CanUseDblLoad = (SuperRegNext == SuperReg); } if (CanUseDblLoad) { - TII.loadRegFromStackSlot(MBB, MI, SuperReg[0], CSI[i+1].getFrameIdx(), + TII.loadRegFromStackSlot(MBB, MI, SuperReg, CSI[i+1].getFrameIdx(), SuperRegClass, TRI); - MBB.addLiveIn(SuperReg[0]); + MBB.addLiveIn(SuperReg); ++i; } else { // Cannot use a double-word load. @@ -326,6 +328,21 @@ bool HexagonFrameLowering::restoreCalleeSavedRegisters( return true; } +void HexagonFrameLowering:: +eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const { + MachineInstr &MI = *I; + + if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) { + // Hexagon_TODO: add code + } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) { + // Hexagon_TODO: add code + } else { + llvm_unreachable("Cannot handle this call frame pseudo instruction"); + } + MBB.erase(I); +} + int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF, int FI) const { return MF.getFrameInfo()->getObjectOffset(FI);