1 //===- ARMConstantPoolValue.cpp - ARM constantpool value ------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the ARM specific constantpool value class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "ARMConstantPoolValue.h" 14 #include "llvm/ADT/FoldingSet.h" 15 #include "llvm/CodeGen/MachineBasicBlock.h" 16 #include "llvm/Config/llvm-config.h" 17 #include "llvm/IR/Constant.h" 18 #include "llvm/IR/Constants.h" 19 #include "llvm/IR/GlobalValue.h" 20 #include "llvm/IR/GlobalVariable.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 Align 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), CVal(C) { 144 GVars.insert(GV); 145 } 146 147 ARMConstantPoolConstant * 148 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) { 149 return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0, 150 ARMCP::no_modifier, false); 151 } 152 153 ARMConstantPoolConstant * 154 ARMConstantPoolConstant::Create(const GlobalVariable *GVar, 155 const Constant *Initializer) { 156 return new ARMConstantPoolConstant(GVar, Initializer); 157 } 158 159 ARMConstantPoolConstant * 160 ARMConstantPoolConstant::Create(const GlobalValue *GV, 161 ARMCP::ARMCPModifier Modifier) { 162 return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()), 163 GV, 0, ARMCP::CPValue, 0, 164 Modifier, false); 165 } 166 167 ARMConstantPoolConstant * 168 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 169 ARMCP::ARMCPKind Kind, unsigned char PCAdj) { 170 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, 171 ARMCP::no_modifier, false); 172 } 173 174 ARMConstantPoolConstant * 175 ARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 176 ARMCP::ARMCPKind Kind, unsigned char PCAdj, 177 ARMCP::ARMCPModifier Modifier, 178 bool AddCurrentAddress) { 179 return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier, 180 AddCurrentAddress); 181 } 182 183 const GlobalValue *ARMConstantPoolConstant::getGV() const { 184 return dyn_cast_or_null<GlobalValue>(CVal); 185 } 186 187 const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const { 188 return dyn_cast_or_null<BlockAddress>(CVal); 189 } 190 191 int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, 192 Align Alignment) { 193 int index = 194 getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment); 195 if (index != -1) { 196 auto *CPV = static_cast<ARMConstantPoolValue*>( 197 CP->getConstants()[index].Val.MachineCPVal); 198 auto *Constant = cast<ARMConstantPoolConstant>(CPV); 199 Constant->GVars.insert(GVars.begin(), GVars.end()); 200 } 201 return index; 202 } 203 204 bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { 205 const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV); 206 return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV); 207 } 208 209 void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 210 ID.AddPointer(CVal); 211 for (const auto *GV : GVars) 212 ID.AddPointer(GV); 213 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 214 } 215 216 void ARMConstantPoolConstant::print(raw_ostream &O) const { 217 O << CVal->getName(); 218 ARMConstantPoolValue::print(O); 219 } 220 221 //===----------------------------------------------------------------------===// 222 // ARMConstantPoolSymbol 223 //===----------------------------------------------------------------------===// 224 225 ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, StringRef s, 226 unsigned id, unsigned char PCAdj, 227 ARMCP::ARMCPModifier Modifier, 228 bool AddCurrentAddress) 229 : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier, 230 AddCurrentAddress), 231 S(std::string(s)) {} 232 233 ARMConstantPoolSymbol *ARMConstantPoolSymbol::Create(LLVMContext &C, 234 StringRef s, unsigned ID, 235 unsigned char PCAdj) { 236 return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false); 237 } 238 239 int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP, 240 Align Alignment) { 241 return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment); 242 } 243 244 bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) { 245 const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV); 246 return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV); 247 } 248 249 void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 250 ID.AddString(S); 251 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 252 } 253 254 void ARMConstantPoolSymbol::print(raw_ostream &O) const { 255 O << S; 256 ARMConstantPoolValue::print(O); 257 } 258 259 //===----------------------------------------------------------------------===// 260 // ARMConstantPoolMBB 261 //===----------------------------------------------------------------------===// 262 263 ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C, 264 const MachineBasicBlock *mbb, 265 unsigned id, unsigned char PCAdj, 266 ARMCP::ARMCPModifier Modifier, 267 bool AddCurrentAddress) 268 : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj, 269 Modifier, AddCurrentAddress), 270 MBB(mbb) {} 271 272 ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C, 273 const MachineBasicBlock *mbb, 274 unsigned ID, 275 unsigned char PCAdj) { 276 return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false); 277 } 278 279 int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP, 280 Align Alignment) { 281 return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment); 282 } 283 284 bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) { 285 const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV); 286 return ACPMBB && ACPMBB->MBB == MBB && 287 ARMConstantPoolValue::hasSameValue(ACPV); 288 } 289 290 void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 291 ID.AddPointer(MBB); 292 ARMConstantPoolValue::addSelectionDAGCSEId(ID); 293 } 294 295 void ARMConstantPoolMBB::print(raw_ostream &O) const { 296 O << printMBBReference(*MBB); 297 ARMConstantPoolValue::print(O); 298 } 299