blob: 30ce8716c5cb70af489ec915f2690a89253d41f0 [file] [log] [blame]
Jia Liub22310f2012-02-18 12:03:15 +00001//===-- ARMConstantPoolValue.h - ARM constantpool value ---------*- C++ -*-===//
Evan Cheng10043e22007-01-19 07:51:42 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Evan Cheng10043e22007-01-19 07:51:42 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the ARM specific constantpool value class.
11//
12//===----------------------------------------------------------------------===//
13
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000014#ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
15#define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H
Evan Cheng10043e22007-01-19 07:51:42 +000016
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000017#include "llvm/ADT/StringRef.h"
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +000018#include "llvm/ADT/SmallPtrSet.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;
Dan Gohman0597e5b2008-07-11 20:38:31 +000032
Jim Grosbach20eac922009-09-01 01:57:56 +000033namespace ARMCP {
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000034
Jim Grosbach20eac922009-09-01 01:57:56 +000035 enum ARMCPKind {
36 CPValue,
Bob Wilson433ab092009-11-02 16:59:06 +000037 CPExtSymbol,
38 CPBlockAddress,
Bill Wendlinga1127b22011-09-29 23:48:44 +000039 CPLSDA,
James Molloy9abb2fa2016-09-26 07:26:24 +000040 CPMachineBasicBlock,
41 CPPromotedGlobal
Jim Grosbach20eac922009-09-01 01:57:56 +000042 };
Jim Grosbacha942ad42010-11-09 21:36:17 +000043
44 enum ARMCPModifier {
Saleem Abdulrasoolce4eee42016-06-07 03:15:01 +000045 no_modifier, /// None
46 TLSGD, /// Thread Local Storage (General Dynamic Mode)
47 GOT_PREL, /// Global Offset Table, PC Relative
48 GOTTPOFF, /// Global Offset Table, Thread Pointer Offset
49 TPOFF, /// Thread Pointer Offset
Saleem Abdulrasool532dcbc2016-06-07 03:15:07 +000050 SECREL, /// Section Relative (Windows TLS)
Oliver Stannard8331aae2016-08-08 15:28:31 +000051 SBREL, /// Static Base Relative (RWPI)
Jim Grosbacha942ad42010-11-09 21:36:17 +000052 };
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000053
54} // end namespace ARMCP
Jim Grosbach20eac922009-09-01 01:57:56 +000055
Evan Cheng10043e22007-01-19 07:51:42 +000056/// ARMConstantPoolValue - ARM specific constantpool value. This is used to
Bob Wilson4c00a522009-11-02 17:10:37 +000057/// represent PC-relative displacement between the address of the load
Bob Wilson433ab092009-11-02 16:59:06 +000058/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
Evan Cheng10043e22007-01-19 07:51:42 +000059class ARMConstantPoolValue : public MachineConstantPoolValue {
Evan Cheng10043e22007-01-19 07:51:42 +000060 unsigned LabelId; // Label id of the load.
Bob Wilson433ab092009-11-02 16:59:06 +000061 ARMCP::ARMCPKind Kind; // Kind of constant.
Bob Wilson4c00a522009-11-02 17:10:37 +000062 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative.
Evan Cheng10043e22007-01-19 07:51:42 +000063 // 8 for ARM, 4 for Thumb.
Jim Grosbacha942ad42010-11-09 21:36:17 +000064 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000065 bool AddCurrentAddress;
Evan Cheng10043e22007-01-19 07:51:42 +000066
Bill Wendling396c2112011-10-01 06:40:33 +000067protected:
68 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
69 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
70 bool AddCurrentAddress);
71
Bill Wendlingd7fa0162011-10-01 08:36:59 +000072 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
73 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
74 bool AddCurrentAddress);
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000075
76 template <typename Derived>
77 int getExistingMachineCPValueImpl(MachineConstantPool *CP,
78 unsigned Alignment) {
79 unsigned AlignMask = Alignment - 1;
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].getAlignment() & AlignMask) == 0) {
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +000084 auto *CPV =
85 static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000086 if (Derived *APC = dyn_cast<Derived>(CPV))
87 if (cast<Derived>(this)->equals(APC))
88 return i;
89 }
90 }
91
92 return -1;
93 }
94
Evan Cheng10043e22007-01-19 07:51:42 +000095public:
Alexander Kornienkof817c1c2015-04-11 02:11:45 +000096 ~ARMConstantPoolValue() override;
Lauro Ramos Venancioee2d1642007-04-22 00:04:12 +000097
Jim Grosbacha942ad42010-11-09 21:36:17 +000098 ARMCP::ARMCPModifier getModifier() const { return Modifier; }
Mehdi Amini5b007702016-10-05 01:41:06 +000099 StringRef getModifierText() const;
Jim Grosbacha942ad42010-11-09 21:36:17 +0000100 bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000101
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +0000102 bool mustAddCurrentAddress() const { return AddCurrentAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000103
Evan Cheng10043e22007-01-19 07:51:42 +0000104 unsigned getLabelId() const { return LabelId; }
Evan Cheng10043e22007-01-19 07:51:42 +0000105 unsigned char getPCAdjustment() const { return PCAdjust; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000106
Bob Wilson433ab092009-11-02 16:59:06 +0000107 bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
108 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
Bill Wendling396c2112011-10-01 06:40:33 +0000109 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000110 bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000111 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
James Molloy9abb2fa2016-09-26 07:26:24 +0000112 bool isPromotedGlobal() const{ return Kind == ARMCP::CPPromotedGlobal; }
113
Craig Topper6bc27bf2014-03-10 02:09:33 +0000114 int getExistingMachineCPValue(MachineConstantPool *CP,
115 unsigned Alignment) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000116
Craig Topper6bc27bf2014-03-10 02:09:33 +0000117 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000118
Bill Wendling396c2112011-10-01 06:40:33 +0000119 /// 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);
Evan Cheng7ff83192009-11-07 03:52:02 +0000122
Bill Wendlingf977ff52011-10-01 12:44:28 +0000123 bool equals(const ARMConstantPoolValue *A) const {
124 return this->LabelId == A->LabelId &&
125 this->PCAdjust == A->PCAdjust &&
126 this->Modifier == A->Modifier;
127 }
128
Craig Topper6bc27bf2014-03-10 02:09:33 +0000129 void print(raw_ostream &O) const override;
Evan Chengde9dbc52008-10-29 23:55:17 +0000130 void print(raw_ostream *O) const { if (O) print(*O); }
Evan Chengde9dbc52008-10-29 23:55:17 +0000131 void dump() const;
Evan Cheng10043e22007-01-19 07:51:42 +0000132};
Evan Chengde9dbc52008-10-29 23:55:17 +0000133
Evan Chengde9dbc52008-10-29 23:55:17 +0000134inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
135 V.print(O);
136 return O;
137}
138
Bill Wendling396c2112011-10-01 06:40:33 +0000139/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
140/// Functions, and BlockAddresses.
141class ARMConstantPoolConstant : public ARMConstantPoolValue {
142 const Constant *CVal; // Constant being loaded.
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +0000143 SmallPtrSet<const GlobalVariable*, 1> GVars;
Bill Wendling396c2112011-10-01 06:40:33 +0000144
145 ARMConstantPoolConstant(const Constant *C,
146 unsigned ID,
147 ARMCP::ARMCPKind Kind,
148 unsigned char PCAdj,
149 ARMCP::ARMCPModifier Modifier,
150 bool AddCurrentAddress);
Bill Wendlingf117a352011-10-01 07:52:37 +0000151 ARMConstantPoolConstant(Type *Ty, const Constant *C,
152 unsigned ID,
153 ARMCP::ARMCPKind Kind,
154 unsigned char PCAdj,
155 ARMCP::ARMCPModifier Modifier,
156 bool AddCurrentAddress);
James Molloy9abb2fa2016-09-26 07:26:24 +0000157 ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init);
Bill Wendlingf117a352011-10-01 07:52:37 +0000158
Bill Wendling396c2112011-10-01 06:40:33 +0000159public:
160 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
Bill Wendlingf117a352011-10-01 07:52:37 +0000161 static ARMConstantPoolConstant *Create(const GlobalValue *GV,
162 ARMCP::ARMCPModifier Modifier);
James Molloy9abb2fa2016-09-26 07:26:24 +0000163 static ARMConstantPoolConstant *Create(const GlobalVariable *GV,
164 const Constant *Initializer);
Bill Wendling67225562011-10-01 06:44:24 +0000165 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
166 ARMCP::ARMCPKind Kind,
167 unsigned char PCAdj);
Bill Wendlingf117a352011-10-01 07:52:37 +0000168 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
169 ARMCP::ARMCPKind Kind,
170 unsigned char PCAdj,
171 ARMCP::ARMCPModifier Modifier,
172 bool AddCurrentAddress);
Bill Wendling396c2112011-10-01 06:40:33 +0000173
174 const GlobalValue *getGV() const;
Bill Wendlingf117a352011-10-01 07:52:37 +0000175 const BlockAddress *getBlockAddress() const;
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000176
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +0000177 typedef SmallPtrSet<const GlobalVariable *, 1>::iterator promoted_iterator;
178 iterator_range<promoted_iterator> promotedGlobals() {
179 return iterator_range<promoted_iterator>(GVars.begin(), GVars.end());
James Molloy9abb2fa2016-09-26 07:26:24 +0000180 }
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000181
James Molloy9abb2fa2016-09-26 07:26:24 +0000182 const Constant *getPromotedGlobalInit() const {
183 return CVal;
184 }
Bill Wendlingf117a352011-10-01 07:52:37 +0000185
Craig Topper6bc27bf2014-03-10 02:09:33 +0000186 int getExistingMachineCPValue(MachineConstantPool *CP,
187 unsigned Alignment) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000188
189 /// hasSameValue - Return true if this ARM constpool value can share the same
190 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000191 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000192
Craig Topper6bc27bf2014-03-10 02:09:33 +0000193 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000194
Craig Topper6bc27bf2014-03-10 02:09:33 +0000195 void print(raw_ostream &O) const override;
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000196
Bill Wendling396c2112011-10-01 06:40:33 +0000197 static bool classof(const ARMConstantPoolValue *APV) {
James Molloy9abb2fa2016-09-26 07:26:24 +0000198 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA() ||
199 APV->isPromotedGlobal();
Bill Wendling396c2112011-10-01 06:40:33 +0000200 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000201
202 bool equals(const ARMConstantPoolConstant *A) const {
203 return CVal == A->CVal && ARMConstantPoolValue::equals(A);
204 }
Bill Wendling396c2112011-10-01 06:40:33 +0000205};
206
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000207/// ARMConstantPoolSymbol - ARM-specific constantpool values for external
208/// symbols.
209class ARMConstantPoolSymbol : public ARMConstantPoolValue {
Benjamin Kramer9d461102012-12-24 19:23:30 +0000210 const std::string S; // ExtSymbol being loaded.
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000211
Mehdi Amini5b007702016-10-05 01:41:06 +0000212 ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id,
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000213 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
214 bool AddCurrentAddress);
215
216public:
Mehdi Amini5b007702016-10-05 01:41:06 +0000217 static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID,
218 unsigned char PCAdj);
Bill Wendlingc214cb02011-10-01 08:58:29 +0000219
Mehdi Amini5b007702016-10-05 01:41:06 +0000220 StringRef getSymbol() const { return S; }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000221
Craig Topper6bc27bf2014-03-10 02:09:33 +0000222 int getExistingMachineCPValue(MachineConstantPool *CP,
223 unsigned Alignment) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000224
Craig Topper6bc27bf2014-03-10 02:09:33 +0000225 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000226
227 /// hasSameValue - Return true if this ARM constpool value can share the same
228 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000229 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000230
Craig Topper6bc27bf2014-03-10 02:09:33 +0000231 void print(raw_ostream &O) const override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000232
233 static bool classof(const ARMConstantPoolValue *ACPV) {
234 return ACPV->isExtSymbol();
235 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000236
237 bool equals(const ARMConstantPoolSymbol *A) const {
238 return S == A->S && ARMConstantPoolValue::equals(A);
239 }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000240};
241
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000242/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
243/// block.
244class ARMConstantPoolMBB : public ARMConstantPoolValue {
Bill Wendling4a4772f2011-10-01 09:30:42 +0000245 const MachineBasicBlock *MBB; // Machine basic block.
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000246
Bill Wendling4a4772f2011-10-01 09:30:42 +0000247 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000248 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
249 bool AddCurrentAddress);
250
251public:
Bill Wendling4a4772f2011-10-01 09:30:42 +0000252 static ARMConstantPoolMBB *Create(LLVMContext &C,
253 const MachineBasicBlock *mbb,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000254 unsigned ID, unsigned char PCAdj);
255
256 const MachineBasicBlock *getMBB() const { return MBB; }
257
Craig Topper6bc27bf2014-03-10 02:09:33 +0000258 int getExistingMachineCPValue(MachineConstantPool *CP,
259 unsigned Alignment) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000260
Craig Topper6bc27bf2014-03-10 02:09:33 +0000261 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000262
263 /// hasSameValue - Return true if this ARM constpool value can share the same
264 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000265 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000266
Craig Topper6bc27bf2014-03-10 02:09:33 +0000267 void print(raw_ostream &O) const override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000268
269 static bool classof(const ARMConstantPoolValue *ACPV) {
270 return ACPV->isMachineBasicBlock();
271 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000272
273 bool equals(const ARMConstantPoolMBB *A) const {
274 return MBB == A->MBB && ARMConstantPoolValue::equals(A);
275 }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000276};
277
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000278} // end namespace llvm
Evan Cheng10043e22007-01-19 07:51:42 +0000279
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000280#endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H