aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMMachineFunctionInfo.h
blob: 138f0c2622718526583264e231de68522878340a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
//====- ARMMachineFuctionInfo.h - ARM machine function info -----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares ARM-specific per-machine-function information.
//
//===----------------------------------------------------------------------===//

#ifndef ARMMACHINEFUNCTIONINFO_H
#define ARMMACHINEFUNCTIONINFO_H

#include "ARMSubtarget.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/BitVector.h"

namespace llvm {

/// ARMFunctionInfo - This class is derived from MachineFunctionInfo and
/// contains private ARM-specific information for each MachineFunction.
class ARMFunctionInfo : public MachineFunctionInfo {

  /// isThumb - True if this function is compiled under Thumb mode.
  /// Used to initialized Align, so must precede it.
  bool isThumb;

  /// hasThumb2 - True if the target architecture supports Thumb2. Do not use
  /// to determine if function is compiled under Thumb mode, for that use
  /// 'isThumb'.
  bool hasThumb2;

  /// VarArgsRegSaveSize - Size of the register save area for vararg functions.
  ///
  unsigned VarArgsRegSaveSize;

  /// HasStackFrame - True if this function has a stack frame. Set by
  /// processFunctionBeforeCalleeSavedScan().
  bool HasStackFrame;

  /// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by
  /// emitPrologue.
  bool RestoreSPFromFP;

  /// LRSpilledForFarJump - True if the LR register has been for spilled to
  /// enable far jump.
  bool LRSpilledForFarJump;

  /// FramePtrSpillOffset - If HasStackFrame, this records the frame pointer
  /// spill stack offset.
  unsigned FramePtrSpillOffset;

  /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
  /// register spills areas. For Mac OS X:
  ///
  /// GPR callee-saved (1) : r4, r5, r6, r7, lr
  /// --------------------------------------------
  /// GPR callee-saved (2) : r8, r10, r11
  /// --------------------------------------------
  /// DPR callee-saved : d8 - d15
  unsigned GPRCS1Offset;
  unsigned GPRCS2Offset;
  unsigned DPRCSOffset;

  /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
  /// areas.
  unsigned GPRCS1Size;
  unsigned GPRCS2Size;
  unsigned DPRCSSize;

  /// GPRCS1Frames, GPRCS2Frames, DPRCSFrames - Keeps track of frame indices
  /// which belong to these spill areas.
  BitVector GPRCS1Frames;
  BitVector GPRCS2Frames;
  BitVector DPRCSFrames;

  /// JumpTableUId - Unique id for jumptables.
  ///
  unsigned JumpTableUId;

  unsigned PICLabelUId;

  /// VarArgsFrameIndex - FrameIndex for start of varargs area.
  int VarArgsFrameIndex;

  /// HasITBlocks - True if IT blocks have been inserted.
  bool HasITBlocks;

  /// CPEClones - Track constant pool entries clones created by Constant Island
  /// pass.
  DenseMap<unsigned, unsigned> CPEClones;

public:
  ARMFunctionInfo() :
    isThumb(false),
    hasThumb2(false),
    VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
    LRSpilledForFarJump(false),
    FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
    GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
    GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0),
    JumpTableUId(0), PICLabelUId(0),
    VarArgsFrameIndex(0), HasITBlocks(false) {}

  explicit ARMFunctionInfo(MachineFunction &MF) :
    isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
    hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()),
    VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
    LRSpilledForFarJump(false),
    FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
    GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
    GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32),
    JumpTableUId(0), PICLabelUId(0),
    VarArgsFrameIndex(0), HasITBlocks(false) {}

  bool isThumbFunction() const { return isThumb; }
  bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
  bool isThumb2Function() const { return isThumb && hasThumb2; }

  unsigned getVarArgsRegSaveSize() const { return VarArgsRegSaveSize; }
  void setVarArgsRegSaveSize(unsigned s) { VarArgsRegSaveSize = s; }

  bool hasStackFrame() const { return HasStackFrame; }
  void setHasStackFrame(bool s) { HasStackFrame = s; }

  bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
  void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }

  bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
  void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }

  unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
  void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }

  unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
  unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
  unsigned getDPRCalleeSavedAreaOffset()  const { return DPRCSOffset; }

  void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
  void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
  void setDPRCalleeSavedAreaOffset(unsigned o)  { DPRCSOffset = o; }

  unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
  unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
  unsigned getDPRCalleeSavedAreaSize()  const { return DPRCSSize; }

  void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
  void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
  void setDPRCalleeSavedAreaSize(unsigned s)  { DPRCSSize = s; }

  bool isGPRCalleeSavedArea1Frame(int fi) const {
    if (fi < 0 || fi >= (int)GPRCS1Frames.size())
      return false;
    return GPRCS1Frames[fi];
  }
  bool isGPRCalleeSavedArea2Frame(int fi) const {
    if (fi < 0 || fi >= (int)GPRCS2Frames.size())
      return false;
    return GPRCS2Frames[fi];
  }
  bool isDPRCalleeSavedAreaFrame(int fi) const {
    if (fi < 0 || fi >= (int)DPRCSFrames.size())
      return false;
    return DPRCSFrames[fi];
  }

  void addGPRCalleeSavedArea1Frame(int fi) {
    if (fi >= 0) {
      int Size = GPRCS1Frames.size();
      if (fi >= Size) {
        Size *= 2;
        if (fi >= Size)
          Size = fi+1;
        GPRCS1Frames.resize(Size);
      }
      GPRCS1Frames[fi] = true;
    }
  }
  void addGPRCalleeSavedArea2Frame(int fi) {
    if (fi >= 0) {
      int Size = GPRCS2Frames.size();
      if (fi >= Size) {
        Size *= 2;
        if (fi >= Size)
          Size = fi+1;
        GPRCS2Frames.resize(Size);
      }
      GPRCS2Frames[fi] = true;
    }
  }
  void addDPRCalleeSavedAreaFrame(int fi) {
    if (fi >= 0) {
      int Size = DPRCSFrames.size();
      if (fi >= Size) {
        Size *= 2;
        if (fi >= Size)
          Size = fi+1;
        DPRCSFrames.resize(Size);
      }
      DPRCSFrames[fi] = true;
    }
  }

  unsigned createJumpTableUId() {
    return JumpTableUId++;
  }

  unsigned getNumJumpTables() const {
    return JumpTableUId;
  }

  void initPICLabelUId(unsigned UId) {
    PICLabelUId = UId;
  }

  unsigned getNumPICLabels() const {
    return PICLabelUId;
  }

  unsigned createPICLabelUId() {
    return PICLabelUId++;
  }

  int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
  void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }

  bool hasITBlocks() const { return HasITBlocks; }
  void setHasITBlocks(bool h) { HasITBlocks = h; }

  void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) {
    if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second)
      assert(0 && "Duplicate entries!");
  }

  unsigned getOriginalCPIdx(unsigned CloneIdx) const {
    DenseMap<unsigned, unsigned>::const_iterator I = CPEClones.find(CloneIdx);
    if (I != CPEClones.end())
      return I->second;
    else
      return -1U;
  }
};
} // End llvm namespace

#endif // ARMMACHINEFUNCTIONINFO_H