1 //===- ARMConstantPoolValue.h - ARM constantpool value ----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the ARM specific constantpool value class.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
15 #define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
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"
32 class MachineBasicBlock;
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)
57 } // end namespace ARMCP
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;
71 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
72 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
73 bool AddCurrentAddress);
75 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
76 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
77 bool AddCurrentAddress);
79 template <typename Derived>
80 int getExistingMachineCPValueImpl(MachineConstantPool *CP,
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) {
88 static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);
89 if (Derived *APC = dyn_cast<Derived>(CPV))
90 if (cast<Derived>(this)->equals(APC))
99 ~ARMConstantPoolValue() override;
101 ARMCP::ARMCPModifier getModifier() const { return Modifier; }
102 StringRef getModifierText() const;
103 bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
105 bool mustAddCurrentAddress() const { return AddCurrentAddress; }
107 unsigned getLabelId() const { return LabelId; }
108 unsigned char getPCAdjustment() const { return PCAdjust; }
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; }
117 int getExistingMachineCPValue(MachineConstantPool *CP,
118 unsigned Alignment) override;
120 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
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);
126 bool equals(const ARMConstantPoolValue *A) const {
127 return this->LabelId == A->LabelId &&
128 this->PCAdjust == A->PCAdjust &&
129 this->Modifier == A->Modifier;
132 void print(raw_ostream &O) const override;
133 void print(raw_ostream *O) const { if (O) print(*O); }
137 inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
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;
148 ARMConstantPoolConstant(const Constant *C,
150 ARMCP::ARMCPKind Kind,
152 ARMCP::ARMCPModifier Modifier,
153 bool AddCurrentAddress);
154 ARMConstantPoolConstant(Type *Ty, const Constant *C,
156 ARMCP::ARMCPKind Kind,
158 ARMCP::ARMCPModifier Modifier,
159 bool AddCurrentAddress);
160 ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init);
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,
174 ARMCP::ARMCPModifier Modifier,
175 bool AddCurrentAddress);
177 const GlobalValue *getGV() const;
178 const BlockAddress *getBlockAddress() const;
180 using promoted_iterator = SmallPtrSet<const GlobalVariable *, 1>::iterator;
182 iterator_range<promoted_iterator> promotedGlobals() {
183 return iterator_range<promoted_iterator>(GVars.begin(), GVars.end());
186 const Constant *getPromotedGlobalInit() const {
190 int getExistingMachineCPValue(MachineConstantPool *CP,
191 unsigned Alignment) override;
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;
197 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
199 void print(raw_ostream &O) const override;
201 static bool classof(const ARMConstantPoolValue *APV) {
202 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA() ||
203 APV->isPromotedGlobal();
206 bool equals(const ARMConstantPoolConstant *A) const {
207 return CVal == A->CVal && ARMConstantPoolValue::equals(A);
211 /// ARMConstantPoolSymbol - ARM-specific constantpool values for external
213 class ARMConstantPoolSymbol : public ARMConstantPoolValue {
214 const std::string S; // ExtSymbol being loaded.
216 ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id,
217 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
218 bool AddCurrentAddress);
221 static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID,
222 unsigned char PCAdj);
224 StringRef getSymbol() const { return S; }
226 int getExistingMachineCPValue(MachineConstantPool *CP,
227 unsigned Alignment) override;
229 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
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;
235 void print(raw_ostream &O) const override;
237 static bool classof(const ARMConstantPoolValue *ACPV) {
238 return ACPV->isExtSymbol();
241 bool equals(const ARMConstantPoolSymbol *A) const {
242 return S == A->S && ARMConstantPoolValue::equals(A);
246 /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
248 class ARMConstantPoolMBB : public ARMConstantPoolValue {
249 const MachineBasicBlock *MBB; // Machine basic block.
251 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
252 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
253 bool AddCurrentAddress);
256 static ARMConstantPoolMBB *Create(LLVMContext &C,
257 const MachineBasicBlock *mbb,
258 unsigned ID, unsigned char PCAdj);
260 const MachineBasicBlock *getMBB() const { return MBB; }
262 int getExistingMachineCPValue(MachineConstantPool *CP,
263 unsigned Alignment) override;
265 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
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;
271 void print(raw_ostream &O) const override;
273 static bool classof(const ARMConstantPoolValue *ACPV) {
274 return ACPV->isMachineBasicBlock();
277 bool equals(const ARMConstantPoolMBB *A) const {
278 return MBB == A->MBB && ARMConstantPoolValue::equals(A);
282 } // end namespace llvm
284 #endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H