blob: 1061c6a0b23f93eedbd04288fac1db72fe10dc4f [file] [log] [blame]
Evan Chenga8e29892007-01-19 07:51:42 +00001//===- ARMConstantPoolValue.cpp - ARM constantpool value --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-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 Chenga8e29892007-01-19 07:51:42 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the ARM specific constantpool value class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARMConstantPoolValue.h"
15#include "llvm/ADT/FoldingSet.h"
Bob Wilson28989a82009-11-02 16:59:06 +000016#include "llvm/Constant.h"
17#include "llvm/Constants.h"
Evan Chenga8e29892007-01-19 07:51:42 +000018#include "llvm/GlobalValue.h"
Evan Chengc60e76d2007-01-30 20:37:08 +000019#include "llvm/Type.h"
Bill Wendling4dd9b092011-09-29 23:48:44 +000020#include "llvm/CodeGen/MachineBasicBlock.h"
Chris Lattner944fac72008-08-23 22:23:09 +000021#include "llvm/Support/raw_ostream.h"
Jim Grosbachf1287872009-08-11 15:26:27 +000022#include <cstdlib>
Evan Chenga8e29892007-01-19 07:51:42 +000023using namespace llvm;
24
Bill Wendlingf2b76aa2011-10-01 06:40:33 +000025//===----------------------------------------------------------------------===//
26// ARMConstantPoolValue
27//===----------------------------------------------------------------------===//
28
29ARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id,
30 ARMCP::ARMCPKind kind,
31 unsigned char PCAdj,
32 ARMCP::ARMCPModifier modifier,
33 bool addCurrentAddress)
Bill Wendling5bb77992011-10-01 08:00:54 +000034 : MachineConstantPoolValue(Ty), MBB(NULL), S(NULL), LabelId(id), Kind(kind),
Bill Wendling3e944e32011-10-01 07:52:37 +000035 PCAdjust(PCAdj), Modifier(modifier),
36 AddCurrentAddress(addCurrentAddress) {}
Bill Wendlingf2b76aa2011-10-01 06:40:33 +000037
Owen Anderson1d0be152009-08-13 21:58:54 +000038ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C,
Bill Wendling4dd9b092011-09-29 23:48:44 +000039 const MachineBasicBlock *mbb,
40 unsigned id,
41 ARMCP::ARMCPKind K,
42 unsigned char PCAdj,
43 ARMCP::ARMCPModifier Modif,
44 bool AddCA)
45 : MachineConstantPoolValue((Type*)Type::getInt8PtrTy(C)),
Bill Wendling3f4e4592011-10-01 08:02:05 +000046 MBB(mbb), S(NULL), LabelId(id), Kind(K), PCAdjust(PCAdj),
Bill Wendling4dd9b092011-09-29 23:48:44 +000047 Modifier(Modif), AddCurrentAddress(AddCA) {}
48
49ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C,
Owen Anderson1d0be152009-08-13 21:58:54 +000050 const char *s, unsigned id,
Lauro Ramos Venancio0ae4a332007-04-22 00:04:12 +000051 unsigned char PCAdj,
Jim Grosbach3a2429a2010-11-09 21:36:17 +000052 ARMCP::ARMCPModifier Modif,
Lauro Ramos Venancio64f4fa52007-04-27 13:54:47 +000053 bool AddCA)
Chris Lattnerdb125cf2011-07-18 04:54:35 +000054 : MachineConstantPoolValue((Type*)Type::getInt32Ty(C)),
Bill Wendling3f4e4592011-10-01 08:02:05 +000055 S(strdup(s)), LabelId(id), Kind(ARMCP::CPExtSymbol),
Bob Wilson28989a82009-11-02 16:59:06 +000056 PCAdjust(PCAdj), Modifier(Modif), AddCurrentAddress(AddCA) {}
Lauro Ramos Venancio0ae4a332007-04-22 00:04:12 +000057
Bill Wendling4dd9b092011-09-29 23:48:44 +000058const MachineBasicBlock *ARMConstantPoolValue::getMBB() const {
59 return MBB;
60}
61
Bill Wendlingd98f8382011-09-30 18:42:06 +000062const char *ARMConstantPoolValue::getModifierText() const {
63 switch (Modifier) {
64 default: llvm_unreachable("Unknown modifier!");
65 // FIXME: Are these case sensitive? It'd be nice to lower-case all the
66 // strings if that's legal.
67 case ARMCP::no_modifier: return "none";
68 case ARMCP::TLSGD: return "tlsgd";
69 case ARMCP::GOT: return "GOT";
70 case ARMCP::GOTOFF: return "GOTOFF";
71 case ARMCP::GOTTPOFF: return "gottpoff";
72 case ARMCP::TPOFF: return "tpoff";
73 }
74}
75
Evan Chengde0e11c2010-09-24 05:18:35 +000076static bool CPV_streq(const char *S1, const char *S2) {
77 if (S1 == S2)
78 return true;
79 if (S1 && S2 && strcmp(S1, S2) == 0)
80 return true;
81 return false;
82}
83
Evan Chenga8e29892007-01-19 07:51:42 +000084int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
85 unsigned Alignment) {
Evan Cheng1606e8e2009-03-13 07:51:59 +000086 unsigned AlignMask = Alignment - 1;
Evan Chenga8e29892007-01-19 07:51:42 +000087 const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
88 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
89 if (Constants[i].isMachineConstantPoolEntry() &&
Evan Cheng1606e8e2009-03-13 07:51:59 +000090 (Constants[i].getAlignment() & AlignMask) == 0) {
Evan Chenga8e29892007-01-19 07:51:42 +000091 ARMConstantPoolValue *CPV =
92 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
Bill Wendling5bb77992011-10-01 08:00:54 +000093 if (CPV->LabelId == LabelId &&
Evan Cheng78e5c112009-11-07 03:52:02 +000094 CPV->PCAdjust == PCAdjust &&
Evan Chengde0e11c2010-09-24 05:18:35 +000095 CPV_streq(CPV->S, S) &&
Jim Grosbach3a2429a2010-11-09 21:36:17 +000096 CPV->Modifier == Modifier)
Evan Chenga8e29892007-01-19 07:51:42 +000097 return i;
98 }
99 }
100
101 return -1;
102}
103
Benjamin Kramer327365e2009-08-11 16:03:08 +0000104ARMConstantPoolValue::~ARMConstantPoolValue() {
Jim Grosbachf1287872009-08-11 15:26:27 +0000105 free((void*)S);
106}
107
Evan Chenga8e29892007-01-19 07:51:42 +0000108void
Jim Grosbach5405d582011-09-27 20:59:33 +0000109ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
Evan Chengc60e76d2007-01-30 20:37:08 +0000110 ID.AddPointer(S);
Evan Chenga8e29892007-01-19 07:51:42 +0000111 ID.AddInteger(LabelId);
Evan Chenga8e29892007-01-19 07:51:42 +0000112 ID.AddInteger(PCAdjust);
113}
114
Evan Cheng78e5c112009-11-07 03:52:02 +0000115bool
116ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
117 if (ACPV->Kind == Kind &&
Evan Cheng78e5c112009-11-07 03:52:02 +0000118 ACPV->PCAdjust == PCAdjust &&
Evan Chengde0e11c2010-09-24 05:18:35 +0000119 CPV_streq(ACPV->S, S) &&
Jim Grosbach3a2429a2010-11-09 21:36:17 +0000120 ACPV->Modifier == Modifier) {
Evan Cheng78e5c112009-11-07 03:52:02 +0000121 if (ACPV->LabelId == LabelId)
122 return true;
123 // Two PC relative constpool entries containing the same GV address or
124 // external symbols. FIXME: What about blockaddress?
125 if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
126 return true;
127 }
128 return false;
129}
130
Evan Cheng5be59ea2008-10-29 23:55:17 +0000131void ARMConstantPoolValue::dump() const {
Chris Lattner705e07f2009-08-23 03:41:05 +0000132 errs() << " " << *this;
Evan Cheng5be59ea2008-10-29 23:55:17 +0000133}
134
Chris Lattner944fac72008-08-23 22:23:09 +0000135void ARMConstantPoolValue::print(raw_ostream &O) const {
Bill Wendling3f4e4592011-10-01 08:02:05 +0000136 if (MBB)
Bill Wendling4dd9b092011-09-29 23:48:44 +0000137 O << "";
Evan Chengc60e76d2007-01-30 20:37:08 +0000138 else
139 O << S;
Jim Grosbach3a2429a2010-11-09 21:36:17 +0000140 if (Modifier) O << "(" << getModifierText() << ")";
Lauro Ramos Venancio64f4fa52007-04-27 13:54:47 +0000141 if (PCAdjust != 0) {
Evan Cheng25e04782008-11-04 00:50:32 +0000142 O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
143 if (AddCurrentAddress) O << "-.";
Lauro Ramos Venancio64f4fa52007-04-27 13:54:47 +0000144 O << ")";
145 }
Evan Chenga8e29892007-01-19 07:51:42 +0000146}
Bill Wendlingf2b76aa2011-10-01 06:40:33 +0000147
148//===----------------------------------------------------------------------===//
149// ARMConstantPoolConstant
150//===----------------------------------------------------------------------===//
151
Bill Wendling3e944e32011-10-01 07:52:37 +0000152ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty,
153 const Constant *C,
154 unsigned ID,
155 ARMCP::ARMCPKind Kind,
156 unsigned char PCAdj,
157 ARMCP::ARMCPModifier Modifier,
158 bool AddCurrentAddress)
159 : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress),
160 CVal(C) {}
161
Bill Wendlingf2b76aa2011-10-01 06:40:33 +0000162ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C,
163 unsigned ID,
164 ARMCP::ARMCPKind Kind,
165 unsigned char PCAdj,
166 ARMCP::ARMCPModifier Modifier,
167 bool AddCurrentAddress)
168 : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier,
169 AddCurrentAddress),
170 CVal(C) {}
171
172ARMConstantPoolConstant *
173ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) {
174 return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0,
175 ARMCP::no_modifier, false);
176}
177
Bill Wendling029e93882011-10-01 06:44:24 +0000178ARMConstantPoolConstant *
Bill Wendling3e944e32011-10-01 07:52:37 +0000179ARMConstantPoolConstant::Create(const GlobalValue *GV,
180 ARMCP::ARMCPModifier Modifier) {
181 return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()),
182 GV, 0, ARMCP::CPValue, 0,
183 Modifier, false);
184}
185
186ARMConstantPoolConstant *
Bill Wendling029e93882011-10-01 06:44:24 +0000187ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
188 ARMCP::ARMCPKind Kind, unsigned char PCAdj) {
189 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj,
190 ARMCP::no_modifier, false);
191}
192
Bill Wendling3e944e32011-10-01 07:52:37 +0000193ARMConstantPoolConstant *
194ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
195 ARMCP::ARMCPKind Kind, unsigned char PCAdj,
196 ARMCP::ARMCPModifier Modifier,
197 bool AddCurrentAddress) {
198 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier,
199 AddCurrentAddress);
200}
201
Bill Wendlingf2b76aa2011-10-01 06:40:33 +0000202const GlobalValue *ARMConstantPoolConstant::getGV() const {
Bill Wendling3e944e32011-10-01 07:52:37 +0000203 return dyn_cast_or_null<GlobalValue>(CVal);
204}
205
206const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const {
207 return dyn_cast_or_null<BlockAddress>(CVal);
208}
209
210int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP,
211 unsigned Alignment) {
212 unsigned AlignMask = Alignment - 1;
213 const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
214 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
215 if (Constants[i].isMachineConstantPoolEntry() &&
216 (Constants[i].getAlignment() & AlignMask) == 0) {
217 ARMConstantPoolValue *CPV =
218 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
219 ARMConstantPoolConstant *APC = dyn_cast<ARMConstantPoolConstant>(CPV);
220 if (!APC) continue;
221
222 if (APC->getGV() == this->CVal &&
223 APC->getLabelId() == this->getLabelId() &&
224 APC->getPCAdjustment() == this->getPCAdjustment() &&
225 CPV_streq(APC->getSymbol(), this->getSymbol()) &&
226 APC->getModifier() == this->getModifier())
227 return i;
228 }
229 }
230
231 return -1;
Bill Wendlingf2b76aa2011-10-01 06:40:33 +0000232}
233
234bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
235 const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
Bill Wendling3e944e32011-10-01 07:52:37 +0000236 return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
Bill Wendlingf2b76aa2011-10-01 06:40:33 +0000237}
238
239void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
240 ID.AddPointer(CVal);
241 ARMConstantPoolValue::addSelectionDAGCSEId(ID);
242}
243
244void ARMConstantPoolConstant::print(raw_ostream &O) const {
245 O << CVal->getName();
246 ARMConstantPoolValue::print(O);
247}