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