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