]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARM/ARMConstantPoolValue.h
9018 Replace kmem_cache_reap_now() with kmem_cache_reap_soon()
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / ARM / ARMConstantPoolValue.h
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 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   int getExistingMachineCPValueImpl(MachineConstantPool *CP,
81                                     unsigned Alignment) {
82     unsigned AlignMask = Alignment - 1;
83     const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
84     for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
85       if (Constants[i].isMachineConstantPoolEntry() &&
86           (Constants[i].getAlignment() & AlignMask) == 0) {
87         auto *CPV =
88           static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);
89         if (Derived *APC = dyn_cast<Derived>(CPV))
90           if (cast<Derived>(this)->equals(APC))
91             return i;
92       }
93     }
94
95     return -1;
96   }
97
98 public:
99   ~ARMConstantPoolValue() override;
100
101   ARMCP::ARMCPModifier getModifier() const { return Modifier; }
102   StringRef getModifierText() const;
103   bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
104
105   bool mustAddCurrentAddress() const { return AddCurrentAddress; }
106
107   unsigned getLabelId() const { return LabelId; }
108   unsigned char getPCAdjustment() const { return PCAdjust; }
109
110   bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
111   bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
112   bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
113   bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
114   bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
115   bool isPromotedGlobal() const{ return Kind == ARMCP::CPPromotedGlobal; }
116   
117   int getExistingMachineCPValue(MachineConstantPool *CP,
118                                 unsigned Alignment) override;
119
120   void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
121
122   /// hasSameValue - Return true if this ARM constpool value can share the same
123   /// constantpool entry as another ARM constpool value.
124   virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
125
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
132   void print(raw_ostream &O) const override;
133   void print(raw_ostream *O) const { if (O) print(*O); }
134   void dump() const;
135 };
136
137 inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
138   V.print(O);
139   return O;
140 }
141
142 /// 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
162 public:
163   static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
164   static ARMConstantPoolConstant *Create(const GlobalValue *GV,
165                                          ARMCP::ARMCPModifier Modifier);
166   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   const BlockAddress *getBlockAddress() const;
179
180   using promoted_iterator = SmallPtrSet<const GlobalVariable *, 1>::iterator;
181
182   iterator_range<promoted_iterator> promotedGlobals() {
183     return iterator_range<promoted_iterator>(GVars.begin(), GVars.end());
184   }
185
186   const Constant *getPromotedGlobalInit() const {
187     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                      bool AddCurrentAddress);
254
255 public:
256   static ARMConstantPoolMBB *Create(LLVMContext &C,
257                                     const MachineBasicBlock *mbb,
258                                     unsigned ID, unsigned char PCAdj);
259
260   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