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 LLVM_DUMP_METHOD void ARMConstantPoolValue::dump() const { 102 errs() << " " << *this; 103 } 104 105 void ARMConstantPoolValue::print(raw_ostream &O) const { 106 if (Modifier) O << "(" << getModifierText() << ")"; 107 if (PCAdjust != 0) { 108 O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust; 109 if (AddCurrentAddress) O << "-."; 110 O << ")"; 111 } 112 } 113 114 //===----------------------------------------------------------------------===// 115 // ARMConstantPoolConstant 116 //===----------------------------------------------------------------------===// 117 118 ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty, 119 const Constant *C, 120 unsigned ID, 121 ARMCP::ARMCPKind Kind, 122 unsigned char PCAdj, 123 ARMCP::ARMCPModifier Modifier, 124 bool AddCurrentAddress) 125 : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress), 126 CVal(C) {} 127 128 ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C, 129 unsigned ID, 130 ARMCP::ARMCPKind Kind, 131 unsigned char PCAdj, 132 ARMCP::ARMCPModifier Modifier, 133 bool AddCurrentAddress) 134 : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier, 135 AddCurrentAddress), 136 CVal(C) {} 137 138 ARMConstantPoolConstant::ARMConstantPoolConstant(const GlobalVariable *GV, 139 const Constant *C) 140 : ARMConstantPoolValue((Type *)C->getType(), 0, ARMCP::CPPromotedGlobal, 0, 141 ARMCP::no_modifier, false), 142 CVal(C), GVar(GV) {} 143 144 ARMConstantPoolConstant * 145 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) { 146 return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0, 147 ARMCP::no_modifier, false); 148 } 149 150 ARMConstantPoolConstant * 151 ARMConstantPoolConstant::Create(const GlobalVariable *GVar, 152 const Constant *Initializer) { 153 return new ARMConstantPoolConstant(GVar, Initializer); 154 } 155 156 ARMConstantPoolConstant * 157 ARMConstantPoolConstant::Create(const GlobalValue *GV, 158 ARMCP::ARMCPModifier Modifier) { 159 return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()), 160 GV, 0, ARMCP::CPValue, 0, 161 Modifier, false); 162 } 163 164 ARMConstantPoolConstant * 165 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 166 ARMCP::ARMCPKind Kind, unsigned char PCAdj) { 167 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, 168 ARMCP::no_modifier, false); 169 } 170 171 ARMConstantPoolConstant * 172 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 173 ARMCP::ARMCPKind Kind, unsigned char PCAdj, 174 ARMCP::ARMCPModifier Modifier, 175 bool AddCurrentAddress) { 176 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier, 177 AddCurrentAddress); 178 } 179 180 const GlobalValue *ARMConstantPoolConstant::getGV() const { 181 return dyn_cast_or_null<GlobalValue>(CVal); 182 } 183 184 const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const { 185 return dyn_cast_or_null<BlockAddress>(CVal); 186 } 187 188 int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, 189 unsigned Alignment) { 190 return getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment); 191 } 192 193 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { 194 const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV); 195 return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV); 196 } 197 198 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 199 ID.AddPointer(CVal); 200 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 201 } 202 203 void ARMConstantPoolConstant::print(raw_ostream &O) const { 204 O << CVal->getName(); 205 ARMConstantPoolValue::print(O); 206 } 207 208 //===----------------------------------------------------------------------===// 209 // ARMConstantPoolSymbol 210 //===----------------------------------------------------------------------===// 211 212 ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, StringRef s, 213 unsigned id, unsigned char PCAdj, 214 ARMCP::ARMCPModifier Modifier, 215 bool AddCurrentAddress) 216 : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier, 217 AddCurrentAddress), 218 S(s) {} 219 220 ARMConstantPoolSymbol *ARMConstantPoolSymbol::Create(LLVMContext &C, 221 StringRef s, unsigned ID, 222 unsigned char PCAdj) { 223 return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false); 224 } 225 226 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP, 227 unsigned Alignment) { 228 return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment); 229 } 230 231 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) { 232 const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV); 233 return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV); 234 } 235 236 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 237 ID.AddString(S); 238 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 239 } 240 241 void ARMConstantPoolSymbol::print(raw_ostream &O) const { 242 O << S; 243 ARMConstantPoolValue::print(O); 244 } 245 246 //===----------------------------------------------------------------------===// 247 // ARMConstantPoolMBB 248 //===----------------------------------------------------------------------===// 249 250 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C, 251 const MachineBasicBlock *mbb, 252 unsigned id, unsigned char PCAdj, 253 ARMCP::ARMCPModifier Modifier, 254 bool AddCurrentAddress) 255 : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj, 256 Modifier, AddCurrentAddress), 257 MBB(mbb) {} 258 259 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C, 260 const MachineBasicBlock *mbb, 261 unsigned ID, 262 unsigned char PCAdj) { 263 return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false); 264 } 265 266 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP, 267 unsigned Alignment) { 268 return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment); 269 } 270 271 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) { 272 const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV); 273 return ACPMBB && ACPMBB->MBB == MBB && 274 ARMConstantPoolValue::hasSameValue(ACPV); 275 } 276 277 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 278 ID.AddPointer(MBB); 279 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 280 } 281 282 void ARMConstantPoolMBB::print(raw_ostream &O) const { 283 O << "BB#" << MBB->getNumber(); 284 ARMConstantPoolValue::print(O); 285 } 286