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