X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FHexagon%2FHexagonFrameLowering.cpp;h=2b04f25dd677eea57bc1a4b9c642dd3a9393702a;hb=488401e9c995b6bfcc54fa7c54a5ec09e75d01a1;hp=50db2a6d56cea5fed172d8120ce079217a9746a9;hpb=d04a8d4b33ff316ca4cf961e06c9e312eff8e64f;p=oota-llvm.git diff --git a/lib/Target/Hexagon/HexagonFrameLowering.cpp b/lib/Target/Hexagon/HexagonFrameLowering.cpp index 50db2a6d56c..2b04f25dd67 100644 --- a/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -25,14 +25,14 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" -#include "llvm/Function.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/Type.h" using namespace llvm; @@ -76,17 +76,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()); 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 +108,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. // @@ -166,37 +139,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()); 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)) { + if (hasFP(MF) || MF.getTarget().getOptLevel() == CodeGenOpt::None) { MachineBasicBlock::iterator MBBI = prior(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(); - + // 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::ADD_rr), + 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 + if (STI.hasV4TOps() && MBBI->getOpcode() == Hexagon::JMPret && !DisableDeallocRet) { - // Remove jumpr node. - MBB.erase(MBBI); + // 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 : prior(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() : prior(Term); + if (I != MBB.end() && + I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4) + return; + + BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME)); } } } @@ -326,6 +325,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);