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/StringRef.h"
18 #include "llvm/CodeGen/MachineConstantPool.h"
19 #include "llvm/Support/Casting.h"
30 class MachineBasicBlock;
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)
53 } // end namespace ARMCP
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;
67 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
68 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
69 bool AddCurrentAddress);
71 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
72 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
73 bool AddCurrentAddress);
75 template <typename Derived>
76 int getExistingMachineCPValueImpl(MachineConstantPool *CP,
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))
95 ~ARMConstantPoolValue() override;
97 ARMCP::ARMCPModifier getModifier() const { return Modifier; }
98 StringRef getModifierText() const;
99 bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
101 bool mustAddCurrentAddress() const { return AddCurrentAddress; }
103 unsigned getLabelId() const { return LabelId; }
104 unsigned char getPCAdjustment() const { return PCAdjust; }
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; }
113 int getExistingMachineCPValue(MachineConstantPool *CP,
114 unsigned Alignment) override;
116 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
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);
122 bool equals(const ARMConstantPoolValue *A) const {
123 return this->LabelId == A->LabelId &&
124 this->PCAdjust == A->PCAdjust &&
125 this->Modifier == A->Modifier;
128 void print(raw_ostream &O) const override;
129 void print(raw_ostream *O) const { if (O) print(*O); }
133 inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
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;
144 ARMConstantPoolConstant(const Constant *C,
146 ARMCP::ARMCPKind Kind,
148 ARMCP::ARMCPModifier Modifier,
149 bool AddCurrentAddress);
150 ARMConstantPoolConstant(Type *Ty, const Constant *C,
152 ARMCP::ARMCPKind Kind,
154 ARMCP::ARMCPModifier Modifier,
155 bool AddCurrentAddress);
156 ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init);
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,
170 ARMCP::ARMCPModifier Modifier,
171 bool AddCurrentAddress);
173 const GlobalValue *getGV() const;
174 const BlockAddress *getBlockAddress() const;
176 const GlobalVariable *getPromotedGlobal() const {
177 return dyn_cast_or_null<GlobalVariable>(GVar);
180 const Constant *getPromotedGlobalInit() const {
184 int getExistingMachineCPValue(MachineConstantPool *CP,
185 unsigned Alignment) override;
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;
191 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
193 void print(raw_ostream &O) const override;
195 static bool classof(const ARMConstantPoolValue *APV) {
196 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA() ||
197 APV->isPromotedGlobal();
200 bool equals(const ARMConstantPoolConstant *A) const {
201 return CVal == A->CVal && ARMConstantPoolValue::equals(A);
205 /// ARMConstantPoolSymbol - ARM-specific constantpool values for external
207 class ARMConstantPoolSymbol : public ARMConstantPoolValue {
208 const std::string S; // ExtSymbol being loaded.
210 ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id,
211 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
212 bool AddCurrentAddress);
215 static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID,
216 unsigned char PCAdj);
218 StringRef getSymbol() const { return S; }
220 int getExistingMachineCPValue(MachineConstantPool *CP,
221 unsigned Alignment) override;
223 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
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;
229 void print(raw_ostream &O) const override;
231 static bool classof(const ARMConstantPoolValue *ACPV) {
232 return ACPV->isExtSymbol();
235 bool equals(const ARMConstantPoolSymbol *A) const {
236 return S == A->S && ARMConstantPoolValue::equals(A);
240 /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
242 class ARMConstantPoolMBB : public ARMConstantPoolValue {
243 const MachineBasicBlock *MBB; // Machine basic block.
245 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
246 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
247 bool AddCurrentAddress);
250 static ARMConstantPoolMBB *Create(LLVMContext &C,
251 const MachineBasicBlock *mbb,
252 unsigned ID, unsigned char PCAdj);
254 const MachineBasicBlock *getMBB() const { return MBB; }
256 int getExistingMachineCPValue(MachineConstantPool *CP,
257 unsigned Alignment) override;
259 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
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;
265 void print(raw_ostream &O) const override;
267 static bool classof(const ARMConstantPoolValue *ACPV) {
268 return ACPV->isMachineBasicBlock();
271 bool equals(const ARMConstantPoolMBB *A) const {
272 return MBB == A->MBB && ARMConstantPoolValue::equals(A);
276 } // end namespace llvm
278 #endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H