diff options
Diffstat (limited to 'llvm/lib/Target/SystemZ')
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZFrameInfo.cpp | 171 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZFrameInfo.h | 41 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp | 137 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZRegisterInfo.h | 3 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZTargetMachine.h | 6 |
6 files changed, 215 insertions, 145 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameInfo.cpp b/llvm/lib/Target/SystemZ/SystemZFrameInfo.cpp new file mode 100644 index 00000000000..6df072228d8 --- /dev/null +++ b/llvm/lib/Target/SystemZ/SystemZFrameInfo.cpp @@ -0,0 +1,171 @@ +//=====- SystemZFrameInfo.cpp - SystemZ Frame Information ------*- C++ -*-====// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the SystemZ implementation of TargetFrameInfo class. +// +//===----------------------------------------------------------------------===// + +#include "SystemZFrameInfo.h" +#include "SystemZInstrBuilder.h" +#include "SystemZInstrInfo.h" +#include "SystemZMachineFunctionInfo.h" +#include "llvm/Function.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Support/CommandLine.h" + +using namespace llvm; + +/// emitSPUpdate - Emit a series of instructions to increment / decrement the +/// stack pointer by a constant value. +static +void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, + int64_t NumBytes, const TargetInstrInfo &TII) { + unsigned Opc; uint64_t Chunk; + bool isSub = NumBytes < 0; + uint64_t Offset = isSub ? -NumBytes : NumBytes; + + 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 ? -ThisVal : ThisVal); + // The PSW implicit def is dead. + MI->getOperand(3).setIsDead(); + Offset -= ThisVal; + } +} + +void SystemZFrameInfo::emitPrologue(MachineFunction &MF) const { + MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB + const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + const SystemZRegisterInfo *RegInfo = + static_cast<const SystemZRegisterInfo*>(MF.getTarget().getRegisterInfo()); + const SystemZInstrInfo &TII = + *static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo()); + SystemZMachineFunctionInfo *SystemZMFI = + MF.getInfo<SystemZMachineFunctionInfo>(); + MachineBasicBlock::iterator MBBI = MBB.begin(); + 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(); + StackSize -= SystemZMFI->getCalleeSavedFrameSize(); + + uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea(); + + // Skip the callee-saved push instructions. + while (MBBI != MBB.end() && + (MBBI->getOpcode() == SystemZ::MOV64mr || + MBBI->getOpcode() == SystemZ::MOV64mrm)) + ++MBBI; + + if (MBBI != MBB.end()) + DL = MBBI->getDebugLoc(); + + // 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 (RegInfo->hasFP(MF)) { + // Update R11 with the new base value... + BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D) + .addReg(SystemZ::R15D); + + // Mark the FramePtr as live-in in every block except the entry. + for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); + I != E; ++I) + I->addLiveIn(SystemZ::R11D); + + } +} + +void SystemZFrameInfo::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + const MachineFrameInfo *MFI = MF.getFrameInfo(); + const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); + MachineBasicBlock::iterator MBBI = prior(MBB.end()); + const SystemZInstrInfo &TII = + *static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo()); + SystemZMachineFunctionInfo *SystemZMFI = + MF.getInfo<SystemZMachineFunctionInfo>(); + unsigned RetOpcode = MBBI->getOpcode(); + + switch (RetOpcode) { + case SystemZ::RET: break; // These are ok + default: + assert(0 && "Can only insert epilog into returning blocks"); + } + + // 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 NumBytes = StackSize - TFI.getOffsetOfLocalArea(); + + // Skip the final terminator instruction. + while (MBBI != MBB.begin()) { + MachineBasicBlock::iterator PI = prior(MBBI); + --MBBI; + if (!PI->getDesc().isTerminator()) + break; + } + + // 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 (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; + while (!MI.getOperand(i).isImm()) { + ++i; + assert(i < MI.getNumOperands() && "Unexpected restore code!"); + } + + 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); + } +} diff --git a/llvm/lib/Target/SystemZ/SystemZFrameInfo.h b/llvm/lib/Target/SystemZ/SystemZFrameInfo.h new file mode 100644 index 00000000000..2f97331c7a4 --- /dev/null +++ b/llvm/lib/Target/SystemZ/SystemZFrameInfo.h @@ -0,0 +1,41 @@ +//==- SystemZFrameInfo.h - Define TargetFrameInfo for z/System --*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// +// +//===----------------------------------------------------------------------===// + +#ifndef SYSTEMZ_FRAMEINFO_H +#define SYSTEMZ_FRAMEINFO_H + +#include "SystemZ.h" +#include "SystemZSubtarget.h" +#include "llvm/Target/TargetFrameInfo.h" + +namespace llvm { + class SystemZSubtarget; + +class SystemZFrameInfo : public TargetFrameInfo { +protected: + const SystemZSubtarget &STI; + +public: + explicit SystemZFrameInfo(const SystemZSubtarget &sti) + : TargetFrameInfo(TargetFrameInfo::StackGrowsDown, 8, -160), STI(sti) { + } + + /// emitProlog/emitEpilog - These methods insert prolog and epilog code into + /// the function. + void emitPrologue(MachineFunction &MF) const; + void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; +}; + +} // End llvm namespace + +#endif diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp index f8d3e6ac8a6..e738d17056f 100644 --- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -160,143 +160,6 @@ SystemZRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, MRI.setPhysRegUsed(SystemZ::R15D); } -/// emitSPUpdate - Emit a series of instructions to increment / decrement the -/// stack pointer by a constant value. -static -void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, - int64_t NumBytes, const TargetInstrInfo &TII) { - unsigned Opc; uint64_t Chunk; - bool isSub = NumBytes < 0; - uint64_t Offset = isSub ? -NumBytes : NumBytes; - - 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 ? -ThisVal : ThisVal); - // The PSW implicit def is dead. - MI->getOperand(3).setIsDead(); - Offset -= ThisVal; - } -} - -void SystemZRegisterInfo::emitPrologue(MachineFunction &MF) const { - MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB - const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - SystemZMachineFunctionInfo *SystemZMFI = - MF.getInfo<SystemZMachineFunctionInfo>(); - MachineBasicBlock::iterator MBBI = MBB.begin(); - 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(); - StackSize -= SystemZMFI->getCalleeSavedFrameSize(); - - uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea(); - - // Skip the callee-saved push instructions. - while (MBBI != MBB.end() && - (MBBI->getOpcode() == SystemZ::MOV64mr || - MBBI->getOpcode() == SystemZ::MOV64mrm)) - ++MBBI; - - if (MBBI != MBB.end()) - DL = MBBI->getDebugLoc(); - - // 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... - BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D) - .addReg(SystemZ::R15D); - - // Mark the FramePtr as live-in in every block except the entry. - for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); - I != E; ++I) - I->addLiveIn(SystemZ::R11D); - - } -} - -void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { - const MachineFrameInfo *MFI = MF.getFrameInfo(); - const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo(); - MachineBasicBlock::iterator MBBI = prior(MBB.end()); - SystemZMachineFunctionInfo *SystemZMFI = - MF.getInfo<SystemZMachineFunctionInfo>(); - unsigned RetOpcode = MBBI->getOpcode(); - - switch (RetOpcode) { - case SystemZ::RET: break; // These are ok - default: - assert(0 && "Can only insert epilog into returning blocks"); - } - - // 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 NumBytes = StackSize - TFI.getOffsetOfLocalArea(); - - // Skip the final terminator instruction. - while (MBBI != MBB.begin()) { - MachineBasicBlock::iterator PI = prior(MBBI); - --MBBI; - if (!PI->getDesc().isTerminator()) - break; - } - - // 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 (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; - while (!MI.getOperand(i).isImm()) { - ++i; - assert(i < MI.getNumOperands() && "Unexpected restore code!"); - } - - 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); - } -} - unsigned SystemZRegisterInfo::getRARegister() const { assert(0 && "What is the return address register"); return 0; diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h index 5dae865cb79..e376d1b7c68 100644 --- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h +++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.h @@ -50,9 +50,6 @@ struct SystemZRegisterInfo : public SystemZGenRegisterInfo { void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, RegScavenger *RS) const; - void emitPrologue(MachineFunction &MF) const; - void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; - // Debug information queries. unsigned getRARegister() const; unsigned getFrameRegister(const MachineFunction &MF) const; diff --git a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp index f45827b2b30..161b0d7ee7c 100644 --- a/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp +++ b/llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp @@ -30,7 +30,7 @@ SystemZTargetMachine::SystemZTargetMachine(const Target &T, DataLayout("E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32" "-f64:64:64-f128:128:128-a0:16:16-n32:64"), InstrInfo(*this), TLInfo(*this), TSInfo(*this), - FrameInfo(TargetFrameInfo::StackGrowsDown, 8, -160) { + FrameInfo(Subtarget) { if (getRelocationModel() == Reloc::Default) setRelocationModel(Reloc::Static); diff --git a/llvm/lib/Target/SystemZ/SystemZTargetMachine.h b/llvm/lib/Target/SystemZ/SystemZTargetMachine.h index 6af829bb596..248141a032a 100644 --- a/llvm/lib/Target/SystemZ/SystemZTargetMachine.h +++ b/llvm/lib/Target/SystemZ/SystemZTargetMachine.h @@ -17,6 +17,7 @@ #include "SystemZInstrInfo.h" #include "SystemZISelLowering.h" +#include "SystemZFrameInfo.h" #include "SystemZSelectionDAGInfo.h" #include "SystemZRegisterInfo.h" #include "SystemZSubtarget.h" @@ -34,10 +35,7 @@ class SystemZTargetMachine : public LLVMTargetMachine { SystemZInstrInfo InstrInfo; SystemZTargetLowering TLInfo; SystemZSelectionDAGInfo TSInfo; - - // SystemZ does not have any call stack frame, therefore not having - // any SystemZ specific FrameInfo class. - TargetFrameInfo FrameInfo; + SystemZFrameInfo FrameInfo; public: SystemZTargetMachine(const Target &T, const std::string &TT, const std::string &FS); |