blob: 5f61832aa740c581caafb5857fd88c970e31fc3f [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
17#include "llvm/CodeGen/MachineConstantPool.h"
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000018#include "llvm/Support/Casting.h"
Jim Grosbacha942ad42010-11-09 21:36:17 +000019#include "llvm/Support/ErrorHandling.h"
Daniel Dunbar09041342010-06-15 14:50:42 +000020#include <cstddef>
Evan Cheng10043e22007-01-19 07:51:42 +000021
22namespace llvm {
23
Bob Wilson433ab092009-11-02 16:59:06 +000024class BlockAddress;
Bill Wendlinga1127b22011-09-29 23:48:44 +000025class Constant;
Dan Gohman0597e5b2008-07-11 20:38:31 +000026class GlobalValue;
James Molloy9abb2fa2016-09-26 07:26:24 +000027class GlobalVariable;
Owen Anderson55f1c092009-08-13 21:58:54 +000028class LLVMContext;
Bill Wendlinga1127b22011-09-29 23:48:44 +000029class MachineBasicBlock;
Dan Gohman0597e5b2008-07-11 20:38:31 +000030
Jim Grosbach20eac922009-09-01 01:57:56 +000031namespace ARMCP {
32 enum ARMCPKind {
33 CPValue,
Bob Wilson433ab092009-11-02 16:59:06 +000034 CPExtSymbol,
35 CPBlockAddress,
Bill Wendlinga1127b22011-09-29 23:48:44 +000036 CPLSDA,
James Molloy9abb2fa2016-09-26 07:26:24 +000037 CPMachineBasicBlock,
38 CPPromotedGlobal
Jim Grosbach20eac922009-09-01 01:57:56 +000039 };
Jim Grosbacha942ad42010-11-09 21:36:17 +000040
41 enum ARMCPModifier {
Saleem Abdulrasoolce4eee42016-06-07 03:15:01 +000042 no_modifier, /// None
43 TLSGD, /// Thread Local Storage (General Dynamic Mode)
44 GOT_PREL, /// Global Offset Table, PC Relative
45 GOTTPOFF, /// Global Offset Table, Thread Pointer Offset
46 TPOFF, /// Thread Pointer Offset
Saleem Abdulrasool532dcbc2016-06-07 03:15:07 +000047 SECREL, /// Section Relative (Windows TLS)
Oliver Stannard8331aae2016-08-08 15:28:31 +000048 SBREL, /// Static Base Relative (RWPI)
Jim Grosbacha942ad42010-11-09 21:36:17 +000049 };
Alexander Kornienkof00654e2015-06-23 09:49:53 +000050}
Jim Grosbach20eac922009-09-01 01:57:56 +000051
Evan Cheng10043e22007-01-19 07:51:42 +000052/// ARMConstantPoolValue - ARM specific constantpool value. This is used to
Bob Wilson4c00a522009-11-02 17:10:37 +000053/// represent PC-relative displacement between the address of the load
Bob Wilson433ab092009-11-02 16:59:06 +000054/// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)).
Evan Cheng10043e22007-01-19 07:51:42 +000055class ARMConstantPoolValue : public MachineConstantPoolValue {
Evan Cheng10043e22007-01-19 07:51:42 +000056 unsigned LabelId; // Label id of the load.
Bob Wilson433ab092009-11-02 16:59:06 +000057 ARMCP::ARMCPKind Kind; // Kind of constant.
Bob Wilson4c00a522009-11-02 17:10:37 +000058 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative.
Evan Cheng10043e22007-01-19 07:51:42 +000059 // 8 for ARM, 4 for Thumb.
Jim Grosbacha942ad42010-11-09 21:36:17 +000060 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000061 bool AddCurrentAddress;
Evan Cheng10043e22007-01-19 07:51:42 +000062
Bill Wendling396c2112011-10-01 06:40:33 +000063protected:
64 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind,
65 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
66 bool AddCurrentAddress);
67
Bill Wendlingd7fa0162011-10-01 08:36:59 +000068 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind,
69 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
70 bool AddCurrentAddress);
Benjamin Kramer2ef689c2013-09-16 10:17:31 +000071
72 template <typename Derived>
73 int getExistingMachineCPValueImpl(MachineConstantPool *CP,
74 unsigned Alignment) {
75 unsigned AlignMask = Alignment - 1;
76 const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
77 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
78 if (Constants[i].isMachineConstantPoolEntry() &&
79 (Constants[i].getAlignment() & AlignMask) == 0) {
80 ARMConstantPoolValue *CPV =
81 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
82 if (Derived *APC = dyn_cast<Derived>(CPV))
83 if (cast<Derived>(this)->equals(APC))
84 return i;
85 }
86 }
87
88 return -1;
89 }
90
Evan Cheng10043e22007-01-19 07:51:42 +000091public:
Alexander Kornienkof817c1c2015-04-11 02:11:45 +000092 ~ARMConstantPoolValue() override;
Lauro Ramos Venancioee2d1642007-04-22 00:04:12 +000093
Jim Grosbacha942ad42010-11-09 21:36:17 +000094 ARMCP::ARMCPModifier getModifier() const { return Modifier; }
Mehdi Amini5b007702016-10-05 01:41:06 +000095 StringRef getModifierText() const;
Jim Grosbacha942ad42010-11-09 21:36:17 +000096 bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +000097
Lauro Ramos Venancioc39c12a2007-04-27 13:54:47 +000098 bool mustAddCurrentAddress() const { return AddCurrentAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +000099
Evan Cheng10043e22007-01-19 07:51:42 +0000100 unsigned getLabelId() const { return LabelId; }
Evan Cheng10043e22007-01-19 07:51:42 +0000101 unsigned char getPCAdjustment() const { return PCAdjust; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000102
Bob Wilson433ab092009-11-02 16:59:06 +0000103 bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
104 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
Bill Wendling396c2112011-10-01 06:40:33 +0000105 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
Bill Wendlinge8e4dbf2011-09-30 18:42:06 +0000106 bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000107 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
James Molloy9abb2fa2016-09-26 07:26:24 +0000108 bool isPromotedGlobal() const{ return Kind == ARMCP::CPPromotedGlobal; }
109
Craig Topper6bc27bf2014-03-10 02:09:33 +0000110 int getExistingMachineCPValue(MachineConstantPool *CP,
111 unsigned Alignment) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000112
Craig Topper6bc27bf2014-03-10 02:09:33 +0000113 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Evan Cheng10043e22007-01-19 07:51:42 +0000114
Bill Wendling396c2112011-10-01 06:40:33 +0000115 /// hasSameValue - Return true if this ARM constpool value can share the same
116 /// constantpool entry as another ARM constpool value.
117 virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
Evan Cheng7ff83192009-11-07 03:52:02 +0000118
Bill Wendlingf977ff52011-10-01 12:44:28 +0000119 bool equals(const ARMConstantPoolValue *A) const {
120 return this->LabelId == A->LabelId &&
121 this->PCAdjust == A->PCAdjust &&
122 this->Modifier == A->Modifier;
123 }
124
Craig Topper6bc27bf2014-03-10 02:09:33 +0000125 void print(raw_ostream &O) const override;
Evan Chengde9dbc52008-10-29 23:55:17 +0000126 void print(raw_ostream *O) const { if (O) print(*O); }
Evan Chengde9dbc52008-10-29 23:55:17 +0000127 void dump() const;
Evan Cheng10043e22007-01-19 07:51:42 +0000128};
Evan Chengde9dbc52008-10-29 23:55:17 +0000129
Evan Chengde9dbc52008-10-29 23:55:17 +0000130inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
131 V.print(O);
132 return O;
133}
134
Bill Wendling396c2112011-10-01 06:40:33 +0000135/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
136/// Functions, and BlockAddresses.
137class ARMConstantPoolConstant : public ARMConstantPoolValue {
138 const Constant *CVal; // Constant being loaded.
James Molloy9abb2fa2016-09-26 07:26:24 +0000139 const GlobalVariable *GVar = nullptr;
Bill Wendling396c2112011-10-01 06:40:33 +0000140
141 ARMConstantPoolConstant(const Constant *C,
142 unsigned ID,
143 ARMCP::ARMCPKind Kind,
144 unsigned char PCAdj,
145 ARMCP::ARMCPModifier Modifier,
146 bool AddCurrentAddress);
Bill Wendlingf117a352011-10-01 07:52:37 +0000147 ARMConstantPoolConstant(Type *Ty, const Constant *C,
148 unsigned ID,
149 ARMCP::ARMCPKind Kind,
150 unsigned char PCAdj,
151 ARMCP::ARMCPModifier Modifier,
152 bool AddCurrentAddress);
James Molloy9abb2fa2016-09-26 07:26:24 +0000153 ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init);
Bill Wendlingf117a352011-10-01 07:52:37 +0000154
Bill Wendling396c2112011-10-01 06:40:33 +0000155public:
156 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
Bill Wendlingf117a352011-10-01 07:52:37 +0000157 static ARMConstantPoolConstant *Create(const GlobalValue *GV,
158 ARMCP::ARMCPModifier Modifier);
James Molloy9abb2fa2016-09-26 07:26:24 +0000159 static ARMConstantPoolConstant *Create(const GlobalVariable *GV,
160 const Constant *Initializer);
Bill Wendling67225562011-10-01 06:44:24 +0000161 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
162 ARMCP::ARMCPKind Kind,
163 unsigned char PCAdj);
Bill Wendlingf117a352011-10-01 07:52:37 +0000164 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
165 ARMCP::ARMCPKind Kind,
166 unsigned char PCAdj,
167 ARMCP::ARMCPModifier Modifier,
168 bool AddCurrentAddress);
Bill Wendling396c2112011-10-01 06:40:33 +0000169
170 const GlobalValue *getGV() const;
Bill Wendlingf117a352011-10-01 07:52:37 +0000171 const BlockAddress *getBlockAddress() const;
James Molloy9abb2fa2016-09-26 07:26:24 +0000172 const GlobalVariable *getPromotedGlobal() const {
173 return dyn_cast_or_null<GlobalVariable>(GVar);
174 }
175 const Constant *getPromotedGlobalInit() const {
176 return CVal;
177 }
Bill Wendlingf117a352011-10-01 07:52:37 +0000178
Craig Topper6bc27bf2014-03-10 02:09:33 +0000179 int getExistingMachineCPValue(MachineConstantPool *CP,
180 unsigned Alignment) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000181
182 /// hasSameValue - Return true if this ARM constpool value can share the same
183 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000184 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000185
Craig Topper6bc27bf2014-03-10 02:09:33 +0000186 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling396c2112011-10-01 06:40:33 +0000187
Craig Topper6bc27bf2014-03-10 02:09:33 +0000188 void print(raw_ostream &O) const override;
Bill Wendling396c2112011-10-01 06:40:33 +0000189 static bool classof(const ARMConstantPoolValue *APV) {
James Molloy9abb2fa2016-09-26 07:26:24 +0000190 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA() ||
191 APV->isPromotedGlobal();
Bill Wendling396c2112011-10-01 06:40:33 +0000192 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000193
194 bool equals(const ARMConstantPoolConstant *A) const {
195 return CVal == A->CVal && ARMConstantPoolValue::equals(A);
196 }
Bill Wendling396c2112011-10-01 06:40:33 +0000197};
198
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000199/// ARMConstantPoolSymbol - ARM-specific constantpool values for external
200/// symbols.
201class ARMConstantPoolSymbol : public ARMConstantPoolValue {
Benjamin Kramer9d461102012-12-24 19:23:30 +0000202 const std::string S; // ExtSymbol being loaded.
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000203
Mehdi Amini5b007702016-10-05 01:41:06 +0000204 ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id,
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000205 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
206 bool AddCurrentAddress);
207
208public:
Mehdi Amini5b007702016-10-05 01:41:06 +0000209 static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID,
210 unsigned char PCAdj);
Bill Wendlingc214cb02011-10-01 08:58:29 +0000211
Mehdi Amini5b007702016-10-05 01:41:06 +0000212 StringRef getSymbol() const { return S; }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000213
Craig Topper6bc27bf2014-03-10 02:09:33 +0000214 int getExistingMachineCPValue(MachineConstantPool *CP,
215 unsigned Alignment) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000216
Craig Topper6bc27bf2014-03-10 02:09:33 +0000217 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000218
219 /// hasSameValue - Return true if this ARM constpool value can share the same
220 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000221 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000222
Craig Topper6bc27bf2014-03-10 02:09:33 +0000223 void print(raw_ostream &O) const override;
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000224
225 static bool classof(const ARMConstantPoolValue *ACPV) {
226 return ACPV->isExtSymbol();
227 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000228
229 bool equals(const ARMConstantPoolSymbol *A) const {
230 return S == A->S && ARMConstantPoolValue::equals(A);
231 }
Bill Wendlingd7fa0162011-10-01 08:36:59 +0000232};
233
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000234/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
235/// block.
236class ARMConstantPoolMBB : public ARMConstantPoolValue {
Bill Wendling4a4772f2011-10-01 09:30:42 +0000237 const MachineBasicBlock *MBB; // Machine basic block.
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000238
Bill Wendling4a4772f2011-10-01 09:30:42 +0000239 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000240 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
241 bool AddCurrentAddress);
242
243public:
Bill Wendling4a4772f2011-10-01 09:30:42 +0000244 static ARMConstantPoolMBB *Create(LLVMContext &C,
245 const MachineBasicBlock *mbb,
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000246 unsigned ID, unsigned char PCAdj);
247
248 const MachineBasicBlock *getMBB() const { return MBB; }
249
Craig Topper6bc27bf2014-03-10 02:09:33 +0000250 int getExistingMachineCPValue(MachineConstantPool *CP,
251 unsigned Alignment) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000252
Craig Topper6bc27bf2014-03-10 02:09:33 +0000253 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000254
255 /// hasSameValue - Return true if this ARM constpool value can share the same
256 /// constantpool entry as another ARM constpool value.
Craig Topper6bc27bf2014-03-10 02:09:33 +0000257 bool hasSameValue(ARMConstantPoolValue *ACPV) override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000258
Craig Topper6bc27bf2014-03-10 02:09:33 +0000259 void print(raw_ostream &O) const override;
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000260
261 static bool classof(const ARMConstantPoolValue *ACPV) {
262 return ACPV->isMachineBasicBlock();
263 }
Benjamin Kramer2ef689c2013-09-16 10:17:31 +0000264
265 bool equals(const ARMConstantPoolMBB *A) const {
266 return MBB == A->MBB && ARMConstantPoolValue::equals(A);
267 }
Bill Wendling6dbc9fe2011-10-01 09:19:10 +0000268};
269
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000270} // End llvm namespace
Evan Cheng10043e22007-01-19 07:51:42 +0000271
272#endif