1 //===- ARMConstantPoolValue.cpp - ARM constantpool value --------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the ARM specific constantpool value class.
12 //===----------------------------------------------------------------------===//
14 #include "ARMConstantPoolValue.h"
15 #include "llvm/ADT/FoldingSet.h"
16 #include "llvm/Constant.h"
17 #include "llvm/Constants.h"
18 #include "llvm/GlobalValue.h"
19 #include "llvm/Type.h"
20 #include "llvm/CodeGen/MachineBasicBlock.h"
21 #include "llvm/Support/raw_ostream.h"
25 //===----------------------------------------------------------------------===//
26 // ARMConstantPoolValue
27 //===----------------------------------------------------------------------===//
29 ARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id,
30 ARMCP::ARMCPKind kind,
32 ARMCP::ARMCPModifier modifier,
33 bool addCurrentAddress)
34 : MachineConstantPoolValue(Ty), S(NULL), LabelId(id), Kind(kind),
35 PCAdjust(PCAdj), Modifier(modifier),
36 AddCurrentAddress(addCurrentAddress) {}
38 ARMConstantPoolValue::ARMConstantPoolValue(const Constant *cval, unsigned id,
41 ARMCP::ARMCPModifier Modif,
43 : MachineConstantPoolValue((Type*)cval->getType()),
44 CVal(cval), S(NULL), LabelId(id), Kind(K), PCAdjust(PCAdj),
45 Modifier(Modif), AddCurrentAddress(AddCA) {}
47 ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C,
48 const MachineBasicBlock *mbb,
52 ARMCP::ARMCPModifier Modif,
54 : MachineConstantPoolValue((Type*)Type::getInt8PtrTy(C)),
55 CVal(NULL), MBB(mbb), S(NULL), LabelId(id), Kind(K), PCAdjust(PCAdj),
56 Modifier(Modif), AddCurrentAddress(AddCA) {}
58 ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C,
59 const char *s, unsigned id,
61 ARMCP::ARMCPModifier Modif,
63 : MachineConstantPoolValue((Type*)Type::getInt32Ty(C)),
64 CVal(NULL), S(strdup(s)), LabelId(id), Kind(ARMCP::CPExtSymbol),
65 PCAdjust(PCAdj), Modifier(Modif), AddCurrentAddress(AddCA) {}
67 ARMConstantPoolValue::ARMConstantPoolValue(const GlobalValue *gv,
68 ARMCP::ARMCPModifier Modif)
69 : MachineConstantPoolValue((Type*)Type::getInt32Ty(gv->getContext())),
70 CVal(gv), S(NULL), LabelId(0), Kind(ARMCP::CPValue), PCAdjust(0),
71 Modifier(Modif), AddCurrentAddress(false) {}
73 const GlobalValue *ARMConstantPoolValue::getGV() const {
74 return dyn_cast_or_null<GlobalValue>(CVal);
77 const BlockAddress *ARMConstantPoolValue::getBlockAddress() const {
78 return dyn_cast_or_null<BlockAddress>(CVal);
81 const MachineBasicBlock *ARMConstantPoolValue::getMBB() const {
85 const char *ARMConstantPoolValue::getModifierText() const {
87 default: llvm_unreachable("Unknown modifier!");
88 // FIXME: Are these case sensitive? It'd be nice to lower-case all the
89 // strings if that's legal.
90 case ARMCP::no_modifier: return "none";
91 case ARMCP::TLSGD: return "tlsgd";
92 case ARMCP::GOT: return "GOT";
93 case ARMCP::GOTOFF: return "GOTOFF";
94 case ARMCP::GOTTPOFF: return "gottpoff";
95 case ARMCP::TPOFF: return "tpoff";
99 static bool CPV_streq(const char *S1, const char *S2) {
102 if (S1 && S2 && strcmp(S1, S2) == 0)
107 int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
108 unsigned Alignment) {
109 unsigned AlignMask = Alignment - 1;
110 const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
111 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
112 if (Constants[i].isMachineConstantPoolEntry() &&
113 (Constants[i].getAlignment() & AlignMask) == 0) {
114 ARMConstantPoolValue *CPV =
115 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
116 if (CPV->CVal == CVal &&
117 CPV->LabelId == LabelId &&
118 CPV->PCAdjust == PCAdjust &&
119 CPV_streq(CPV->S, S) &&
120 CPV->Modifier == Modifier)
128 ARMConstantPoolValue::~ARMConstantPoolValue() {
133 ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
136 ID.AddInteger(LabelId);
137 ID.AddInteger(PCAdjust);
141 ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) {
142 if (ACPV->Kind == Kind &&
143 ACPV->CVal == CVal &&
144 ACPV->PCAdjust == PCAdjust &&
145 CPV_streq(ACPV->S, S) &&
146 ACPV->Modifier == Modifier) {
147 if (ACPV->LabelId == LabelId)
149 // Two PC relative constpool entries containing the same GV address or
150 // external symbols. FIXME: What about blockaddress?
151 if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol)
157 void ARMConstantPoolValue::dump() const {
158 errs() << " " << *this;
161 void ARMConstantPoolValue::print(raw_ostream &O) const {
163 O << CVal->getName();
168 if (Modifier) O << "(" << getModifierText() << ")";
170 O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust;
171 if (AddCurrentAddress) O << "-.";
176 //===----------------------------------------------------------------------===//
177 // ARMConstantPoolConstant
178 //===----------------------------------------------------------------------===//
180 ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty,
183 ARMCP::ARMCPKind Kind,
185 ARMCP::ARMCPModifier Modifier,
186 bool AddCurrentAddress)
187 : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress),
190 ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C,
192 ARMCP::ARMCPKind Kind,
194 ARMCP::ARMCPModifier Modifier,
195 bool AddCurrentAddress)
196 : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier,
200 ARMConstantPoolConstant *
201 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) {
202 return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0,
203 ARMCP::no_modifier, false);
206 ARMConstantPoolConstant *
207 ARMConstantPoolConstant::Create(const GlobalValue *GV,
208 ARMCP::ARMCPModifier Modifier) {
209 return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()),
210 GV, 0, ARMCP::CPValue, 0,
214 ARMConstantPoolConstant *
215 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
216 ARMCP::ARMCPKind Kind, unsigned char PCAdj) {
217 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj,
218 ARMCP::no_modifier, false);
221 ARMConstantPoolConstant *
222 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID,
223 ARMCP::ARMCPKind Kind, unsigned char PCAdj,
224 ARMCP::ARMCPModifier Modifier,
225 bool AddCurrentAddress) {
226 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier,
230 const GlobalValue *ARMConstantPoolConstant::getGV() const {
231 return dyn_cast_or_null<GlobalValue>(CVal);
234 const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const {
235 return dyn_cast_or_null<BlockAddress>(CVal);
238 int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP,
239 unsigned Alignment) {
240 unsigned AlignMask = Alignment - 1;
241 const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
242 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
243 if (Constants[i].isMachineConstantPoolEntry() &&
244 (Constants[i].getAlignment() & AlignMask) == 0) {
245 ARMConstantPoolValue *CPV =
246 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
247 ARMConstantPoolConstant *APC = dyn_cast<ARMConstantPoolConstant>(CPV);
250 if (APC->getGV() == this->CVal &&
251 APC->getLabelId() == this->getLabelId() &&
252 APC->getPCAdjustment() == this->getPCAdjustment() &&
253 CPV_streq(APC->getSymbol(), this->getSymbol()) &&
254 APC->getModifier() == this->getModifier())
262 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) {
263 const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV);
264 return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV);
267 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
269 ARMConstantPoolValue::addSelectionDAGCSEId(ID);
272 void ARMConstantPoolConstant::print(raw_ostream &O) const {
273 O << CVal->getName();
274 ARMConstantPoolValue::print(O);