Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- TargetFrameLoweringImpl.cpp - Implement target frame interface ------==//
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
// Implements the layout of a stack frame on the target machine.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/ADT/BitVector.h"
14
#include "llvm/CodeGen/MachineFrameInfo.h"
15
#include "llvm/CodeGen/MachineFunction.h"
16
#include "llvm/CodeGen/MachineRegisterInfo.h"
17
#include "llvm/CodeGen/TargetFrameLowering.h"
18
#include "llvm/CodeGen/TargetRegisterInfo.h"
19
#include "llvm/CodeGen/TargetSubtargetInfo.h"
20
#include "llvm/IR/Attributes.h"
21
#include "llvm/IR/CallingConv.h"
22
#include "llvm/IR/Function.h"
23
#include "llvm/MC/MCRegisterInfo.h"
24
#include "llvm/Support/Compiler.h"
25
#include "llvm/Target/TargetMachine.h"
26
#include "llvm/Target/TargetOptions.h"
27
28
using namespace llvm;
29
30
40.4k
TargetFrameLowering::~TargetFrameLowering() = default;
31
32
364
bool TargetFrameLowering::enableCalleeSaveSkip(const MachineFunction &MF) const {
33
364
  assert(MF.getFunction().hasFnAttribute(Attribute::NoReturn) &&
34
364
         MF.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
35
364
         !MF.getFunction().hasFnAttribute(Attribute::UWTable));
36
364
  return false;
37
364
}
38
39
/// Returns the displacement from the frame register to the stack
40
/// frame of the specified index, along with the frame register used
41
/// (in output arg FrameReg). This is the default implementation which
42
/// is overridden for some targets.
43
int TargetFrameLowering::getFrameIndexReference(const MachineFunction &MF,
44
4.80k
                                             int FI, unsigned &FrameReg) const {
45
4.80k
  const MachineFrameInfo &MFI = MF.getFrameInfo();
46
4.80k
  const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
47
4.80k
48
4.80k
  // By default, assume all frame indices are referenced via whatever
49
4.80k
  // getFrameRegister() says. The target can override this if it's doing
50
4.80k
  // something different.
51
4.80k
  FrameReg = RI->getFrameRegister(MF);
52
4.80k
53
4.80k
  return MFI.getObjectOffset(FI) + MFI.getStackSize() -
54
4.80k
         getOffsetOfLocalArea() + MFI.getOffsetAdjustment();
55
4.80k
}
56
57
bool TargetFrameLowering::needsFrameIndexResolution(
58
359k
    const MachineFunction &MF) const {
59
359k
  return MF.getFrameInfo().hasStackObjects();
60
359k
}
61
62
void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF,
63
                                               BitVector &SavedRegs,
64
572k
                                               RegScavenger *RS) const {
65
572k
  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
66
572k
67
572k
  // Resize before the early returns. Some backends expect that
68
572k
  // SavedRegs.size() == TRI.getNumRegs() after this call even if there are no
69
572k
  // saved registers.
70
572k
  SavedRegs.resize(TRI.getNumRegs());
71
572k
72
572k
  // When interprocedural register allocation is enabled caller saved registers
73
572k
  // are preferred over callee saved registers.
74
572k
  if (MF.getTarget().Options.EnableIPRA && 
isSafeForNoCSROpt(MF.getFunction())50.3k
)
75
2
    return;
76
572k
77
572k
  // Get the callee saved register list...
78
572k
  const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
79
572k
80
572k
  // Early exit if there are no callee saved registers.
81
572k
  if (
!CSRegs572k
|| CSRegs[0] == 0)
82
49.4k
    return;
83
523k
84
523k
  // In Naked functions we aren't going to save any registers.
85
523k
  if (MF.getFunction().hasFnAttribute(Attribute::Naked))
86
83
    return;
87
523k
88
523k
  // Noreturn+nounwind functions never restore CSR, so no saves are needed.
89
523k
  // Purely noreturn functions may still return through throws, so those must
90
523k
  // save CSR for caller exception handlers.
91
523k
  //
92
523k
  // If the function uses longjmp to break out of its current path of
93
523k
  // execution we do not need the CSR spills either: setjmp stores all CSRs
94
523k
  // it was called with into the jmp_buf, which longjmp then restores.
95
523k
  if (MF.getFunction().hasFnAttribute(Attribute::NoReturn) &&
96
523k
        
MF.getFunction().hasFnAttribute(Attribute::NoUnwind)2.59k
&&
97
523k
        
!MF.getFunction().hasFnAttribute(Attribute::UWTable)2.39k
&&
98
523k
        
enableCalleeSaveSkip(MF)414
)
99
40
    return;
100
523k
101
523k
  // Functions which call __builtin_unwind_init get all their registers saved.
102
523k
  bool CallsUnwindInit = MF.callsUnwindInit();
103
523k
  const MachineRegisterInfo &MRI = MF.getRegInfo();
104
10.0M
  for (unsigned i = 0; CSRegs[i]; 
++i9.52M
) {
105
9.52M
    unsigned Reg = CSRegs[i];
106
9.52M
    if (CallsUnwindInit || 
MRI.isPhysRegModified(Reg)9.52M
)
107
1.24M
      SavedRegs.set(Reg);
108
9.52M
  }
109
523k
}
110
111
unsigned TargetFrameLowering::getStackAlignmentSkew(
112
497k
    const MachineFunction &MF) const {
113
497k
  // When HHVM function is called, the stack is skewed as the return address
114
497k
  // is removed from the stack before we enter the function.
115
497k
  if (LLVM_UNLIKELY(MF.getFunction().getCallingConv() == CallingConv::HHVM))
116
497k
    
return MF.getTarget().getAllocaPointerSize()11
;
117
497k
118
497k
  return 0;
119
497k
}
120
121
0
int TargetFrameLowering::getInitialCFAOffset(const MachineFunction &MF) const {
122
0
  llvm_unreachable("getInitialCFAOffset() not implemented!");
123
0
}
124
125
unsigned TargetFrameLowering::getInitialCFARegister(const MachineFunction &MF)
126
0
    const {
127
0
  llvm_unreachable("getInitialCFARegister() not implemented!");
128
0
}