blob: 660b7fc88d82ec450f394ef65a9359cdfcf52dcc [file] [log] [blame]
Eugene Zelenko076468c2017-09-20 21:35:51 +00001//===- ARMConstantPoolValue.h - ARM constantpool value ----------*- C++ -*-===//
Evan Cheng10043e22007-01-19 07:51:42 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Evan Cheng10043e22007-01-19 07:51:42 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the ARM specific constantpool value class.
10//
11//===----------------------------------------------------------------------===//
12
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000013#ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
14#define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
Evan Cheng10043e22007-01-19 07:51:42 +000015
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +000016#include "llvm/ADT/SmallPtrSet.h"
Eugene Zelenko076468c2017-09-20 21:35:51 +000017#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/iterator_range.h"
Evan Cheng10043e22007-01-19 07:51:42 +000019#include "llvm/CodeGen/MachineConstantPool.h"
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000020#include "llvm/Support/Casting.h"
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000021#include <string>
22#include <vector>
Evan Cheng10043e22007-01-19 07:51:42 +000023
24namespace llvm {
25
Bob Wilson433ab092009-11-02 16:59:06 +000026class BlockAddress;
Bill Wendlinga1127b22011-09-29 23:48:44 +000027class Constant;
Dan Gohman0597e5b2008-07-11 20:38:31 +000028class GlobalValue;
James Molloy9abb2fa2016-09-26 07:26:24 +000029class GlobalVariable;
Owen Anderson55f1c092009-08-13 21:58:54 +000030class LLVMContext;
Bill Wendlinga1127b22011-09-29 23:48:44 +000031class MachineBasicBlock;
Eugene Zelenko076468c2017-09-20 21:35:51 +000032class raw_ostream;
33class Type;
Dan Gohman0597e5b2008-07-11 20:38:31 +000034
Jim Grosbach20eac922009-09-01 01:57:56 +000035namespace ARMCP {
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000036
Jim Grosbach20eac922009-09-01 01:57:56 +000037 enum ARMCPKind {
38 CPValue,
Bob Wilson433ab092009-11-02 16:59:06 +000039 CPExtSymbol,
40 CPBlockAddress,
Bill Wendlinga1127b22011-09-29 23:48:44 +000041 CPLSDA,
James Molloy9abb2fa2016-09-26 07:26:24 +000042 CPMachineBasicBlock,
43 CPPromotedGlobal
Jim Grosbach20eac922009-09-01 01:57:56 +000044 };
Jim Grosbacha942ad42010-11-09 21:36:17 +000045
46 enum ARMCPModifier {
Saleem Abdulrasoolce4eee42016-06-07 03:15:01 +000047 no_modifier, /// None
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
Saleem Abdulrasool532dcbc2016-06-07 03:15:07 +000052 SECREL, /// Section Relative (Windows TLS)
Oliver Stannard8331aae2016-08-08 15:28:31 +000053 SBREL, /// Static Base Relative (RWPI)
Jim Grosbacha942ad42010-11-09 21:36:17 +000054 };
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000055
56} // end namespace ARMCP
Jim Grosbach20eac922009-09-01 01:57:56 +000057
Evan Cheng10043e22007-01-19 07:51:42 +000058/// ARMConstantPoolValue - ARM specific constantpool value. This is used to
Bob Wilson4c00a522009-11-02 17:10:37 +000059/// represent PC-relative displacement between the address of the load
Bob Wilson433ab092009-11-02 16:59:06 +000060/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
Evan Cheng10043e22007-01-19 07:51:42 +000061class ARMConstantPoolValue : public MachineConstantPoolValue {
Evan Cheng10043e22007-01-19 07:51:42 +000062 unsigned LabelId; // Label id of the load.
Bob Wilson433ab092009-11-02 16:59:06 +000063 ARMCP::ARMCPKind Kind; // Kind of constant.
Bob Wilson4c00a522009-11-02 17:10:37 +000064 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative.
Evan Cheng10043e22007-01-19 07:51:42 +000065 // 8 for ARM, 4 for Thumb.
Jim Grosbacha942ad42010-11-09 21:36:17 +000066 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000067 bool AddCurrentAddress;
Evan Cheng10043e22007-01-19 07:51:42 +000068
Bill Wendling396c2112011-10-01 06:40:33 +000069protected:
70 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
71 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
72 bool AddCurrentAddress);
73
Bill Wendlingd7fa0162011-10-01 08:36:59 +000074 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
75 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
76 bool AddCurrentAddress);
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000077
78 template <typename Derived>
79 int getExistingMachineCPValueImpl(MachineConstantPool *CP,
80 unsigned Alignment) {
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) {
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +000086 auto *CPV =
87 static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000088 if (Derived *APC = dyn_cast<Derived>(CPV))
89 if (cast<Derived>(this)->equals(APC))
90 return i;
91 }
92 }
93
94 return -1;
95 }
96
Evan Cheng10043e22007-01-19 07:51:42 +000097public:
Alexander Kornienkof817c1c2015-04-11 02:11:45 +000098 ~ARMConstantPoolValue() override;
Lauro Ramos Venancioee2d1642007-04-22 00:04:12 +000099
Jim Grosbacha942ad42010-11-09 21:36:17 +0000100 ARMCP::ARMCPModifier getModifier() const { return Modifier; }
Mehdi Amini5b007702016-10-05 01:41:06 +0000101 StringRef getModifierText() const;
Jim Grosbacha942ad42010-11-09 21:36:17 +0000102 bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000103
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +0000104 bool mustAddCurrentAddress() const { return AddCurrentAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000105
Evan Cheng10043e22007-01-19 07:51:42 +0000106 unsigned getLabelId() const { return LabelId; }
Evan Cheng10043e22007-01-19 07:51:42 +0000107 unsigned char getPCAdjustment() const { return PCAdjust; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000108
Bob Wilson433ab092009-11-02 16:59:06 +0000109 bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
110 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
Bill Wendling396c2112011-10-01 06:40:33 +0000111 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000112 bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000113 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
James Molloy9abb2fa2016-09-26 07:26:24 +0000114 bool isPromotedGlobal() const{ return Kind == ARMCP::CPPromotedGlobal; }
Fangrui Songf78650a2018-07-30 19:41:25 +0000115
Craig Topper6bc27bf2014-03-10 02:09:33 +0000116 int getExistingMachineCPValue(MachineConstantPool *CP,
117 unsigned Alignment) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000118
Craig Topper6bc27bf2014-03-10 02:09:33 +0000119 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000120
Bill Wendling396c2112011-10-01 06:40:33 +0000121 /// 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);
Evan Cheng7ff83192009-11-07 03:52:02 +0000124
Bill Wendlingf977ff52011-10-01 12:44:28 +0000125 bool equals(const ARMConstantPoolValue *A) const {
126 return this->LabelId == A->LabelId &&
127 this->PCAdjust == A->PCAdjust &&
128 this->Modifier == A->Modifier;
129 }
130
Craig Topper6bc27bf2014-03-10 02:09:33 +0000131 void print(raw_ostream &O) const override;
Evan Chengde9dbc52008-10-29 23:55:17 +0000132 void print(raw_ostream *O) const { if (O) print(*O); }
Evan Chengde9dbc52008-10-29 23:55:17 +0000133 void dump() const;
Evan Cheng10043e22007-01-19 07:51:42 +0000134};
Evan Chengde9dbc52008-10-29 23:55:17 +0000135
Evan Chengde9dbc52008-10-29 23:55:17 +0000136inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
137 V.print(O);
138 return O;
139}
140
Bill Wendling396c2112011-10-01 06:40:33 +0000141/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
142/// Functions, and BlockAddresses.
143class ARMConstantPoolConstant : public ARMConstantPoolValue {
144 const Constant *CVal; // Constant being loaded.
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +0000145 SmallPtrSet<const GlobalVariable*, 1> GVars;
Bill Wendling396c2112011-10-01 06:40:33 +0000146
147 ARMConstantPoolConstant(const Constant *C,
148 unsigned ID,
149 ARMCP::ARMCPKind Kind,
150 unsigned char PCAdj,
151 ARMCP::ARMCPModifier Modifier,
152 bool AddCurrentAddress);
Bill Wendlingf117a352011-10-01 07:52:37 +0000153 ARMConstantPoolConstant(Type *Ty, const Constant *C,
154 unsigned ID,
155 ARMCP::ARMCPKind Kind,
156 unsigned char PCAdj,
157 ARMCP::ARMCPModifier Modifier,
158 bool AddCurrentAddress);
James Molloy9abb2fa2016-09-26 07:26:24 +0000159 ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init);
Bill Wendlingf117a352011-10-01 07:52:37 +0000160
Bill Wendling396c2112011-10-01 06:40:33 +0000161public:
162 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
Bill Wendlingf117a352011-10-01 07:52:37 +0000163 static ARMConstantPoolConstant *Create(const GlobalValue *GV,
164 ARMCP::ARMCPModifier Modifier);
James Molloy9abb2fa2016-09-26 07:26:24 +0000165 static ARMConstantPoolConstant *Create(const GlobalVariable *GV,
166 const Constant *Initializer);
Bill Wendling67225562011-10-01 06:44:24 +0000167 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
168 ARMCP::ARMCPKind Kind,
169 unsigned char PCAdj);
Bill Wendlingf117a352011-10-01 07:52:37 +0000170 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
171 ARMCP::ARMCPKind Kind,
172 unsigned char PCAdj,
173 ARMCP::ARMCPModifier Modifier,
174 bool AddCurrentAddress);
Bill Wendling396c2112011-10-01 06:40:33 +0000175
176 const GlobalValue *getGV() const;
Bill Wendlingf117a352011-10-01 07:52:37 +0000177 const BlockAddress *getBlockAddress() const;
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000178
Eugene Zelenko076468c2017-09-20 21:35:51 +0000179 using promoted_iterator = SmallPtrSet<const GlobalVariable *, 1>::iterator;
180
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +0000181 iterator_range<promoted_iterator> promotedGlobals() {
182 return iterator_range<promoted_iterator>(GVars.begin(), GVars.end());
James Molloy9abb2fa2016-09-26 07:26:24 +0000183 }
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000184
James Molloy9abb2fa2016-09-26 07:26:24 +0000185 const Constant *getPromotedGlobalInit() const {
186 return CVal;
187 }
Bill Wendlingf117a352011-10-01 07:52:37 +0000188
Craig Topper6bc27bf2014-03-10 02:09:33 +0000189 int getExistingMachineCPValue(MachineConstantPool *CP,
190 unsigned Alignment) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000191
192 /// hasSameValue - Return true if this ARM constpool value can share the same
193 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000194 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000195
Craig Topper6bc27bf2014-03-10 02:09:33 +0000196 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000197
Craig Topper6bc27bf2014-03-10 02:09:33 +0000198 void print(raw_ostream &O) const override;
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000199
Bill Wendling396c2112011-10-01 06:40:33 +0000200 static bool classof(const ARMConstantPoolValue *APV) {
James Molloy9abb2fa2016-09-26 07:26:24 +0000201 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA() ||
202 APV->isPromotedGlobal();
Bill Wendling396c2112011-10-01 06:40:33 +0000203 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000204
205 bool equals(const ARMConstantPoolConstant *A) const {
206 return CVal == A->CVal && ARMConstantPoolValue::equals(A);
207 }
Bill Wendling396c2112011-10-01 06:40:33 +0000208};
209
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000210/// ARMConstantPoolSymbol - ARM-specific constantpool values for external
211/// symbols.
212class ARMConstantPoolSymbol : public ARMConstantPoolValue {
Benjamin Kramer9d461102012-12-24 19:23:30 +0000213 const std::string S; // ExtSymbol being loaded.
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000214
Mehdi Amini5b007702016-10-05 01:41:06 +0000215 ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id,
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000216 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
217 bool AddCurrentAddress);
218
219public:
Mehdi Amini5b007702016-10-05 01:41:06 +0000220 static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID,
221 unsigned char PCAdj);
Bill Wendlingc214cb02011-10-01 08:58:29 +0000222
Mehdi Amini5b007702016-10-05 01:41:06 +0000223 StringRef getSymbol() const { return S; }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000224
Craig Topper6bc27bf2014-03-10 02:09:33 +0000225 int getExistingMachineCPValue(MachineConstantPool *CP,
226 unsigned Alignment) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000227
Craig Topper6bc27bf2014-03-10 02:09:33 +0000228 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000229
230 /// hasSameValue - Return true if this ARM constpool value can share the same
231 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000232 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000233
Craig Topper6bc27bf2014-03-10 02:09:33 +0000234 void print(raw_ostream &O) const override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000235
236 static bool classof(const ARMConstantPoolValue *ACPV) {
237 return ACPV->isExtSymbol();
238 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000239
240 bool equals(const ARMConstantPoolSymbol *A) const {
241 return S == A->S && ARMConstantPoolValue::equals(A);
242 }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000243};
244
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000245/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
246/// block.
247class ARMConstantPoolMBB : public ARMConstantPoolValue {
Bill Wendling4a4772f2011-10-01 09:30:42 +0000248 const MachineBasicBlock *MBB; // Machine basic block.
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000249
Bill Wendling4a4772f2011-10-01 09:30:42 +0000250 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000251 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
252 bool AddCurrentAddress);
253
254public:
Bill Wendling4a4772f2011-10-01 09:30:42 +0000255 static ARMConstantPoolMBB *Create(LLVMContext &C,
256 const MachineBasicBlock *mbb,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000257 unsigned ID, unsigned char PCAdj);
258
259 const MachineBasicBlock *getMBB() const { return MBB; }
260
Craig Topper6bc27bf2014-03-10 02:09:33 +0000261 int getExistingMachineCPValue(MachineConstantPool *CP,
262 unsigned Alignment) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000263
Craig Topper6bc27bf2014-03-10 02:09:33 +0000264 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000265
266 /// hasSameValue - Return true if this ARM constpool value can share the same
267 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000268 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000269
Craig Topper6bc27bf2014-03-10 02:09:33 +0000270 void print(raw_ostream &O) const override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000271
272 static bool classof(const ARMConstantPoolValue *ACPV) {
273 return ACPV->isMachineBasicBlock();
274 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000275
276 bool equals(const ARMConstantPoolMBB *A) const {
277 return MBB == A->MBB && ARMConstantPoolValue::equals(A);
278 }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000279};
280
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000281} // end namespace llvm
Evan Cheng10043e22007-01-19 07:51:42 +0000282
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000283#endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H