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
,
81 unsigned AlignMask
= Alignment
- 1;
82 const std::vector
<MachineConstantPoolEntry
> &Constants
= CP
->getConstants();
83 for (unsigned i
= 0, e
= Constants
.size(); i
!= e
; ++i
) {
84 if (Constants
[i
].isMachineConstantPoolEntry() &&
85 (Constants
[i
].getAlignment() & AlignMask
) == 0) {
87 static_cast<ARMConstantPoolValue
*>(Constants
[i
].Val
.MachineCPVal
);
88 if (Derived
*APC
= dyn_cast
<Derived
>(CPV
))
89 if (cast
<Derived
>(this)->equals(APC
))
98 ~ARMConstantPoolValue() override
;
100 ARMCP::ARMCPModifier
getModifier() const { return Modifier
; }
101 StringRef
getModifierText() const;
102 bool hasModifier() const { return Modifier
!= ARMCP::no_modifier
; }
104 bool mustAddCurrentAddress() const { return AddCurrentAddress
; }
106 unsigned getLabelId() const { return LabelId
; }
107 unsigned char getPCAdjustment() const { return PCAdjust
; }
109 bool isGlobalValue() const { return Kind
== ARMCP::CPValue
; }
110 bool isExtSymbol() const { return Kind
== ARMCP::CPExtSymbol
; }
111 bool isBlockAddress() const { return Kind
== ARMCP::CPBlockAddress
; }
112 bool isLSDA() const { return Kind
== ARMCP::CPLSDA
; }
113 bool isMachineBasicBlock() const{ return Kind
== ARMCP::CPMachineBasicBlock
; }
114 bool isPromotedGlobal() const{ return Kind
== ARMCP::CPPromotedGlobal
; }
116 int getExistingMachineCPValue(MachineConstantPool
*CP
,
117 unsigned Alignment
) override
;
119 void addSelectionDAGCSEId(FoldingSetNodeID
&ID
) override
;
121 /// hasSameValue - Return true if this ARM constpool value can share the same
122 /// constantpool entry as another ARM constpool value.
123 virtual bool hasSameValue(ARMConstantPoolValue
*ACPV
);
125 bool equals(const ARMConstantPoolValue
*A
) const {
126 return this->LabelId
== A
->LabelId
&&
127 this->PCAdjust
== A
->PCAdjust
&&
128 this->Modifier
== A
->Modifier
;
131 void print(raw_ostream
&O
) const override
;
132 void print(raw_ostream
*O
) const { if (O
) print(*O
); }
136 inline raw_ostream
&operator<<(raw_ostream
&O
, const ARMConstantPoolValue
&V
) {
141 /// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
142 /// Functions, and BlockAddresses.
143 class ARMConstantPoolConstant
: public ARMConstantPoolValue
{
144 const Constant
*CVal
; // Constant being loaded.
145 SmallPtrSet
<const GlobalVariable
*, 1> GVars
;
147 ARMConstantPoolConstant(const Constant
*C
,
149 ARMCP::ARMCPKind Kind
,
151 ARMCP::ARMCPModifier Modifier
,
152 bool AddCurrentAddress
);
153 ARMConstantPoolConstant(Type
*Ty
, const Constant
*C
,
155 ARMCP::ARMCPKind Kind
,
157 ARMCP::ARMCPModifier Modifier
,
158 bool AddCurrentAddress
);
159 ARMConstantPoolConstant(const GlobalVariable
*GV
, const Constant
*Init
);
162 static ARMConstantPoolConstant
*Create(const Constant
*C
, unsigned ID
);
163 static ARMConstantPoolConstant
*Create(const GlobalValue
*GV
,
164 ARMCP::ARMCPModifier Modifier
);
165 static ARMConstantPoolConstant
*Create(const GlobalVariable
*GV
,
166 const Constant
*Initializer
);
167 static ARMConstantPoolConstant
*Create(const Constant
*C
, unsigned ID
,
168 ARMCP::ARMCPKind Kind
,
169 unsigned char PCAdj
);
170 static ARMConstantPoolConstant
*Create(const Constant
*C
, unsigned ID
,
171 ARMCP::ARMCPKind Kind
,
173 ARMCP::ARMCPModifier Modifier
,
174 bool AddCurrentAddress
);
176 const GlobalValue
*getGV() const;
177 const BlockAddress
*getBlockAddress() const;
179 using promoted_iterator
= SmallPtrSet
<const GlobalVariable
*, 1>::iterator
;
181 iterator_range
<promoted_iterator
> promotedGlobals() {
182 return iterator_range
<promoted_iterator
>(GVars
.begin(), GVars
.end());
185 const Constant
*getPromotedGlobalInit() const {
189 int getExistingMachineCPValue(MachineConstantPool
*CP
,
190 unsigned Alignment
) override
;
192 /// hasSameValue - Return true if this ARM constpool value can share the same
193 /// constantpool entry as another ARM constpool value.
194 bool hasSameValue(ARMConstantPoolValue
*ACPV
) override
;
196 void addSelectionDAGCSEId(FoldingSetNodeID
&ID
) override
;
198 void print(raw_ostream
&O
) const override
;
200 static bool classof(const ARMConstantPoolValue
*APV
) {
201 return APV
->isGlobalValue() || APV
->isBlockAddress() || APV
->isLSDA() ||
202 APV
->isPromotedGlobal();
205 bool equals(const ARMConstantPoolConstant
*A
) const {
206 return CVal
== A
->CVal
&& ARMConstantPoolValue::equals(A
);
210 /// ARMConstantPoolSymbol - ARM-specific constantpool values for external
212 class ARMConstantPoolSymbol
: public ARMConstantPoolValue
{
213 const std::string S
; // ExtSymbol being loaded.
215 ARMConstantPoolSymbol(LLVMContext
&C
, StringRef s
, unsigned id
,
216 unsigned char PCAdj
, ARMCP::ARMCPModifier Modifier
,
217 bool AddCurrentAddress
);
220 static ARMConstantPoolSymbol
*Create(LLVMContext
&C
, StringRef s
, unsigned ID
,
221 unsigned char PCAdj
);
223 StringRef
getSymbol() const { return S
; }
225 int getExistingMachineCPValue(MachineConstantPool
*CP
,
226 unsigned Alignment
) override
;
228 void addSelectionDAGCSEId(FoldingSetNodeID
&ID
) override
;
230 /// hasSameValue - Return true if this ARM constpool value can share the same
231 /// constantpool entry as another ARM constpool value.
232 bool hasSameValue(ARMConstantPoolValue
*ACPV
) override
;
234 void print(raw_ostream
&O
) const override
;
236 static bool classof(const ARMConstantPoolValue
*ACPV
) {
237 return ACPV
->isExtSymbol();
240 bool equals(const ARMConstantPoolSymbol
*A
) const {
241 return S
== A
->S
&& ARMConstantPoolValue::equals(A
);
245 /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
247 class ARMConstantPoolMBB
: public ARMConstantPoolValue
{
248 const MachineBasicBlock
*MBB
; // Machine basic block.
250 ARMConstantPoolMBB(LLVMContext
&C
, const MachineBasicBlock
*mbb
, unsigned id
,
251 unsigned char PCAdj
, ARMCP::ARMCPModifier Modifier
,
252 bool AddCurrentAddress
);
255 static ARMConstantPoolMBB
*Create(LLVMContext
&C
,
256 const MachineBasicBlock
*mbb
,
257 unsigned ID
, unsigned char PCAdj
);
259 const MachineBasicBlock
*getMBB() const { return MBB
; }
261 int getExistingMachineCPValue(MachineConstantPool
*CP
,
262 unsigned Alignment
) override
;
264 void addSelectionDAGCSEId(FoldingSetNodeID
&ID
) override
;
266 /// hasSameValue - Return true if this ARM constpool value can share the same
267 /// constantpool entry as another ARM constpool value.
268 bool hasSameValue(ARMConstantPoolValue
*ACPV
) override
;
270 void print(raw_ostream
&O
) const override
;
272 static bool classof(const ARMConstantPoolValue
*ACPV
) {
273 return ACPV
->isMachineBasicBlock();
276 bool equals(const ARMConstantPoolMBB
*A
) const {
277 return MBB
== A
->MBB
&& ARMConstantPoolValue::equals(A
);
281 } // end namespace llvm
283 #endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H