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