9d6e8a87dcd56c40d735dfb7068dd2ebba397cf9
[oota-llvm.git] / lib / Target / SystemZ / SystemZFrameInfo.cpp
1 //=====- SystemZFrameInfo.cpp - SystemZ Frame Information ------*- C++ -*-====//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the SystemZ implementation of TargetFrameInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SystemZFrameInfo.h"
15 #include "SystemZInstrBuilder.h"
16 #include "SystemZInstrInfo.h"
17 #include "SystemZMachineFunctionInfo.h"
18 #include "llvm/Function.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/Target/TargetData.h"
25 #include "llvm/Target/TargetOptions.h"
26 #include "llvm/Support/CommandLine.h"
27
28 using namespace llvm;
29
30
31 /// needsFP - Return true if the specified function should have a dedicated
32 /// frame pointer register.  This is true if the function has variable sized
33 /// allocas or if frame pointer elimination is disabled.
34 bool SystemZFrameInfo::hasFP(const MachineFunction &MF) const {
35   const MachineFrameInfo *MFI = MF.getFrameInfo();
36   return DisableFramePointerElim(MF) || MFI->hasVarSizedObjects();
37 }
38
39 /// emitSPUpdate - Emit a series of instructions to increment / decrement the
40 /// stack pointer by a constant value.
41 static
42 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
43                   int64_t NumBytes, const TargetInstrInfo &TII) {
44   unsigned Opc; uint64_t Chunk;
45   bool isSub = NumBytes < 0;
46   uint64_t Offset = isSub ? -NumBytes : NumBytes;
47
48   if (Offset >= (1LL << 15) - 1) {
49     Opc = SystemZ::ADD64ri32;
50     Chunk = (1LL << 31) - 1;
51   } else {
52     Opc = SystemZ::ADD64ri16;
53     Chunk = (1LL << 15) - 1;
54   }
55
56   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
57
58   while (Offset) {
59     uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset;
60     MachineInstr *MI =
61       BuildMI(MBB, MBBI, DL, TII.get(Opc), SystemZ::R15D)
62       .addReg(SystemZ::R15D).addImm(isSub ? -ThisVal : ThisVal);
63     // The PSW implicit def is dead.
64     MI->getOperand(3).setIsDead();
65     Offset -= ThisVal;
66   }
67 }
68
69 void SystemZFrameInfo::emitPrologue(MachineFunction &MF) const {
70   MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
71   const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
72   MachineFrameInfo *MFI = MF.getFrameInfo();
73   const SystemZInstrInfo &TII =
74     *static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo());
75   SystemZMachineFunctionInfo *SystemZMFI =
76     MF.getInfo<SystemZMachineFunctionInfo>();
77   MachineBasicBlock::iterator MBBI = MBB.begin();
78   DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
79
80   // Get the number of bytes to allocate from the FrameInfo.
81   // Note that area for callee-saved stuff is already allocated, thus we need to
82   // 'undo' the stack movement.
83   uint64_t StackSize = MFI->getStackSize();
84   StackSize -= SystemZMFI->getCalleeSavedFrameSize();
85
86   uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
87
88   // Skip the callee-saved push instructions.
89   while (MBBI != MBB.end() &&
90          (MBBI->getOpcode() == SystemZ::MOV64mr ||
91           MBBI->getOpcode() == SystemZ::MOV64mrm))
92     ++MBBI;
93
94   if (MBBI != MBB.end())
95     DL = MBBI->getDebugLoc();
96
97   // adjust stack pointer: R15 -= numbytes
98   if (StackSize || MFI->hasCalls()) {
99     assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) &&
100            "Invalid stack frame calculation!");
101     emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, TII);
102   }
103
104   if (hasFP(MF)) {
105     // Update R11 with the new base value...
106     BuildMI(MBB, MBBI, DL, TII.get(SystemZ::MOV64rr), SystemZ::R11D)
107       .addReg(SystemZ::R15D);
108
109     // Mark the FramePtr as live-in in every block except the entry.
110     for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end();
111          I != E; ++I)
112       I->addLiveIn(SystemZ::R11D);
113
114   }
115 }
116
117 void SystemZFrameInfo::emitEpilogue(MachineFunction &MF,
118                                     MachineBasicBlock &MBB) const {
119   const MachineFrameInfo *MFI = MF.getFrameInfo();
120   const TargetFrameInfo &TFI = *MF.getTarget().getFrameInfo();
121   MachineBasicBlock::iterator MBBI = prior(MBB.end());
122   const SystemZInstrInfo &TII =
123     *static_cast<const SystemZInstrInfo*>(MF.getTarget().getInstrInfo());
124   SystemZMachineFunctionInfo *SystemZMFI =
125     MF.getInfo<SystemZMachineFunctionInfo>();
126   unsigned RetOpcode = MBBI->getOpcode();
127
128   switch (RetOpcode) {
129   case SystemZ::RET: break;  // These are ok
130   default:
131     assert(0 && "Can only insert epilog into returning blocks");
132   }
133
134   // Get the number of bytes to allocate from the FrameInfo
135   // Note that area for callee-saved stuff is already allocated, thus we need to
136   // 'undo' the stack movement.
137   uint64_t StackSize =
138     MFI->getStackSize() - SystemZMFI->getCalleeSavedFrameSize();
139   uint64_t NumBytes = StackSize - TFI.getOffsetOfLocalArea();
140
141   // Skip the final terminator instruction.
142   while (MBBI != MBB.begin()) {
143     MachineBasicBlock::iterator PI = prior(MBBI);
144     --MBBI;
145     if (!PI->getDesc().isTerminator())
146       break;
147   }
148
149   // During callee-saved restores emission stack frame was not yet finialized
150   // (and thus - the stack size was unknown). Tune the offset having full stack
151   // size in hands.
152   if (StackSize || MFI->hasCalls()) {
153     assert((MBBI->getOpcode() == SystemZ::MOV64rmm ||
154             MBBI->getOpcode() == SystemZ::MOV64rm) &&
155            "Expected to see callee-save register restore code");
156     assert(MF.getRegInfo().isPhysRegUsed(SystemZ::R15D) &&
157            "Invalid stack frame calculation!");
158
159     unsigned i = 0;
160     MachineInstr &MI = *MBBI;
161     while (!MI.getOperand(i).isImm()) {
162       ++i;
163       assert(i < MI.getNumOperands() && "Unexpected restore code!");
164     }
165
166     uint64_t Offset = NumBytes + MI.getOperand(i).getImm();
167     // If Offset does not fit into 20-bit signed displacement field we need to
168     // emit some additional code...
169     if (Offset > 524287) {
170       // Fold the displacement into load instruction as much as possible.
171       NumBytes = Offset - 524287;
172       Offset = 524287;
173       emitSPUpdate(MBB, MBBI, NumBytes, TII);
174     }
175
176     MI.getOperand(i).ChangeToImmediate(Offset);
177   }
178 }