X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FPowerPC%2FPPCRegisterInfo.cpp;h=b7e3ac2824049b295abb3adb48179da294ce4598;hb=bb46f52027416598a662dc1c58f48d9d56b1a65b;hp=984021068b2fc3fed89d9262f6490eeeca8a4727;hpb=3541af73b6b8a083cf2d7784438d60e8bcce3883;p=oota-llvm.git diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 984021068b2..b7e3ac28240 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -19,6 +19,7 @@ #include "PPCRegisterInfo.h" #include "PPCFrameInfo.h" #include "PPCSubtarget.h" +#include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/Type.h" @@ -30,7 +31,6 @@ #include "llvm/CodeGen/MachineLocation.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" -#include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" @@ -332,7 +332,8 @@ PPCRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { // static bool needsFP(const MachineFunction &MF) { const MachineFrameInfo *MFI = MF.getFrameInfo(); - return NoFramePointerElim || MFI->hasVarSizedObjects(); + return NoFramePointerElim || MFI->hasVarSizedObjects() || + (PerformTailCallOpt && MF.getInfo()->hasFastCall()); } static bool spillsCR(const MachineFunction &MF) { @@ -346,6 +347,7 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const { Reserved.set(PPC::R1); Reserved.set(PPC::LR); Reserved.set(PPC::LR8); + Reserved.set(PPC::RM); // In Linux, r2 is reserved for the OS. if (!Subtarget.isDarwin()) @@ -388,20 +390,51 @@ bool PPCRegisterInfo::hasFP(const MachineFunction &MF) const { /// MustSaveLR - Return true if this function requires that we save the LR /// register onto the stack in the prolog and restore it in the epilog of the /// function. -static bool MustSaveLR(const MachineFunction &MF) { +static bool MustSaveLR(const MachineFunction &MF, unsigned LR) { const PPCFunctionInfo *MFI = MF.getInfo(); - // We need an save/restore of LR if there is any use/def of LR explicitly, or - // if there is some use of the LR stack slot (e.g. for builtin_return_address. - return MFI->usesLR() || MFI->isLRStoreRequired() || - // FIXME: Anything that has a call should clobber the LR register, - // isn't this redundant?? - MF.getFrameInfo()->hasCalls(); + // We need a save/restore of LR if there is any def of LR (which is + // defined by calls, including the PIC setup sequence), or if there is + // some use of the LR stack slot (e.g. for builtin_return_address). + // (LR comes in 32 and 64 bit versions.) + MachineRegisterInfo::def_iterator RI = MF.getRegInfo().def_begin(LR); + return RI !=MF.getRegInfo().def_end() || MFI->isLRStoreRequired(); } + + void PPCRegisterInfo:: eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { + if (PerformTailCallOpt && I->getOpcode() == PPC::ADJCALLSTACKUP) { + // Add (actually subtract) back the amount the callee popped on return. + if (int CalleeAmt = I->getOperand(1).getImm()) { + bool is64Bit = Subtarget.isPPC64(); + CalleeAmt *= -1; + unsigned StackReg = is64Bit ? PPC::X1 : PPC::R1; + unsigned TmpReg = is64Bit ? PPC::X0 : PPC::R0; + unsigned ADDIInstr = is64Bit ? PPC::ADDI8 : PPC::ADDI; + unsigned ADDInstr = is64Bit ? PPC::ADD8 : PPC::ADD4; + unsigned LISInstr = is64Bit ? PPC::LIS8 : PPC::LIS; + unsigned ORIInstr = is64Bit ? PPC::ORI8 : PPC::ORI; + + if (isInt16(CalleeAmt)) { + BuildMI(MBB, I, TII.get(ADDIInstr), StackReg).addReg(StackReg). + addImm(CalleeAmt); + } else { + MachineBasicBlock::iterator MBBI = I; + BuildMI(MBB, MBBI, TII.get(LISInstr), TmpReg) + .addImm(CalleeAmt >> 16); + BuildMI(MBB, MBBI, TII.get(ORIInstr), TmpReg) + .addReg(TmpReg, false, false, true) + .addImm(CalleeAmt & 0xFFFF); + BuildMI(MBB, MBBI, TII.get(ADDInstr)) + .addReg(StackReg) + .addReg(StackReg) + .addReg(TmpReg); + } + } + } // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions. MBB.erase(I); } @@ -597,7 +630,7 @@ void PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, // Find out which operand is the frame index. unsigned FIOperandNo = 0; - while (!MI.getOperand(FIOperandNo).isFrameIndex()) { + while (!MI.getOperand(FIOperandNo).isFI()) { ++FIOperandNo; assert(FIOperandNo != MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); @@ -902,7 +935,7 @@ PPCRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, // Save and clear the LR state. PPCFunctionInfo *FI = MF.getInfo(); unsigned LR = getRARegister(); - FI->setUsesLR(MF.getRegInfo().isPhysRegUsed(LR)); + FI->setMustSaveLR(MustSaveLR(MF, LR)); MF.getRegInfo().setPhysRegUnused(LR); // Save R31 if necessary @@ -924,6 +957,13 @@ PPCRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, FI->setFramePointerSaveIndex(FPSI); } + // Reserve stack space to move the linkage area to in case of a tail call. + int TCSPDelta = 0; + if (PerformTailCallOpt && (TCSPDelta=FI->getTailCallSPDelta()) < 0) { + int AddFPOffsetAmount = IsELF32_ABI ? -4 : 0; + MF.getFrameInfo()->CreateFixedObject( -1 * TCSPDelta, + AddFPOffsetAmount + TCSPDelta); + } // Reserve a slot closest to SP or frame pointer if we have a dynalloc or // a large stack, which will require scavenging a register to materialize a // large offset. @@ -976,8 +1016,9 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { bool IsPPC64 = Subtarget.isPPC64(); // Get operating system bool IsMachoABI = Subtarget.isMachoABI(); - // Check if the link register (LR) has been used. - bool UsesLR = MustSaveLR(MF); + // Check if the link register (LR) must be saved. + PPCFunctionInfo *FI = MF.getInfo(); + bool MustSaveLR = FI->mustSaveLR(); // Do we have a frame pointer for this function? bool HasFP = hasFP(MF) && FrameSize; @@ -985,7 +1026,7 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI); if (IsPPC64) { - if (UsesLR) + if (MustSaveLR) BuildMI(MBB, MBBI, TII.get(PPC::MFLR8), PPC::X0); if (HasFP) @@ -994,13 +1035,13 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { .addImm(FPOffset/4) .addReg(PPC::X1); - if (UsesLR) + if (MustSaveLR) BuildMI(MBB, MBBI, TII.get(PPC::STD)) .addReg(PPC::X0) .addImm(LROffset / 4) .addReg(PPC::X1); } else { - if (UsesLR) + if (MustSaveLR) BuildMI(MBB, MBBI, TII.get(PPC::MFLR), PPC::R0); if (HasFP) @@ -1009,7 +1050,7 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { .addImm(FPOffset) .addReg(PPC::R1); - if (UsesLR) + if (MustSaveLR) BuildMI(MBB, MBBI, TII.get(PPC::STW)) .addReg(PPC::R0) .addImm(LROffset) @@ -1026,7 +1067,7 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { if (needsFrameMoves) { // Mark effective beginning of when frame pointer becomes valid. FrameLabelId = MMI->NextLabelID(); - BuildMI(MBB, MBBI, TII.get(PPC::LABEL)).addImm(FrameLabelId).addImm(0); + BuildMI(MBB, MBBI, TII.get(PPC::DBG_LABEL)).addImm(FrameLabelId); } // Adjust stack pointer: r1 += NegFrameSize. @@ -1123,7 +1164,7 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { for (unsigned I = 0, E = CSI.size(); I != E; ++I) { int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); unsigned Reg = CSI[I].getReg(); - if (Reg == PPC::LR || Reg == PPC::LR8) continue; + if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue; MachineLocation CSDst(MachineLocation::VirtualFP, Offset); MachineLocation CSSrc(Reg); Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc)); @@ -1135,7 +1176,7 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { // Mark effective beginning of when frame pointer is ready. unsigned ReadyLabelId = MMI->NextLabelID(); - BuildMI(MBB, MBBI, TII.get(PPC::LABEL)).addImm(ReadyLabelId).addImm(0); + BuildMI(MBB, MBBI, TII.get(PPC::DBG_LABEL)).addImm(ReadyLabelId); MachineLocation FPDst(HasFP ? (IsPPC64 ? PPC::X31 : PPC::R31) : (IsPPC64 ? PPC::X1 : PPC::R1)); @@ -1160,7 +1201,15 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { void PPCRegisterInfo::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = prior(MBB.end()); - assert(MBBI->getOpcode() == PPC::BLR && + unsigned RetOpcode = MBBI->getOpcode(); + + assert( (RetOpcode == PPC::BLR || + RetOpcode == PPC::TCRETURNri || + RetOpcode == PPC::TCRETURNdi || + RetOpcode == PPC::TCRETURNai || + RetOpcode == PPC::TCRETURNri8 || + RetOpcode == PPC::TCRETURNdi8 || + RetOpcode == PPC::TCRETURNai8) && "Can only insert epilog into returning blocks"); // Get alignment info so we know how to restore r1 @@ -1169,33 +1218,88 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF, unsigned MaxAlign = MFI->getMaxAlignment(); // Get the number of bytes allocated from the FrameInfo. - unsigned FrameSize = MFI->getStackSize(); + int FrameSize = MFI->getStackSize(); // Get processor type. bool IsPPC64 = Subtarget.isPPC64(); // Get operating system bool IsMachoABI = Subtarget.isMachoABI(); - // Check if the link register (LR) has been used. - bool UsesLR = MustSaveLR(MF); + // Check if the link register (LR) has been saved. + PPCFunctionInfo *FI = MF.getInfo(); + bool MustSaveLR = FI->mustSaveLR(); // Do we have a frame pointer for this function? bool HasFP = hasFP(MF) && FrameSize; int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64, IsMachoABI); int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI); + bool UsesTCRet = RetOpcode == PPC::TCRETURNri || + RetOpcode == PPC::TCRETURNdi || + RetOpcode == PPC::TCRETURNai || + RetOpcode == PPC::TCRETURNri8 || + RetOpcode == PPC::TCRETURNdi8 || + RetOpcode == PPC::TCRETURNai8; + + if (UsesTCRet) { + int MaxTCRetDelta = FI->getTailCallSPDelta(); + MachineOperand &StackAdjust = MBBI->getOperand(1); + assert(StackAdjust.isImm() && "Expecting immediate value."); + // Adjust stack pointer. + int StackAdj = StackAdjust.getImm(); + int Delta = StackAdj - MaxTCRetDelta; + assert((Delta >= 0) && "Delta must be positive"); + if (MaxTCRetDelta>0) + FrameSize += (StackAdj +Delta); + else + FrameSize += StackAdj; + } + if (FrameSize) { // The loaded (or persistent) stack pointer value is offset by the 'stwu' // on entry to the function. Add this offset back now. - if (!Subtarget.isPPC64()) { - if (isInt16(FrameSize) && (!ALIGN_STACK || TargetAlign >= MaxAlign) && - !MFI->hasVarSizedObjects()) { - BuildMI(MBB, MBBI, TII.get(PPC::ADDI), PPC::R1) - .addReg(PPC::R1).addImm(FrameSize); + if (!IsPPC64) { + // If this function contained a fastcc call and PerformTailCallOpt is + // enabled (=> hasFastCall()==true) the fastcc call might contain a tail + // call which invalidates the stack pointer value in SP(0). So we use the + // value of R31 in this case. + if (FI->hasFastCall() && isInt16(FrameSize)) { + assert(hasFP(MF) && "Expecting a valid the frame pointer."); + BuildMI(MBB, MBBI, TII.get(PPC::ADDI), PPC::R1) + .addReg(PPC::R31).addImm(FrameSize); + } else if(FI->hasFastCall()) { + BuildMI(MBB, MBBI, TII.get(PPC::LIS), PPC::R0) + .addImm(FrameSize >> 16); + BuildMI(MBB, MBBI, TII.get(PPC::ORI), PPC::R0) + .addReg(PPC::R0, false, false, true) + .addImm(FrameSize & 0xFFFF); + BuildMI(MBB, MBBI, TII.get(PPC::ADD4)) + .addReg(PPC::R1) + .addReg(PPC::R31) + .addReg(PPC::R0); + } else if (isInt16(FrameSize) && + (!ALIGN_STACK || TargetAlign >= MaxAlign) && + !MFI->hasVarSizedObjects()) { + BuildMI(MBB, MBBI, TII.get(PPC::ADDI), PPC::R1) + .addReg(PPC::R1).addImm(FrameSize); } else { BuildMI(MBB, MBBI, TII.get(PPC::LWZ),PPC::R1).addImm(0).addReg(PPC::R1); } } else { - if (isInt16(FrameSize) && TargetAlign >= MaxAlign && + if (FI->hasFastCall() && isInt16(FrameSize)) { + assert(hasFP(MF) && "Expecting a valid the frame pointer."); + BuildMI(MBB, MBBI, TII.get(PPC::ADDI8), PPC::X1) + .addReg(PPC::X31).addImm(FrameSize); + } else if(FI->hasFastCall()) { + BuildMI(MBB, MBBI, TII.get(PPC::LIS8), PPC::X0) + .addImm(FrameSize >> 16); + BuildMI(MBB, MBBI, TII.get(PPC::ORI8), PPC::X0) + .addReg(PPC::X0, false, false, true) + .addImm(FrameSize & 0xFFFF); + BuildMI(MBB, MBBI, TII.get(PPC::ADD8)) + .addReg(PPC::X1) + .addReg(PPC::X31) + .addReg(PPC::X0); + } else if (isInt16(FrameSize) && TargetAlign >= MaxAlign && !MFI->hasVarSizedObjects()) { BuildMI(MBB, MBBI, TII.get(PPC::ADDI8), PPC::X1) .addReg(PPC::X1).addImm(FrameSize); @@ -1206,7 +1310,7 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF, } if (IsPPC64) { - if (UsesLR) + if (MustSaveLR) BuildMI(MBB, MBBI, TII.get(PPC::LD), PPC::X0) .addImm(LROffset/4).addReg(PPC::X1); @@ -1214,10 +1318,10 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF, BuildMI(MBB, MBBI, TII.get(PPC::LD), PPC::X31) .addImm(FPOffset/4).addReg(PPC::X1); - if (UsesLR) + if (MustSaveLR) BuildMI(MBB, MBBI, TII.get(PPC::MTLR8)).addReg(PPC::X0); } else { - if (UsesLR) + if (MustSaveLR) BuildMI(MBB, MBBI, TII.get(PPC::LWZ), PPC::R0) .addImm(LROffset).addReg(PPC::R1); @@ -1225,9 +1329,67 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF, BuildMI(MBB, MBBI, TII.get(PPC::LWZ), PPC::R31) .addImm(FPOffset).addReg(PPC::R1); - if (UsesLR) + if (MustSaveLR) BuildMI(MBB, MBBI, TII.get(PPC::MTLR)).addReg(PPC::R0); } + + // Callee pop calling convention. Pop parameter/linkage area. Used for tail + // call optimization + if (PerformTailCallOpt && RetOpcode == PPC::BLR && + MF.getFunction()->getCallingConv() == CallingConv::Fast) { + PPCFunctionInfo *FI = MF.getInfo(); + unsigned CallerAllocatedAmt = FI->getMinReservedArea(); + unsigned StackReg = IsPPC64 ? PPC::X1 : PPC::R1; + unsigned FPReg = IsPPC64 ? PPC::X31 : PPC::R31; + unsigned TmpReg = IsPPC64 ? PPC::X0 : PPC::R0; + unsigned ADDIInstr = IsPPC64 ? PPC::ADDI8 : PPC::ADDI; + unsigned ADDInstr = IsPPC64 ? PPC::ADD8 : PPC::ADD4; + unsigned LISInstr = IsPPC64 ? PPC::LIS8 : PPC::LIS; + unsigned ORIInstr = IsPPC64 ? PPC::ORI8 : PPC::ORI; + + if (CallerAllocatedAmt && isInt16(CallerAllocatedAmt)) { + BuildMI(MBB, MBBI, TII.get(ADDIInstr), StackReg) + .addReg(StackReg).addImm(CallerAllocatedAmt); + } else { + BuildMI(MBB, MBBI, TII.get(LISInstr), TmpReg) + .addImm(CallerAllocatedAmt >> 16); + BuildMI(MBB, MBBI, TII.get(ORIInstr), TmpReg) + .addReg(TmpReg, false, false, true) + .addImm(CallerAllocatedAmt & 0xFFFF); + BuildMI(MBB, MBBI, TII.get(ADDInstr)) + .addReg(StackReg) + .addReg(FPReg) + .addReg(TmpReg); + } + } else if (RetOpcode == PPC::TCRETURNdi) { + MBBI = prior(MBB.end()); + MachineOperand &JumpTarget = MBBI->getOperand(0); + BuildMI(MBB, MBBI, TII.get(PPC::TAILB)). + addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); + } else if (RetOpcode == PPC::TCRETURNri) { + MBBI = prior(MBB.end()); + MachineOperand &JumpTarget = MBBI->getOperand(0); + assert(JumpTarget.isReg() && "Expecting register operand."); + BuildMI(MBB, MBBI, TII.get(PPC::TAILBCTR)); + } else if (RetOpcode == PPC::TCRETURNai) { + MBBI = prior(MBB.end()); + MachineOperand &JumpTarget = MBBI->getOperand(0); + BuildMI(MBB, MBBI, TII.get(PPC::TAILBA)).addImm(JumpTarget.getImm()); + } else if (RetOpcode == PPC::TCRETURNdi8) { + MBBI = prior(MBB.end()); + MachineOperand &JumpTarget = MBBI->getOperand(0); + BuildMI(MBB, MBBI, TII.get(PPC::TAILB8)). + addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); + } else if (RetOpcode == PPC::TCRETURNri8) { + MBBI = prior(MBB.end()); + MachineOperand &JumpTarget = MBBI->getOperand(0); + assert(JumpTarget.isReg() && "Expecting register operand."); + BuildMI(MBB, MBBI, TII.get(PPC::TAILBCTR8)); + } else if (RetOpcode == PPC::TCRETURNai8) { + MBBI = prior(MBB.end()); + MachineOperand &JumpTarget = MBBI->getOperand(0); + BuildMI(MBB, MBBI, TII.get(PPC::TAILBA8)).addImm(JumpTarget.getImm()); + } } unsigned PPCRegisterInfo::getRARegister() const {