1 //===- ARMConstantPoolValue.h - ARM constantpool value ----------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements the ARM specific constantpool value class.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
14 #define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
16 #include "llvm/ADT/SmallPtrSet.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/iterator_range.h"
19 #include "llvm/CodeGen/MachineConstantPool.h"
20 #include "llvm/Support/Casting.h"
31 class MachineBasicBlock
;
48 TLSGD
, /// Thread Local Storage (General Dynamic Mode)
49 GOT_PREL
, /// Global Offset Table, PC Relative
50 GOTTPOFF
, /// Global Offset Table, Thread Pointer Offset
51 TPOFF
, /// Thread Pointer Offset
52 SECREL
, /// Section Relative (Windows TLS)
53 SBREL
, /// Static Base Relative (RWPI)
56 } // end namespace ARMCP
58 /// ARMConstantPoolValue - ARM specific constantpool value. This is used to
59 /// represent PC-relative displacement between the address of the load
60 /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
61 class ARMConstantPoolValue
: public MachineConstantPoolValue
{
62 unsigned LabelId
; // Label id of the load.
63 ARMCP::ARMCPKind Kind
; // Kind of constant.
64 unsigned char PCAdjust
; // Extra adjustment if constantpool is pc-relative.
65 // 8 for ARM, 4 for Thumb.
66 ARMCP::ARMCPModifier Modifier
; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
67 bool AddCurrentAddress
;
70 ARMConstantPoolValue(Type
*Ty
, unsigned id
, ARMCP::ARMCPKind Kind
,
71 unsigned char PCAdj
, ARMCP::ARMCPModifier Modifier
,
72 bool AddCurrentAddress
);
74 ARMConstantPoolValue(LLVMContext
&C
, unsigned id
, ARMCP::ARMCPKind Kind
,
75 unsigned char PCAdj
, ARMCP::ARMCPModifier Modifier
,
76 bool AddCurrentAddress
);
78 template <typename Derived
>
79 int getExistingMachineCPValueImpl(MachineConstantPool
*CP
, Align Alignment
) {
80 const std::vector
<MachineConstantPoolEntry
> &Constants
= CP
->getConstants();
81 for (unsigned i
= 0, e
= Constants
.size(); i
!= e
; ++i
) {
82 if (Constants
[i
].isMachineConstantPoolEntry() &&
83 Constants
[i
].getAlign() >= Alignment
) {
85 static_cast<ARMConstantPoolValue
*>(Constants
[i
].Val
.MachineCPVal
);
86 if (Derived
*APC
= dyn_cast
<Derived
>(CPV
))
87 if (cast
<Derived
>(this)->equals(APC
))
96 ~ARMConstantPoolValue() override
;
98 ARMCP::ARMCPModifier
getModifier() const { return Modifier
; }
99 StringRef
getModifierText() const;
100 bool hasModifier() const { return Modifier
!= ARMCP::no_modifier
; }
102 bool mustAddCurrentAddress() const { return AddCurrentAddress
; }
104 unsigned getLabelId() const { return LabelId
; }
105 unsigned char getPCAdjustment() const { return PCAdjust
; }
107 bool isGlobalValue() const { return Kind
== ARMCP::CPValue
; }
108 bool isExtSymbol() const { return Kind
== ARMCP::CPExtSymbol
; }
109 bool isBlockAddress() const { return Kind
== ARMCP::CPBlockAddress
; }
110 bool isLSDA() const { return Kind
== ARMCP::CPLSDA
; }
111 bool isMachineBasicBlock() const{ return Kind
== ARMCP::CPMachineBasicBlock
; }
112 bool isPromotedGlobal() const{ return Kind
== ARMCP::CPPromotedGlobal
; }
114 int getExistingMachineCPValue(MachineConstantPool
*CP
,
115 Align Alignment
) override
;
117 void addSelectionDAGCSEId(FoldingSetNodeID
&ID
) override
;
119 /// hasSameValue - Return true if this ARM constpool value can share the same
120 /// constantpool entry as another ARM constpool value.
121 virtual bool hasSameValue(ARMConstantPoolValue
*ACPV
);
123 bool equals(const ARMConstantPoolValue
*A
) const {
124 return this->LabelId
== A
->LabelId
&&
125 this->PCAdjust
== A
->PCAdjust
&&
126 this->Modifier
== A
->Modifier
;
129 void print(raw_ostream
&O
) const override
;
130 void print(raw_ostream
*O
) const { if (O
) print(*O
); }
134 inline raw_ostream
&operator<<(raw_ostream
&O
, const ARMConstantPoolValue
&V
) {
139 /// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
140 /// Functions, and BlockAddresses.
141 class ARMConstantPoolConstant
: public ARMConstantPoolValue
{
142 const Constant
*CVal
; // Constant being loaded.
143 SmallPtrSet
<const GlobalVariable
*, 1> GVars
;
145 ARMConstantPoolConstant(const Constant
*C
,
147 ARMCP::ARMCPKind Kind
,
149 ARMCP::ARMCPModifier Modifier
,
150 bool AddCurrentAddress
);
151 ARMConstantPoolConstant(Type
*Ty
, const Constant
*C
,
153 ARMCP::ARMCPKind Kind
,
155 ARMCP::ARMCPModifier Modifier
,
156 bool AddCurrentAddress
);
157 ARMConstantPoolConstant(const GlobalVariable
*GV
, const Constant
*Init
);
160 static ARMConstantPoolConstant
*Create(const Constant
*C
, unsigned ID
);
161 static ARMConstantPoolConstant
*Create(const GlobalValue
*GV
,
162 ARMCP::ARMCPModifier Modifier
);
163 static ARMConstantPoolConstant
*Create(const GlobalVariable
*GV
,
164 const Constant
*Initializer
);
165 static ARMConstantPoolConstant
*Create(const Constant
*C
, unsigned ID
,
166 ARMCP::ARMCPKind Kind
,
167 unsigned char PCAdj
);
168 static ARMConstantPoolConstant
*Create(const Constant
*C
, unsigned ID
,
169 ARMCP::ARMCPKind Kind
,
171 ARMCP::ARMCPModifier Modifier
,
172 bool AddCurrentAddress
);
174 const GlobalValue
*getGV() const;
175 const BlockAddress
*getBlockAddress() const;
177 using promoted_iterator
= SmallPtrSet
<const GlobalVariable
*, 1>::iterator
;
179 iterator_range
<promoted_iterator
> promotedGlobals() {
180 return iterator_range
<promoted_iterator
>(GVars
.begin(), GVars
.end());
183 const Constant
*getPromotedGlobalInit() const {
187 int getExistingMachineCPValue(MachineConstantPool
*CP
,
188 Align Alignment
) override
;
190 /// hasSameValue - Return true if this ARM constpool value can share the same
191 /// constantpool entry as another ARM constpool value.
192 bool hasSameValue(ARMConstantPoolValue
*ACPV
) override
;
194 void addSelectionDAGCSEId(FoldingSetNodeID
&ID
) override
;
196 void print(raw_ostream
&O
) const override
;
198 static bool classof(const ARMConstantPoolValue
*APV
) {
199 return APV
->isGlobalValue() || APV
->isBlockAddress() || APV
->isLSDA() ||
200 APV
->isPromotedGlobal();
203 bool equals(const ARMConstantPoolConstant
*A
) const {
204 return CVal
== A
->CVal
&& ARMConstantPoolValue::equals(A
);
208 /// ARMConstantPoolSymbol - ARM-specific constantpool values for external
210 class ARMConstantPoolSymbol
: public ARMConstantPoolValue
{
211 const std::string S
; // ExtSymbol being loaded.
213 ARMConstantPoolSymbol(LLVMContext
&C
, StringRef s
, unsigned id
,
214 unsigned char PCAdj
, ARMCP::ARMCPModifier Modifier
,
215 bool AddCurrentAddress
);
218 static ARMConstantPoolSymbol
*Create(LLVMContext
&C
, StringRef s
, unsigned ID
,
219 unsigned char PCAdj
);
221 StringRef
getSymbol() const { return S
; }
223 int getExistingMachineCPValue(MachineConstantPool
*CP
,
224 Align Alignment
) override
;
226 void addSelectionDAGCSEId(FoldingSetNodeID
&ID
) override
;
228 /// hasSameValue - Return true if this ARM constpool value can share the same
229 /// constantpool entry as another ARM constpool value.
230 bool hasSameValue(ARMConstantPoolValue
*ACPV
) override
;
232 void print(raw_ostream
&O
) const override
;
234 static bool classof(const ARMConstantPoolValue
*ACPV
) {
235 return ACPV
->isExtSymbol();
238 bool equals(const ARMConstantPoolSymbol
*A
) const {
239 return S
== A
->S
&& ARMConstantPoolValue::equals(A
);
243 /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
245 class ARMConstantPoolMBB
: public ARMConstantPoolValue
{
246 const MachineBasicBlock
*MBB
; // Machine basic block.
248 ARMConstantPoolMBB(LLVMContext
&C
, const MachineBasicBlock
*mbb
, unsigned id
,
249 unsigned char PCAdj
, ARMCP::ARMCPModifier Modifier
,
250 bool AddCurrentAddress
);
253 static ARMConstantPoolMBB
*Create(LLVMContext
&C
,
254 const MachineBasicBlock
*mbb
,
255 unsigned ID
, unsigned char PCAdj
);
257 const MachineBasicBlock
*getMBB() const { return MBB
; }
259 int getExistingMachineCPValue(MachineConstantPool
*CP
,
260 Align Alignment
) override
;
262 void addSelectionDAGCSEId(FoldingSetNodeID
&ID
) override
;
264 /// hasSameValue - Return true if this ARM constpool value can share the same
265 /// constantpool entry as another ARM constpool value.
266 bool hasSameValue(ARMConstantPoolValue
*ACPV
) override
;
268 void print(raw_ostream
&O
) const override
;
270 static bool classof(const ARMConstantPoolValue
*ACPV
) {
271 return ACPV
->isMachineBasicBlock();
274 bool equals(const ARMConstantPoolMBB
*A
) const {
275 return MBB
== A
->MBB
&& ARMConstantPoolValue::equals(A
);
279 } // end namespace llvm
281 #endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H