1 //===- ARMConstantPoolValue.cpp - ARM constantpool value --------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 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" 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" 22 #include <cstdlib> 23 using namespace llvm; 24 25 //===----------------------------------------------------------------------===// 26 // ARMConstantPoolValue 27 //===----------------------------------------------------------------------===// 28 29 ARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id, 30 ARMCP::ARMCPKind kind, 31 unsigned char PCAdj, 32 ARMCP::ARMCPModifier modifier, 33 bool addCurrentAddress) 34 : MachineConstantPoolValue(Ty), LabelId(id), Kind(kind), 35 PCAdjust(PCAdj), Modifier(modifier), 36 AddCurrentAddress(addCurrentAddress) {} 37 38 ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, unsigned id, 39 ARMCP::ARMCPKind kind, 40 unsigned char PCAdj, 41 ARMCP::ARMCPModifier modifier, 42 bool addCurrentAddress) 43 : MachineConstantPoolValue((Type*)Type::getInt32Ty(C)), 44 LabelId(id), Kind(kind), PCAdjust(PCAdj), Modifier(modifier), 45 AddCurrentAddress(addCurrentAddress) {} 46 47 ARMConstantPoolValue::~ARMConstantPoolValue() {} 48 49 const char *ARMConstantPoolValue::getModifierText() const { 50 switch (Modifier) { 51 default: llvm_unreachable("Unknown modifier!"); 52 // FIXME: Are these case sensitive? It'd be nice to lower-case all the 53 // strings if that's legal. 54 case ARMCP::no_modifier: return "none"; 55 case ARMCP::TLSGD: return "tlsgd"; 56 case ARMCP::GOT: return "GOT"; 57 case ARMCP::GOTOFF: return "GOTOFF"; 58 case ARMCP::GOTTPOFF: return "gottpoff"; 59 case ARMCP::TPOFF: return "tpoff"; 60 } 61 } 62 63 int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, 64 unsigned Alignment) { 65 assert(false && "Shouldn't be calling this directly!"); 66 return -1; 67 } 68 69 void 70 ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 71 ID.AddInteger(LabelId); 72 ID.AddInteger(PCAdjust); 73 } 74 75 bool 76 ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) { 77 if (ACPV->Kind == Kind && 78 ACPV->PCAdjust == PCAdjust && 79 ACPV->Modifier == Modifier) { 80 if (ACPV->LabelId == LabelId) 81 return true; 82 // Two PC relative constpool entries containing the same GV address or 83 // external symbols. FIXME: What about blockaddress? 84 if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol) 85 return true; 86 } 87 return false; 88 } 89 90 void ARMConstantPoolValue::dump() const { 91 errs() << " " << *this; 92 } 93 94 void ARMConstantPoolValue::print(raw_ostream &O) const { 95 if (Modifier) O << "(" << getModifierText() << ")"; 96 if (PCAdjust != 0) { 97 O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust; 98 if (AddCurrentAddress) O << "-."; 99 O << ")"; 100 } 101 } 102 103 //===----------------------------------------------------------------------===// 104 // ARMConstantPoolConstant 105 //===----------------------------------------------------------------------===// 106 107 ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty, 108 const Constant *C, 109 unsigned ID, 110 ARMCP::ARMCPKind Kind, 111 unsigned char PCAdj, 112 ARMCP::ARMCPModifier Modifier, 113 bool AddCurrentAddress) 114 : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress), 115 CVal(C) {} 116 117 ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C, 118 unsigned ID, 119 ARMCP::ARMCPKind Kind, 120 unsigned char PCAdj, 121 ARMCP::ARMCPModifier Modifier, 122 bool AddCurrentAddress) 123 : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier, 124 AddCurrentAddress), 125 CVal(C) {} 126 127 ARMConstantPoolConstant * 128 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) { 129 return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0, 130 ARMCP::no_modifier, false); 131 } 132 133 ARMConstantPoolConstant * 134 ARMConstantPoolConstant::Create(const GlobalValue *GV, 135 ARMCP::ARMCPModifier Modifier) { 136 return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()), 137 GV, 0, ARMCP::CPValue, 0, 138 Modifier, false); 139 } 140 141 ARMConstantPoolConstant * 142 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 143 ARMCP::ARMCPKind Kind, unsigned char PCAdj) { 144 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, 145 ARMCP::no_modifier, false); 146 } 147 148 ARMConstantPoolConstant * 149 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 150 ARMCP::ARMCPKind Kind, unsigned char PCAdj, 151 ARMCP::ARMCPModifier Modifier, 152 bool AddCurrentAddress) { 153 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier, 154 AddCurrentAddress); 155 } 156 157 const GlobalValue *ARMConstantPoolConstant::getGV() const { 158 return dyn_cast_or_null<GlobalValue>(CVal); 159 } 160 161 const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const { 162 return dyn_cast_or_null<BlockAddress>(CVal); 163 } 164 165 int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, 166 unsigned Alignment) { 167 unsigned AlignMask = Alignment - 1; 168 const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants(); 169 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 170 if (Constants[i].isMachineConstantPoolEntry() && 171 (Constants[i].getAlignment() & AlignMask) == 0) { 172 ARMConstantPoolValue *CPV = 173 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; 174 ARMConstantPoolConstant *APC = dyn_cast<ARMConstantPoolConstant>(CPV); 175 if (!APC) continue; 176 if (APC->CVal == CVal && equals(APC)) 177 return i; 178 } 179 } 180 181 return -1; 182 } 183 184 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { 185 const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV); 186 return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV); 187 } 188 189 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 190 ID.AddPointer(CVal); 191 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 192 } 193 194 void ARMConstantPoolConstant::print(raw_ostream &O) const { 195 O << CVal->getName(); 196 ARMConstantPoolValue::print(O); 197 } 198 199 //===----------------------------------------------------------------------===// 200 // ARMConstantPoolSymbol 201 //===----------------------------------------------------------------------===// 202 203 ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s, 204 unsigned id, 205 unsigned char PCAdj, 206 ARMCP::ARMCPModifier Modifier, 207 bool AddCurrentAddress) 208 : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier, 209 AddCurrentAddress), 210 S(strdup(s)) {} 211 212 ARMConstantPoolSymbol::~ARMConstantPoolSymbol() { 213 free((void*)S); 214 } 215 216 ARMConstantPoolSymbol * 217 ARMConstantPoolSymbol::Create(LLVMContext &C, const char *s, 218 unsigned ID, unsigned char PCAdj) { 219 return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false); 220 } 221 222 static bool CPV_streq(const char *S1, const char *S2) { 223 if (S1 == S2) 224 return true; 225 if (S1 && S2 && strcmp(S1, S2) == 0) 226 return true; 227 return false; 228 } 229 230 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP, 231 unsigned Alignment) { 232 unsigned AlignMask = Alignment - 1; 233 const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants(); 234 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 235 if (Constants[i].isMachineConstantPoolEntry() && 236 (Constants[i].getAlignment() & AlignMask) == 0) { 237 ARMConstantPoolValue *CPV = 238 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; 239 ARMConstantPoolSymbol *APS = dyn_cast<ARMConstantPoolSymbol>(CPV); 240 if (!APS) continue; 241 242 if (CPV_streq(APS->S, S) && equals(APS)) 243 return i; 244 } 245 } 246 247 return -1; 248 } 249 250 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) { 251 const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV); 252 return ACPS && CPV_streq(ACPS->S, S) && 253 ARMConstantPoolValue::hasSameValue(ACPV); 254 } 255 256 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 257 ID.AddPointer(S); 258 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 259 } 260 261 void ARMConstantPoolSymbol::print(raw_ostream &O) const { 262 O << S; 263 ARMConstantPoolValue::print(O); 264 } 265 266 //===----------------------------------------------------------------------===// 267 // ARMConstantPoolMBB 268 //===----------------------------------------------------------------------===// 269 270 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C, 271 const MachineBasicBlock *mbb, 272 unsigned id, unsigned char PCAdj, 273 ARMCP::ARMCPModifier Modifier, 274 bool AddCurrentAddress) 275 : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj, 276 Modifier, AddCurrentAddress), 277 MBB(mbb) {} 278 279 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C, 280 const MachineBasicBlock *mbb, 281 unsigned ID, 282 unsigned char PCAdj) { 283 return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false); 284 } 285 286 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP, 287 unsigned Alignment) { 288 unsigned AlignMask = Alignment - 1; 289 const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants(); 290 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 291 if (Constants[i].isMachineConstantPoolEntry() && 292 (Constants[i].getAlignment() & AlignMask) == 0) { 293 ARMConstantPoolValue *CPV = 294 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; 295 ARMConstantPoolMBB *APMBB = dyn_cast<ARMConstantPoolMBB>(CPV); 296 if (!APMBB) continue; 297 298 if (APMBB->MBB == MBB && equals(APMBB)) 299 return i; 300 } 301 } 302 303 return -1; 304 } 305 306 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) { 307 const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV); 308 return ACPMBB && ACPMBB->MBB == MBB && 309 ARMConstantPoolValue::hasSameValue(ACPV); 310 } 311 312 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 313 ID.AddPointer(MBB); 314 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 315 } 316 317 void ARMConstantPoolMBB::print(raw_ostream &O) const { 318 ARMConstantPoolValue::print(O); 319 } 320