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/ADT/StringRef.h" 17 #include "llvm/CodeGen/MachineBasicBlock.h" 18 #include "llvm/IR/Constant.h" 19 #include "llvm/IR/Constants.h" 20 #include "llvm/IR/GlobalValue.h" 21 #include "llvm/IR/Type.h" 22 #include "llvm/Support/Casting.h" 23 #include "llvm/Support/Compiler.h" 24 #include "llvm/Support/ErrorHandling.h" 25 #include "llvm/Support/raw_ostream.h" 26 27 using namespace llvm; 28 29 //===----------------------------------------------------------------------===// 30 // ARMConstantPoolValue 31 //===----------------------------------------------------------------------===// 32 33 ARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id, 34 ARMCP::ARMCPKind kind, 35 unsigned char PCAdj, 36 ARMCP::ARMCPModifier modifier, 37 bool addCurrentAddress) 38 : MachineConstantPoolValue(Ty), LabelId(id), Kind(kind), 39 PCAdjust(PCAdj), Modifier(modifier), 40 AddCurrentAddress(addCurrentAddress) {} 41 42 ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, unsigned id, 43 ARMCP::ARMCPKind kind, 44 unsigned char PCAdj, 45 ARMCP::ARMCPModifier modifier, 46 bool addCurrentAddress) 47 : MachineConstantPoolValue((Type*)Type::getInt32Ty(C)), 48 LabelId(id), Kind(kind), PCAdjust(PCAdj), Modifier(modifier), 49 AddCurrentAddress(addCurrentAddress) {} 50 51 ARMConstantPoolValue::~ARMConstantPoolValue() = default; 52 53 StringRef ARMConstantPoolValue::getModifierText() const { 54 switch (Modifier) { 55 // FIXME: Are these case sensitive? It'd be nice to lower-case all the 56 // strings if that's legal. 57 case ARMCP::no_modifier: 58 return "none"; 59 case ARMCP::TLSGD: 60 return "tlsgd"; 61 case ARMCP::GOT_PREL: 62 return "GOT_PREL"; 63 case ARMCP::GOTTPOFF: 64 return "gottpoff"; 65 case ARMCP::TPOFF: 66 return "tpoff"; 67 case ARMCP::SBREL: 68 return "SBREL"; 69 case ARMCP::SECREL: 70 return "secrel32"; 71 } 72 llvm_unreachable("Unknown modifier!"); 73 } 74 75 int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, 76 unsigned Alignment) { 77 llvm_unreachable("Shouldn't be calling this directly!"); 78 } 79 80 void 81 ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 82 ID.AddInteger(LabelId); 83 ID.AddInteger(PCAdjust); 84 } 85 86 bool 87 ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) { 88 if (ACPV->Kind == Kind && 89 ACPV->PCAdjust == PCAdjust && 90 ACPV->Modifier == Modifier && 91 ACPV->LabelId == LabelId && 92 ACPV->AddCurrentAddress == AddCurrentAddress) { 93 // Two PC relative constpool entries containing the same GV address or 94 // external symbols. FIXME: What about blockaddress? 95 if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol) 96 return true; 97 } 98 return false; 99 } 100 101 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 102 LLVM_DUMP_METHOD void ARMConstantPoolValue::dump() const { 103 errs() << " " << *this; 104 } 105 #endif 106 107 void ARMConstantPoolValue::print(raw_ostream &O) const { 108 if (Modifier) O << "(" << getModifierText() << ")"; 109 if (PCAdjust != 0) { 110 O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust; 111 if (AddCurrentAddress) O << "-."; 112 O << ")"; 113 } 114 } 115 116 //===----------------------------------------------------------------------===// 117 // ARMConstantPoolConstant 118 //===----------------------------------------------------------------------===// 119 120 ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty, 121 const Constant *C, 122 unsigned ID, 123 ARMCP::ARMCPKind Kind, 124 unsigned char PCAdj, 125 ARMCP::ARMCPModifier Modifier, 126 bool AddCurrentAddress) 127 : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress), 128 CVal(C) {} 129 130 ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C, 131 unsigned ID, 132 ARMCP::ARMCPKind Kind, 133 unsigned char PCAdj, 134 ARMCP::ARMCPModifier Modifier, 135 bool AddCurrentAddress) 136 : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier, 137 AddCurrentAddress), 138 CVal(C) {} 139 140 ARMConstantPoolConstant::ARMConstantPoolConstant(const GlobalVariable *GV, 141 const Constant *C) 142 : ARMConstantPoolValue((Type *)C->getType(), 0, ARMCP::CPPromotedGlobal, 0, 143 ARMCP::no_modifier, false), 144 CVal(C), GVar(GV) {} 145 146 ARMConstantPoolConstant * 147 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) { 148 return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0, 149 ARMCP::no_modifier, false); 150 } 151 152 ARMConstantPoolConstant * 153 ARMConstantPoolConstant::Create(const GlobalVariable *GVar, 154 const Constant *Initializer) { 155 return new ARMConstantPoolConstant(GVar, Initializer); 156 } 157 158 ARMConstantPoolConstant * 159 ARMConstantPoolConstant::Create(const GlobalValue *GV, 160 ARMCP::ARMCPModifier Modifier) { 161 return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()), 162 GV, 0, ARMCP::CPValue, 0, 163 Modifier, false); 164 } 165 166 ARMConstantPoolConstant * 167 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 168 ARMCP::ARMCPKind Kind, unsigned char PCAdj) { 169 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, 170 ARMCP::no_modifier, false); 171 } 172 173 ARMConstantPoolConstant * 174 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 175 ARMCP::ARMCPKind Kind, unsigned char PCAdj, 176 ARMCP::ARMCPModifier Modifier, 177 bool AddCurrentAddress) { 178 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier, 179 AddCurrentAddress); 180 } 181 182 const GlobalValue *ARMConstantPoolConstant::getGV() const { 183 return dyn_cast_or_null<GlobalValue>(CVal); 184 } 185 186 const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const { 187 return dyn_cast_or_null<BlockAddress>(CVal); 188 } 189 190 int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, 191 unsigned Alignment) { 192 return getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment); 193 } 194 195 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { 196 const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV); 197 return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV); 198 } 199 200 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 201 ID.AddPointer(CVal); 202 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 203 } 204 205 void ARMConstantPoolConstant::print(raw_ostream &O) const { 206 O << CVal->getName(); 207 ARMConstantPoolValue::print(O); 208 } 209 210 //===----------------------------------------------------------------------===// 211 // ARMConstantPoolSymbol 212 //===----------------------------------------------------------------------===// 213 214 ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, StringRef s, 215 unsigned id, unsigned char PCAdj, 216 ARMCP::ARMCPModifier Modifier, 217 bool AddCurrentAddress) 218 : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier, 219 AddCurrentAddress), 220 S(s) {} 221 222 ARMConstantPoolSymbol *ARMConstantPoolSymbol::Create(LLVMContext &C, 223 StringRef s, unsigned ID, 224 unsigned char PCAdj) { 225 return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false); 226 } 227 228 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP, 229 unsigned Alignment) { 230 return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment); 231 } 232 233 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) { 234 const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV); 235 return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV); 236 } 237 238 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 239 ID.AddString(S); 240 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 241 } 242 243 void ARMConstantPoolSymbol::print(raw_ostream &O) const { 244 O << S; 245 ARMConstantPoolValue::print(O); 246 } 247 248 //===----------------------------------------------------------------------===// 249 // ARMConstantPoolMBB 250 //===----------------------------------------------------------------------===// 251 252 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C, 253 const MachineBasicBlock *mbb, 254 unsigned id, unsigned char PCAdj, 255 ARMCP::ARMCPModifier Modifier, 256 bool AddCurrentAddress) 257 : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj, 258 Modifier, AddCurrentAddress), 259 MBB(mbb) {} 260 261 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C, 262 const MachineBasicBlock *mbb, 263 unsigned ID, 264 unsigned char PCAdj) { 265 return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false); 266 } 267 268 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP, 269 unsigned Alignment) { 270 return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment); 271 } 272 273 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) { 274 const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV); 275 return ACPMBB && ACPMBB->MBB == MBB && 276 ARMConstantPoolValue::hasSameValue(ACPV); 277 } 278 279 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 280 ID.AddPointer(MBB); 281 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 282 } 283 284 void ARMConstantPoolMBB::print(raw_ostream &O) const { 285 O << "BB#" << MBB->getNumber(); 286 ARMConstantPoolValue::print(O); 287 } 288