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