Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Lanai/LanaiFrameLowering.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- LanaiFrameLowering.cpp - Lanai Frame Information ------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file contains the Lanai implementation of TargetFrameLowering class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "LanaiFrameLowering.h"
14
15
#include "LanaiAluCode.h"
16
#include "LanaiInstrInfo.h"
17
#include "LanaiSubtarget.h"
18
#include "llvm/CodeGen/MachineFrameInfo.h"
19
#include "llvm/CodeGen/MachineFunction.h"
20
#include "llvm/CodeGen/MachineInstrBuilder.h"
21
#include "llvm/CodeGen/MachineRegisterInfo.h"
22
#include "llvm/IR/Function.h"
23
24
using namespace llvm;
25
26
// Determines the size of the frame and maximum call frame size.
27
92
void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const {
28
92
  MachineFrameInfo &MFI = MF.getFrameInfo();
29
92
  const LanaiRegisterInfo *LRI = STI.getRegisterInfo();
30
92
31
92
  // Get the number of bytes to allocate from the FrameInfo.
32
92
  unsigned FrameSize = MFI.getStackSize();
33
92
34
92
  // Get the alignment.
35
92
  unsigned StackAlign = LRI->needsStackRealignment(MF) ? 
MFI.getMaxAlignment()0
36
92
                                                       : getStackAlignment();
37
92
38
92
  // Get the maximum call frame size of all the calls.
39
92
  unsigned MaxCallFrameSize = MFI.getMaxCallFrameSize();
40
92
41
92
  // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so
42
92
  // that allocations will be aligned.
43
92
  if (MFI.hasVarSizedObjects())
44
0
    MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign);
45
92
46
92
  // Update maximum call frame size.
47
92
  MFI.setMaxCallFrameSize(MaxCallFrameSize);
48
92
49
92
  // Include call frame size in total.
50
92
  if (!(hasReservedCallFrame(MF) && 
MFI.adjustsStack()0
))
51
92
    FrameSize += MaxCallFrameSize;
52
92
53
92
  // Make sure the frame is aligned.
54
92
  FrameSize = alignTo(FrameSize, StackAlign);
55
92
56
92
  // Update frame info.
57
92
  MFI.setStackSize(FrameSize);
58
92
}
59
60
// Iterates through each basic block in a machine function and replaces
61
// ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the
62
// maximum call frame size as the immediate.
63
0
void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const {
64
0
  const LanaiInstrInfo &LII =
65
0
      *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
66
0
  unsigned MaxCallFrameSize = MF.getFrameInfo().getMaxCallFrameSize();
67
0
68
0
  for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); MBB != E;
69
0
       ++MBB) {
70
0
    MachineBasicBlock::iterator MBBI = MBB->begin();
71
0
    while (MBBI != MBB->end()) {
72
0
      MachineInstr &MI = *MBBI++;
73
0
      if (MI.getOpcode() == Lanai::ADJDYNALLOC) {
74
0
        DebugLoc DL = MI.getDebugLoc();
75
0
        unsigned Dst = MI.getOperand(0).getReg();
76
0
        unsigned Src = MI.getOperand(1).getReg();
77
0
78
0
        BuildMI(*MBB, MI, DL, LII.get(Lanai::ADD_I_LO), Dst)
79
0
            .addReg(Src)
80
0
            .addImm(MaxCallFrameSize);
81
0
        MI.eraseFromParent();
82
0
      }
83
0
    }
84
0
  }
85
0
}
86
87
// Generates the following sequence for function entry:
88
//   st %fp,-4[*%sp]        !push old FP
89
//   add %sp,8,%fp          !generate new FP
90
//   sub %sp,0x4,%sp        !allocate stack space (as needed)
91
void LanaiFrameLowering::emitPrologue(MachineFunction &MF,
92
92
                                      MachineBasicBlock &MBB) const {
93
92
  assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
94
92
95
92
  MachineFrameInfo &MFI = MF.getFrameInfo();
96
92
  const LanaiInstrInfo &LII =
97
92
      *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
98
92
  MachineBasicBlock::iterator MBBI = MBB.begin();
99
92
100
92
  // Debug location must be unknown since the first debug location is used
101
92
  // to determine the end of the prologue.
102
92
  DebugLoc DL;
103
92
104
92
  // Determine the correct frame layout
105
92
  determineFrameLayout(MF);
106
92
107
92
  // FIXME: This appears to be overallocating.  Needs investigation.
108
92
  // Get the number of bytes to allocate from the FrameInfo.
109
92
  unsigned StackSize = MFI.getStackSize();
110
92
111
92
  // Push old FP
112
92
  // st %fp,-4[*%sp]
113
92
  BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI))
114
92
      .addReg(Lanai::FP)
115
92
      .addReg(Lanai::SP)
116
92
      .addImm(-4)
117
92
      .addImm(LPAC::makePreOp(LPAC::ADD))
118
92
      .setMIFlag(MachineInstr::FrameSetup);
119
92
120
92
  // Generate new FP
121
92
  // add %sp,8,%fp
122
92
  BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP)
123
92
      .addReg(Lanai::SP)
124
92
      .addImm(8)
125
92
      .setMIFlag(MachineInstr::FrameSetup);
126
92
127
92
  // Allocate space on the stack if needed
128
92
  // sub %sp,StackSize,%sp
129
92
  if (StackSize != 0) {
130
92
    BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP)
131
92
        .addReg(Lanai::SP)
132
92
        .addImm(StackSize)
133
92
        .setMIFlag(MachineInstr::FrameSetup);
134
92
  }
135
92
136
92
  // Replace ADJDYNANALLOC
137
92
  if (MFI.hasVarSizedObjects())
138
0
    replaceAdjDynAllocPseudo(MF);
139
92
}
140
141
MachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr(
142
    MachineFunction & /*MF*/, MachineBasicBlock &MBB,
143
26
    MachineBasicBlock::iterator I) const {
144
26
  // Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
145
26
  return MBB.erase(I);
146
26
}
147
148
// The function epilogue should not depend on the current stack pointer!
149
// It should use the frame pointer only.  This is mandatory because
150
// of alloca; we also take advantage of it to omit stack adjustments
151
// before returning.
152
//
153
// Note that when we go to restore the preserved register values we must
154
// not try to address their slots by using offsets from the stack pointer.
155
// That's because the stack pointer may have been moved during the function
156
// execution due to a call to alloca().  Rather, we must restore all
157
// preserved registers via offsets from the frame pointer value.
158
//
159
// Note also that when the current frame is being "popped" (by adjusting
160
// the value of the stack pointer) on function exit, we must (for the
161
// sake of alloca) set the new value of the stack pointer based upon
162
// the current value of the frame pointer.  We can't just add what we
163
// believe to be the (static) frame size to the stack pointer because
164
// if we did that, and alloca() had been called during this function,
165
// we would end up returning *without* having fully deallocated all of
166
// the space grabbed by alloca.  If that happened, and a function
167
// containing one or more alloca() calls was called over and over again,
168
// then the stack would grow without limit!
169
//
170
// RET is lowered to
171
//      ld -4[%fp],%pc  # modify %pc (two delay slots)
172
// as the return address is in the stack frame and mov to pc is allowed.
173
// emitEpilogue emits
174
//      mov %fp,%sp     # restore the stack pointer
175
//      ld -8[%fp],%fp  # restore the caller's frame pointer
176
// before RET and the delay slot filler will move RET such that these
177
// instructions execute in the delay slots of the load to PC.
178
void LanaiFrameLowering::emitEpilogue(MachineFunction & /*MF*/,
179
92
                                      MachineBasicBlock &MBB) const {
180
92
  MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
181
92
  const LanaiInstrInfo &LII =
182
92
      *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
183
92
  DebugLoc DL = MBBI->getDebugLoc();
184
92
185
92
  // Restore the stack pointer using the callee's frame pointer value.
186
92
  BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::SP)
187
92
      .addReg(Lanai::FP)
188
92
      .addImm(0);
189
92
190
92
  // Restore the frame pointer from the stack.
191
92
  BuildMI(MBB, MBBI, DL, LII.get(Lanai::LDW_RI), Lanai::FP)
192
92
      .addReg(Lanai::FP)
193
92
      .addImm(-8)
194
92
      .addImm(LPAC::ADD);
195
92
}
196
197
void LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF,
198
                                              BitVector &SavedRegs,
199
92
                                              RegScavenger *RS) const {
200
92
  TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
201
92
202
92
  MachineFrameInfo &MFI = MF.getFrameInfo();
203
92
  const LanaiRegisterInfo *LRI =
204
92
      static_cast<const LanaiRegisterInfo *>(STI.getRegisterInfo());
205
92
  int Offset = -4;
206
92
207
92
  // Reserve 4 bytes for the saved RCA
208
92
  MFI.CreateFixedObject(4, Offset, true);
209
92
  Offset -= 4;
210
92
211
92
  // Reserve 4 bytes for the saved FP
212
92
  MFI.CreateFixedObject(4, Offset, true);
213
92
  Offset -= 4;
214
92
215
92
  if (LRI->hasBasePointer(MF)) {
216
0
    MFI.CreateFixedObject(4, Offset, true);
217
0
    SavedRegs.reset(LRI->getBaseRegister());
218
0
  }
219
92
}