Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/ARM/ARMConstantPoolValue.h
Line
Count
Source (jump to first uncovered line)
1
//===- ARMConstantPoolValue.h - ARM constantpool value ----------*- C++ -*-===//
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 implements the ARM specific constantpool value class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
14
#define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
15
16
#include "llvm/ADT/SmallPtrSet.h"
17
#include "llvm/ADT/StringRef.h"
18
#include "llvm/ADT/iterator_range.h"
19
#include "llvm/CodeGen/MachineConstantPool.h"
20
#include "llvm/Support/Casting.h"
21
#include <string>
22
#include <vector>
23
24
namespace llvm {
25
26
class BlockAddress;
27
class Constant;
28
class GlobalValue;
29
class GlobalVariable;
30
class LLVMContext;
31
class MachineBasicBlock;
32
class raw_ostream;
33
class Type;
34
35
namespace ARMCP {
36
37
  enum ARMCPKind {
38
    CPValue,
39
    CPExtSymbol,
40
    CPBlockAddress,
41
    CPLSDA,
42
    CPMachineBasicBlock,
43
    CPPromotedGlobal
44
  };
45
46
  enum ARMCPModifier {
47
    no_modifier, /// None
48
    TLSGD,       /// Thread Local Storage (General Dynamic Mode)
49
    GOT_PREL,    /// Global Offset Table, PC Relative
50
    GOTTPOFF,    /// Global Offset Table, Thread Pointer Offset
51
    TPOFF,       /// Thread Pointer Offset
52
    SECREL,      /// Section Relative (Windows TLS)
53
    SBREL,       /// Static Base Relative (RWPI)
54
  };
55
56
} // end namespace ARMCP
57
58
/// ARMConstantPoolValue - ARM specific constantpool value. This is used to
59
/// represent PC-relative displacement between the address of the load
60
/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
61
class ARMConstantPoolValue : public MachineConstantPoolValue {
62
  unsigned LabelId;        // Label id of the load.
63
  ARMCP::ARMCPKind Kind;   // Kind of constant.
64
  unsigned char PCAdjust;  // Extra adjustment if constantpool is pc-relative.
65
                           // 8 for ARM, 4 for Thumb.
66
  ARMCP::ARMCPModifier Modifier;   // GV modifier i.e. (&GV(modifier)-(LPIC+8))
67
  bool AddCurrentAddress;
68
69
protected:
70
  ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
71
                       unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
72
                       bool AddCurrentAddress);
73
74
  ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
75
                       unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
76
                       bool AddCurrentAddress);
77
78
  template <typename Derived>
79
  int getExistingMachineCPValueImpl(MachineConstantPool *CP,
80
1.54k
                                    unsigned Alignment) {
81
1.54k
    unsigned AlignMask = Alignment - 1;
82
1.54k
    const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
83
3.40k
    for (unsigned i = 0, e = Constants.size(); i != e; 
++i1.86k
) {
84
1.99k
      if (Constants[i].isMachineConstantPoolEntry() &&
85
1.99k
          
(Constants[i].getAlignment() & AlignMask) == 01.79k
) {
86
1.79k
        auto *CPV =
87
1.79k
          static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);
88
1.79k
        if (Derived *APC = dyn_cast<Derived>(CPV))
89
1.73k
          if (cast<Derived>(this)->equals(APC))
90
132
            return i;
91
1.79k
      }
92
1.99k
    }
93
1.54k
94
1.54k
    
return -11.41k
;
95
1.54k
  }
int llvm::ARMConstantPoolValue::getExistingMachineCPValueImpl<llvm::ARMConstantPoolConstant>(llvm::MachineConstantPool*, unsigned int)
Line
Count
Source
80
1.47k
                                    unsigned Alignment) {
81
1.47k
    unsigned AlignMask = Alignment - 1;
82
1.47k
    const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
83
3.21k
    for (unsigned i = 0, e = Constants.size(); i != e; 
++i1.73k
) {
84
1.86k
      if (Constants[i].isMachineConstantPoolEntry() &&
85
1.86k
          
(Constants[i].getAlignment() & AlignMask) == 01.75k
) {
86
1.75k
        auto *CPV =
87
1.75k
          static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);
88
1.75k
        if (Derived *APC = dyn_cast<Derived>(CPV))
89
1.73k
          if (cast<Derived>(this)->equals(APC))
90
132
            return i;
91
1.75k
      }
92
1.86k
    }
93
1.47k
94
1.47k
    
return -11.34k
;
95
1.47k
  }
int llvm::ARMConstantPoolValue::getExistingMachineCPValueImpl<llvm::ARMConstantPoolSymbol>(llvm::MachineConstantPool*, unsigned int)
Line
Count
Source
80
35
                                    unsigned Alignment) {
81
35
    unsigned AlignMask = Alignment - 1;
82
35
    const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
83
57
    for (unsigned i = 0, e = Constants.size(); i != e; 
++i22
) {
84
22
      if (Constants[i].isMachineConstantPoolEntry() &&
85
22
          
(Constants[i].getAlignment() & AlignMask) == 02
) {
86
2
        auto *CPV =
87
2
          static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);
88
2
        if (Derived *APC = dyn_cast<Derived>(CPV))
89
0
          if (cast<Derived>(this)->equals(APC))
90
0
            return i;
91
2
      }
92
22
    }
93
35
94
35
    return -1;
95
35
  }
int llvm::ARMConstantPoolValue::getExistingMachineCPValueImpl<llvm::ARMConstantPoolMBB>(llvm::MachineConstantPool*, unsigned int)
Line
Count
Source
80
32
                                    unsigned Alignment) {
81
32
    unsigned AlignMask = Alignment - 1;
82
32
    const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
83
136
    for (unsigned i = 0, e = Constants.size(); i != e; 
++i104
) {
84
104
      if (Constants[i].isMachineConstantPoolEntry() &&
85
104
          
(Constants[i].getAlignment() & AlignMask) == 032
) {
86
32
        auto *CPV =
87
32
          static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);
88
32
        if (Derived *APC = dyn_cast<Derived>(CPV))
89
0
          if (cast<Derived>(this)->equals(APC))
90
0
            return i;
91
32
      }
92
104
    }
93
32
94
32
    return -1;
95
32
  }
96
97
public:
98
  ~ARMConstantPoolValue() override;
99
100
1.31k
  ARMCP::ARMCPModifier getModifier() const { return Modifier; }
101
  StringRef getModifierText() const;
102
0
  bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
103
104
1.06k
  bool mustAddCurrentAddress() const { return AddCurrentAddress; }
105
106
1.06k
  unsigned getLabelId() const { return LabelId; }
107
2.38k
  unsigned char getPCAdjustment() const { return PCAdjust; }
108
109
3.02k
  bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
110
2
  bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
111
1.33k
  bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
112
1.35k
  bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
113
99
  bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
114
1.42k
  bool isPromotedGlobal() const{ return Kind == ARMCP::CPPromotedGlobal; }
115
116
  int getExistingMachineCPValue(MachineConstantPool *CP,
117
                                unsigned Alignment) override;
118
119
  void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
120
121
  /// hasSameValue - Return true if this ARM constpool value can share the same
122
  /// constantpool entry as another ARM constpool value.
123
  virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
124
125
528
  bool equals(const ARMConstantPoolValue *A) const {
126
528
    return this->LabelId == A->LabelId &&
127
528
      
this->PCAdjust == A->PCAdjust132
&&
128
528
      
this->Modifier == A->Modifier132
;
129
528
  }
130
131
  void print(raw_ostream &O) const override;
132
0
  void print(raw_ostream *O) const { if (O) print(*O); }
133
  void dump() const;
134
};
135
136
0
inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
137
0
  V.print(O);
138
0
  return O;
139
0
}
140
141
/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
142
/// Functions, and BlockAddresses.
143
class ARMConstantPoolConstant : public ARMConstantPoolValue {
144
  const Constant *CVal;         // Constant being loaded.
145
  SmallPtrSet<const GlobalVariable*, 1> GVars;
146
147
  ARMConstantPoolConstant(const Constant *C,
148
                          unsigned ID,
149
                          ARMCP::ARMCPKind Kind,
150
                          unsigned char PCAdj,
151
                          ARMCP::ARMCPModifier Modifier,
152
                          bool AddCurrentAddress);
153
  ARMConstantPoolConstant(Type *Ty, const Constant *C,
154
                          unsigned ID,
155
                          ARMCP::ARMCPKind Kind,
156
                          unsigned char PCAdj,
157
                          ARMCP::ARMCPModifier Modifier,
158
                          bool AddCurrentAddress);
159
  ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init);
160
161
public:
162
  static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
163
  static ARMConstantPoolConstant *Create(const GlobalValue *GV,
164
                                         ARMCP::ARMCPModifier Modifier);
165
  static ARMConstantPoolConstant *Create(const GlobalVariable *GV,
166
                                         const Constant *Initializer);
167
  static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
168
                                         ARMCP::ARMCPKind Kind,
169
                                         unsigned char PCAdj);
170
  static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
171
                                         ARMCP::ARMCPKind Kind,
172
                                         unsigned char PCAdj,
173
                                         ARMCP::ARMCPModifier Modifier,
174
                                         bool AddCurrentAddress);
175
176
  const GlobalValue *getGV() const;
177
  const BlockAddress *getBlockAddress() const;
178
179
  using promoted_iterator = SmallPtrSet<const GlobalVariable *, 1>::iterator;
180
181
85
  iterator_range<promoted_iterator> promotedGlobals() {
182
85
    return iterator_range<promoted_iterator>(GVars.begin(), GVars.end());
183
85
  }
184
185
85
  const Constant *getPromotedGlobalInit() const {
186
85
    return CVal;
187
85
  }
188
189
  int getExistingMachineCPValue(MachineConstantPool *CP,
190
                                unsigned Alignment) override;
191
192
  /// hasSameValue - Return true if this ARM constpool value can share the same
193
  /// constantpool entry as another ARM constpool value.
194
  bool hasSameValue(ARMConstantPoolValue *ACPV) override;
195
196
  void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
197
198
  void print(raw_ostream &O) const override;
199
200
1.75k
  static bool classof(const ARMConstantPoolValue *APV) {
201
1.75k
    return APV->isGlobalValue() || 
APV->isBlockAddress()44
||
APV->isLSDA()37
||
202
1.75k
           
APV->isPromotedGlobal()24
;
203
1.75k
  }
204
205
1.73k
  bool equals(const ARMConstantPoolConstant *A) const {
206
1.73k
    return CVal == A->CVal && 
ARMConstantPoolValue::equals(A)528
;
207
1.73k
  }
208
};
209
210
/// ARMConstantPoolSymbol - ARM-specific constantpool values for external
211
/// symbols.
212
class ARMConstantPoolSymbol : public ARMConstantPoolValue {
213
  const std::string S;          // ExtSymbol being loaded.
214
215
  ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id,
216
                        unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
217
                        bool AddCurrentAddress);
218
219
public:
220
  static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID,
221
                                       unsigned char PCAdj);
222
223
35
  StringRef getSymbol() const { return S; }
224
225
  int getExistingMachineCPValue(MachineConstantPool *CP,
226
                                unsigned Alignment) override;
227
228
  void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
229
230
  /// hasSameValue - Return true if this ARM constpool value can share the same
231
  /// constantpool entry as another ARM constpool value.
232
  bool hasSameValue(ARMConstantPoolValue *ACPV) override;
233
234
  void print(raw_ostream &O) const override;
235
236
2
  static bool classof(const ARMConstantPoolValue *ACPV) {
237
2
    return ACPV->isExtSymbol();
238
2
  }
239
240
0
  bool equals(const ARMConstantPoolSymbol *A) const {
241
0
    return S == A->S && ARMConstantPoolValue::equals(A);
242
0
  }
243
};
244
245
/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
246
/// block.
247
class ARMConstantPoolMBB : public ARMConstantPoolValue {
248
  const MachineBasicBlock *MBB; // Machine basic block.
249
250
  ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
251
                     unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
252
                     bool AddCurrentAddress);
253
254
public:
255
  static ARMConstantPoolMBB *Create(LLVMContext &C,
256
                                    const MachineBasicBlock *mbb,
257
                                    unsigned ID, unsigned char PCAdj);
258
259
32
  const MachineBasicBlock *getMBB() const { return MBB; }
260
261
  int getExistingMachineCPValue(MachineConstantPool *CP,
262
                                unsigned Alignment) override;
263
264
  void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
265
266
  /// hasSameValue - Return true if this ARM constpool value can share the same
267
  /// constantpool entry as another ARM constpool value.
268
  bool hasSameValue(ARMConstantPoolValue *ACPV) override;
269
270
  void print(raw_ostream &O) const override;
271
272
32
  static bool classof(const ARMConstantPoolValue *ACPV) {
273
32
    return ACPV->isMachineBasicBlock();
274
32
  }
275
276
0
  bool equals(const ARMConstantPoolMBB *A) const {
277
0
    return MBB == A->MBB && ARMConstantPoolValue::equals(A);
278
0
  }
279
};
280
281
} // end namespace llvm
282
283
#endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H