blob: 55194ed945325fd30c16bfcc4a40f19559acba9e [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//
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
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +000017#include "llvm/ADT/SmallPtrSet.h"
Eugene Zelenko076468c2017-09-20 21:35:51 +000018#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/iterator_range.h"
Evan Cheng10043e22007-01-19 07:51:42 +000020#include "llvm/CodeGen/MachineConstantPool.h"
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000021#include "llvm/Support/Casting.h"
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000022#include <string>
23#include <vector>
Evan Cheng10043e22007-01-19 07:51:42 +000024
25namespace llvm {
26
Bob Wilson433ab092009-11-02 16:59:06 +000027class BlockAddress;
Bill Wendlinga1127b22011-09-29 23:48:44 +000028class Constant;
Dan Gohman0597e5b2008-07-11 20:38:31 +000029class GlobalValue;
James Molloy9abb2fa2016-09-26 07:26:24 +000030class GlobalVariable;
Owen Anderson55f1c092009-08-13 21:58:54 +000031class LLVMContext;
Bill Wendlinga1127b22011-09-29 23:48:44 +000032class MachineBasicBlock;
Eugene Zelenko076468c2017-09-20 21:35:51 +000033class raw_ostream;
34class Type;
Dan Gohman0597e5b2008-07-11 20:38:31 +000035
Jim Grosbach20eac922009-09-01 01:57:56 +000036namespace ARMCP {
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000037
Jim Grosbach20eac922009-09-01 01:57:56 +000038 enum ARMCPKind {
39 CPValue,
Bob Wilson433ab092009-11-02 16:59:06 +000040 CPExtSymbol,
41 CPBlockAddress,
Bill Wendlinga1127b22011-09-29 23:48:44 +000042 CPLSDA,
James Molloy9abb2fa2016-09-26 07:26:24 +000043 CPMachineBasicBlock,
44 CPPromotedGlobal
Jim Grosbach20eac922009-09-01 01:57:56 +000045 };
Jim Grosbacha942ad42010-11-09 21:36:17 +000046
47 enum ARMCPModifier {
Saleem Abdulrasoolce4eee42016-06-07 03:15:01 +000048 no_modifier, /// None
49 TLSGD, /// Thread Local Storage (General Dynamic Mode)
50 GOT_PREL, /// Global Offset Table, PC Relative
51 GOTTPOFF, /// Global Offset Table, Thread Pointer Offset
52 TPOFF, /// Thread Pointer Offset
Saleem Abdulrasool532dcbc2016-06-07 03:15:07 +000053 SECREL, /// Section Relative (Windows TLS)
Oliver Stannard8331aae2016-08-08 15:28:31 +000054 SBREL, /// Static Base Relative (RWPI)
Jim Grosbacha942ad42010-11-09 21:36:17 +000055 };
Eugene Zelenkoe79c0772017-01-27 23:58:02 +000056
57} // end namespace ARMCP
Jim Grosbach20eac922009-09-01 01:57:56 +000058
Evan Cheng10043e22007-01-19 07:51:42 +000059/// ARMConstantPoolValue - ARM specific constantpool value. This is used to
Bob Wilson4c00a522009-11-02 17:10:37 +000060/// represent PC-relative displacement between the address of the load
Bob Wilson433ab092009-11-02 16:59:06 +000061/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
Evan Cheng10043e22007-01-19 07:51:42 +000062class ARMConstantPoolValue : public MachineConstantPoolValue {
Evan Cheng10043e22007-01-19 07:51:42 +000063 unsigned LabelId; // Label id of the load.
Bob Wilson433ab092009-11-02 16:59:06 +000064 ARMCP::ARMCPKind Kind; // Kind of constant.
Bob Wilson4c00a522009-11-02 17:10:37 +000065 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative.
Evan Cheng10043e22007-01-19 07:51:42 +000066 // 8 for ARM, 4 for Thumb.
Jim Grosbacha942ad42010-11-09 21:36:17 +000067 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000068 bool AddCurrentAddress;
Evan Cheng10043e22007-01-19 07:51:42 +000069
Bill Wendling396c2112011-10-01 06:40:33 +000070protected:
71 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
72 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
73 bool AddCurrentAddress);
74
Bill Wendlingd7fa0162011-10-01 08:36:59 +000075 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
76 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
77 bool AddCurrentAddress);
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000078
79 template <typename Derived>
80 int getExistingMachineCPValueImpl(MachineConstantPool *CP,
81 unsigned Alignment) {
82 unsigned AlignMask = Alignment - 1;
83 const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
84 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
85 if (Constants[i].isMachineConstantPoolEntry() &&
86 (Constants[i].getAlignment() & AlignMask) == 0) {
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +000087 auto *CPV =
88 static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal);
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000089 if (Derived *APC = dyn_cast<Derived>(CPV))
90 if (cast<Derived>(this)->equals(APC))
91 return i;
92 }
93 }
94
95 return -1;
96 }
97
Evan Cheng10043e22007-01-19 07:51:42 +000098public:
Alexander Kornienkof817c1c2015-04-11 02:11:45 +000099 ~ARMConstantPoolValue() override;
Lauro Ramos Venancioee2d1642007-04-22 00:04:12 +0000100
Jim Grosbacha942ad42010-11-09 21:36:17 +0000101 ARMCP::ARMCPModifier getModifier() const { return Modifier; }
Mehdi Amini5b007702016-10-05 01:41:06 +0000102 StringRef getModifierText() const;
Jim Grosbacha942ad42010-11-09 21:36:17 +0000103 bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000104
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +0000105 bool mustAddCurrentAddress() const { return AddCurrentAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000106
Evan Cheng10043e22007-01-19 07:51:42 +0000107 unsigned getLabelId() const { return LabelId; }
Evan Cheng10043e22007-01-19 07:51:42 +0000108 unsigned char getPCAdjustment() const { return PCAdjust; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000109
Bob Wilson433ab092009-11-02 16:59:06 +0000110 bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
111 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
Bill Wendling396c2112011-10-01 06:40:33 +0000112 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000113 bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000114 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
James Molloy9abb2fa2016-09-26 07:26:24 +0000115 bool isPromotedGlobal() const{ return Kind == ARMCP::CPPromotedGlobal; }
Fangrui Songf78650a2018-07-30 19:41:25 +0000116
Craig Topper6bc27bf2014-03-10 02:09:33 +0000117 int getExistingMachineCPValue(MachineConstantPool *CP,
118 unsigned Alignment) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000119
Craig Topper6bc27bf2014-03-10 02:09:33 +0000120 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000121
Bill Wendling396c2112011-10-01 06:40:33 +0000122 /// hasSameValue - Return true if this ARM constpool value can share the same
123 /// constantpool entry as another ARM constpool value.
124 virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
Evan Cheng7ff83192009-11-07 03:52:02 +0000125
Bill Wendlingf977ff52011-10-01 12:44:28 +0000126 bool equals(const ARMConstantPoolValue *A) const {
127 return this->LabelId == A->LabelId &&
128 this->PCAdjust == A->PCAdjust &&
129 this->Modifier == A->Modifier;
130 }
131
Craig Topper6bc27bf2014-03-10 02:09:33 +0000132 void print(raw_ostream &O) const override;
Evan Chengde9dbc52008-10-29 23:55:17 +0000133 void print(raw_ostream *O) const { if (O) print(*O); }
Evan Chengde9dbc52008-10-29 23:55:17 +0000134 void dump() const;
Evan Cheng10043e22007-01-19 07:51:42 +0000135};
Evan Chengde9dbc52008-10-29 23:55:17 +0000136
Evan Chengde9dbc52008-10-29 23:55:17 +0000137inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
138 V.print(O);
139 return O;
140}
141
Bill Wendling396c2112011-10-01 06:40:33 +0000142/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
143/// Functions, and BlockAddresses.
144class ARMConstantPoolConstant : public ARMConstantPoolValue {
145 const Constant *CVal; // Constant being loaded.
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +0000146 SmallPtrSet<const GlobalVariable*, 1> GVars;
Bill Wendling396c2112011-10-01 06:40:33 +0000147
148 ARMConstantPoolConstant(const Constant *C,
149 unsigned ID,
150 ARMCP::ARMCPKind Kind,
151 unsigned char PCAdj,
152 ARMCP::ARMCPModifier Modifier,
153 bool AddCurrentAddress);
Bill Wendlingf117a352011-10-01 07:52:37 +0000154 ARMConstantPoolConstant(Type *Ty, const Constant *C,
155 unsigned ID,
156 ARMCP::ARMCPKind Kind,
157 unsigned char PCAdj,
158 ARMCP::ARMCPModifier Modifier,
159 bool AddCurrentAddress);
James Molloy9abb2fa2016-09-26 07:26:24 +0000160 ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init);
Bill Wendlingf117a352011-10-01 07:52:37 +0000161
Bill Wendling396c2112011-10-01 06:40:33 +0000162public:
163 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
Bill Wendlingf117a352011-10-01 07:52:37 +0000164 static ARMConstantPoolConstant *Create(const GlobalValue *GV,
165 ARMCP::ARMCPModifier Modifier);
James Molloy9abb2fa2016-09-26 07:26:24 +0000166 static ARMConstantPoolConstant *Create(const GlobalVariable *GV,
167 const Constant *Initializer);
Bill Wendling67225562011-10-01 06:44:24 +0000168 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
169 ARMCP::ARMCPKind Kind,
170 unsigned char PCAdj);
Bill Wendlingf117a352011-10-01 07:52:37 +0000171 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
172 ARMCP::ARMCPKind Kind,
173 unsigned char PCAdj,
174 ARMCP::ARMCPModifier Modifier,
175 bool AddCurrentAddress);
Bill Wendling396c2112011-10-01 06:40:33 +0000176
177 const GlobalValue *getGV() const;
Bill Wendlingf117a352011-10-01 07:52:37 +0000178 const BlockAddress *getBlockAddress() const;
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000179
Eugene Zelenko076468c2017-09-20 21:35:51 +0000180 using promoted_iterator = SmallPtrSet<const GlobalVariable *, 1>::iterator;
181
Saleem Abdulrasool5fba8ba2017-09-07 04:00:13 +0000182 iterator_range<promoted_iterator> promotedGlobals() {
183 return iterator_range<promoted_iterator>(GVars.begin(), GVars.end());
James Molloy9abb2fa2016-09-26 07:26:24 +0000184 }
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000185
James Molloy9abb2fa2016-09-26 07:26:24 +0000186 const Constant *getPromotedGlobalInit() const {
187 return CVal;
188 }
Bill Wendlingf117a352011-10-01 07:52:37 +0000189
Craig Topper6bc27bf2014-03-10 02:09:33 +0000190 int getExistingMachineCPValue(MachineConstantPool *CP,
191 unsigned Alignment) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000192
193 /// hasSameValue - Return true if this ARM constpool value can share the same
194 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000195 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000196
Craig Topper6bc27bf2014-03-10 02:09:33 +0000197 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000198
Craig Topper6bc27bf2014-03-10 02:09:33 +0000199 void print(raw_ostream &O) const override;
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000200
Bill Wendling396c2112011-10-01 06:40:33 +0000201 static bool classof(const ARMConstantPoolValue *APV) {
James Molloy9abb2fa2016-09-26 07:26:24 +0000202 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA() ||
203 APV->isPromotedGlobal();
Bill Wendling396c2112011-10-01 06:40:33 +0000204 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000205
206 bool equals(const ARMConstantPoolConstant *A) const {
207 return CVal == A->CVal && ARMConstantPoolValue::equals(A);
208 }
Bill Wendling396c2112011-10-01 06:40:33 +0000209};
210
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000211/// ARMConstantPoolSymbol - ARM-specific constantpool values for external
212/// symbols.
213class ARMConstantPoolSymbol : public ARMConstantPoolValue {
Benjamin Kramer9d461102012-12-24 19:23:30 +0000214 const std::string S; // ExtSymbol being loaded.
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000215
Mehdi Amini5b007702016-10-05 01:41:06 +0000216 ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id,
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000217 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
218 bool AddCurrentAddress);
219
220public:
Mehdi Amini5b007702016-10-05 01:41:06 +0000221 static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID,
222 unsigned char PCAdj);
Bill Wendlingc214cb02011-10-01 08:58:29 +0000223
Mehdi Amini5b007702016-10-05 01:41:06 +0000224 StringRef getSymbol() const { return S; }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000225
Craig Topper6bc27bf2014-03-10 02:09:33 +0000226 int getExistingMachineCPValue(MachineConstantPool *CP,
227 unsigned Alignment) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000228
Craig Topper6bc27bf2014-03-10 02:09:33 +0000229 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000230
231 /// hasSameValue - Return true if this ARM constpool value can share the same
232 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000233 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000234
Craig Topper6bc27bf2014-03-10 02:09:33 +0000235 void print(raw_ostream &O) const override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000236
237 static bool classof(const ARMConstantPoolValue *ACPV) {
238 return ACPV->isExtSymbol();
239 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000240
241 bool equals(const ARMConstantPoolSymbol *A) const {
242 return S == A->S && ARMConstantPoolValue::equals(A);
243 }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000244};
245
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000246/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
247/// block.
248class ARMConstantPoolMBB : public ARMConstantPoolValue {
Bill Wendling4a4772f2011-10-01 09:30:42 +0000249 const MachineBasicBlock *MBB; // Machine basic block.
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000250
Bill Wendling4a4772f2011-10-01 09:30:42 +0000251 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000252 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
253 bool AddCurrentAddress);
254
255public:
Bill Wendling4a4772f2011-10-01 09:30:42 +0000256 static ARMConstantPoolMBB *Create(LLVMContext &C,
257 const MachineBasicBlock *mbb,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000258 unsigned ID, unsigned char PCAdj);
259
260 const MachineBasicBlock *getMBB() const { return MBB; }
261
Craig Topper6bc27bf2014-03-10 02:09:33 +0000262 int getExistingMachineCPValue(MachineConstantPool *CP,
263 unsigned Alignment) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000264
Craig Topper6bc27bf2014-03-10 02:09:33 +0000265 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000266
267 /// hasSameValue - Return true if this ARM constpool value can share the same
268 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000269 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000270
Craig Topper6bc27bf2014-03-10 02:09:33 +0000271 void print(raw_ostream &O) const override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000272
273 static bool classof(const ARMConstantPoolValue *ACPV) {
274 return ACPV->isMachineBasicBlock();
275 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000276
277 bool equals(const ARMConstantPoolMBB *A) const {
278 return MBB == A->MBB && ARMConstantPoolValue::equals(A);
279 }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000280};
281
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000282} // end namespace llvm
Evan Cheng10043e22007-01-19 07:51:42 +0000283
Eugene Zelenkoe79c0772017-01-27 23:58:02 +0000284#endif // LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H