X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FSystemZ%2FSystemZRegisterInfo.cpp;h=638fd17c9953ee05e32b791a9bb1482496bfed35;hb=6a45d681e53a99b4c4f63e0b1664626a596a8151;hp=6e8982d94a9d4c7cc453f565603a5592e26ccfc4;hpb=66f1b378bc6d7c52ed4398e0d26cc3c0e9865310;p=oota-llvm.git diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/lib/Target/SystemZ/SystemZRegisterInfo.cpp index 6e8982d94a9..638fd17c995 100644 --- a/lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ b/lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -39,7 +39,8 @@ SystemZRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { SystemZ::R6D, SystemZ::R7D, SystemZ::R8D, SystemZ::R9D, SystemZ::R10D, SystemZ::R11D, SystemZ::R12D, SystemZ::R13D, SystemZ::R14D, SystemZ::R15D, - SystemZ::F1, SystemZ::F3, SystemZ::F5, SystemZ::F7, + SystemZ::F8L, SystemZ::F9L, SystemZ::F10L, SystemZ::F11L, + SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L, 0 }; @@ -55,6 +56,8 @@ SystemZRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { &SystemZ::GR64RegClass, &SystemZ::GR64RegClass, &SystemZ::GR64RegClass, &SystemZ::GR64RegClass, &SystemZ::FP64RegClass, &SystemZ::FP64RegClass, + &SystemZ::FP64RegClass, &SystemZ::FP64RegClass, + &SystemZ::FP64RegClass, &SystemZ::FP64RegClass, &SystemZ::FP64RegClass, &SystemZ::FP64RegClass, 0 }; return CalleeSavedRegClasses; @@ -74,7 +77,7 @@ BitVector SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const /// allocas or if frame pointer elimination is disabled. bool SystemZRegisterInfo::hasFP(const MachineFunction &MF) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); - return NoFramePointerElim || MFI->hasVarSizedObjects(); + return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects(); } void SystemZRegisterInfo:: @@ -83,10 +86,11 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MBB.erase(I); } -int SystemZRegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const { +int SystemZRegisterInfo::getFrameIndexOffset(const MachineFunction &MF, + int FI) const { const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - SystemZMachineFunctionInfo *SystemZMFI = + const MachineFrameInfo *MFI = MF.getFrameInfo(); + const SystemZMachineFunctionInfo *SystemZMFI = MF.getInfo(); int Offset = MFI->getObjectOffset(FI) + MFI->getOffsetAdjustment(); uint64_t StackSize = MFI->getStackSize(); @@ -98,14 +102,16 @@ int SystemZRegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const Offset += StackSize - TFI.getOffsetOfLocalArea(); // Skip the register save area if we generated the stack frame. - if (StackSize) + if (StackSize || MFI->hasCalls()) Offset -= TFI.getOffsetOfLocalArea(); return Offset; } -void SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, RegScavenger *RS) const { +unsigned +SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, FrameIndexValue *Value, + RegScavenger *RS) const { assert(SPAdj == 0 && "Unxpected"); unsigned i = 0; @@ -130,10 +136,10 @@ void SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int Offset = getFrameIndexOffset(MF, FrameIndex) + MI.getOperand(i+1).getImm(); // Check whether displacement is too long to fit into 12 bit zext field. - if (Offset < 0 || Offset >= 4096) - MI.setDesc(TII.getLongDispOpc(MI.getOpcode())); + MI.setDesc(TII.getMemoryInstr(MI.getOpcode(), Offset)); MI.getOperand(i+1).ChangeToImmediate(Offset); + return 0; } void @@ -142,18 +148,33 @@ SystemZRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, // Determine whether R15/R14 will ever be clobbered inside the function. And // if yes - mark it as 'callee' saved. MachineFrameInfo *FFI = MF.getFrameInfo(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + + // Check whether high FPRs are ever used, if yes - we need to save R15 as + // well. + static const unsigned HighFPRs[] = { + SystemZ::F8L, SystemZ::F9L, SystemZ::F10L, SystemZ::F11L, + SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L, + SystemZ::F8S, SystemZ::F9S, SystemZ::F10S, SystemZ::F11S, + SystemZ::F12S, SystemZ::F13S, SystemZ::F14S, SystemZ::F15S, + }; + + bool HighFPRsUsed = false; + for (unsigned i = 0, e = array_lengthof(HighFPRs); i != e; ++i) + HighFPRsUsed |= MRI.isPhysRegUsed(HighFPRs[i]); - if (FFI->hasCalls() - /* FIXME: function is varargs */ - /* FIXME: function grabs RA */ - /* FIXME: function calls eh_return */) - MF.getRegInfo().setPhysRegUsed(SystemZ::R14D); + if (FFI->hasCalls()) + /* FIXME: function is varargs */ + /* FIXME: function grabs RA */ + /* FIXME: function calls eh_return */ + MRI.setPhysRegUsed(SystemZ::R14D); - if (FFI->hasCalls() || + if (HighFPRsUsed || + FFI->hasCalls() || FFI->getObjectIndexEnd() != 0 || // Contains automatic variables FFI->hasVarSizedObjects() // Function calls dynamic alloca's /* FIXME: function is varargs */) - MF.getRegInfo().setPhysRegUsed(SystemZ::R15D); + MRI.setPhysRegUsed(SystemZ::R15D); } /// emitSPUpdate - Emit a series of instructions to increment / decrement the @@ -161,19 +182,25 @@ SystemZRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, static void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, int64_t NumBytes, const TargetInstrInfo &TII) { - // FIXME: Handle different stack sizes here. + unsigned Opc; uint64_t Chunk; bool isSub = NumBytes < 0; uint64_t Offset = isSub ? -NumBytes : NumBytes; - unsigned Opc = SystemZ::ADD64ri16; - uint64_t Chunk = (1LL << 15) - 1; - DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() : - DebugLoc::getUnknownLoc()); + + if (Offset >= (1LL << 15) - 1) { + Opc = SystemZ::ADD64ri32; + Chunk = (1LL << 31) - 1; + } else { + Opc = SystemZ::ADD64ri16; + Chunk = (1LL << 15) - 1; + } + + DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); while (Offset) { uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset; MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opc), SystemZ::R15D) - .addReg(SystemZ::R15D).addImm((isSub ? -(int64_t)ThisVal : ThisVal)); + .addReg(SystemZ::R15D).addImm(isSub ? -ThisVal : ThisVal); // The PSW implicit def is dead. MI->getOperand(3).setIsDead(); Offset -= ThisVal; @@ -187,14 +214,15 @@ void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const { SystemZMachineFunctionInfo *SystemZMFI = MF.getInfo(); MachineBasicBlock::iterator MBBI = MBB.begin(); - DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() : - DebugLoc::getUnknownLoc()); + DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); // Get the number of bytes to allocate from the FrameInfo. // Note that area for callee-saved stuff is already allocated, thus we need to // 'undo' the stack movement. - uint64_t StackSize = - MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize(); + uint64_t StackSize = MFI->getStackSize(); + StackSize -= SystemZMFI->getCalleeSavedFrameSize(); + + uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea(); // Skip the callee-saved push instructions. while (MBBI != MBB.end() && @@ -205,10 +233,12 @@ void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const { if (MBBI != MBB.end()) DL = MBBI->getDebugLoc(); - uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea(); - - if (NumBytes) // adjust stack pointer: R15 -= numbytes + // adjust stack pointer: R15 -= numbytes + if (StackSize || MFI->hasCalls()) { + assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) && + "Invalid stack frame calculation!"); emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, TII); + } if (hasFP(MF)) { // Update R11 with the new base value... @@ -216,7 +246,7 @@ void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const { .addReg(SystemZ::R15D); // Mark the FramePtr as live-in in every block except the entry. - for (MachineFunction::iterator I = next(MF.begin()), E = MF.end(); + for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); I != E; ++I) I->addLiveIn(SystemZ::R11D); @@ -231,7 +261,6 @@ void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF, SystemZMachineFunctionInfo *SystemZMFI = MF.getInfo(); unsigned RetOpcode = MBBI->getOpcode(); - DebugLoc DL = MBBI->getDebugLoc(); switch (RetOpcode) { case SystemZ::RET: break; // These are ok @@ -257,10 +286,12 @@ void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF, // During callee-saved restores emission stack frame was not yet finialized // (and thus - the stack size was unknown). Tune the offset having full stack // size in hands. - if (SystemZMFI->getCalleeSavedFrameSize()) { + if (StackSize || MFI->hasCalls()) { assert((MBBI->getOpcode() == SystemZ::MOV64rmm || MBBI->getOpcode() == SystemZ::MOV64rm) && "Expected to see callee-save register restore code"); + assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) && + "Invalid stack frame calculation!"); unsigned i = 0; MachineInstr &MI = *MBBI; @@ -269,7 +300,17 @@ void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF, assert(i < MI.getNumOperands() && "Unexpected restore code!"); } - MI.getOperand(i).ChangeToImmediate(NumBytes + MI.getOperand(i).getImm()); + uint64_t Offset = NumBytes + MI.getOperand(i).getImm(); + // If Offset does not fit into 20-bit signed displacement field we need to + // emit some additional code... + if (Offset > 524287) { + // Fold the displacement into load instruction as much as possible. + NumBytes = Offset - 524287; + Offset = 524287; + emitSPUpdate(MBB, MBBI, NumBytes, TII); + } + + MI.getOperand(i).ChangeToImmediate(Offset); } } @@ -278,7 +319,8 @@ unsigned SystemZRegisterInfo::getRARegister() const { return 0; } -unsigned SystemZRegisterInfo::getFrameRegister(MachineFunction &MF) const { +unsigned +SystemZRegisterInfo::getFrameRegister(const MachineFunction &MF) const { assert(0 && "What is the frame register"); return 0; }