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