1327952Sdim//===- ARMConstantPoolValue.cpp - ARM constantpool value ------------------===// 2193323Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193323Sed// 7193323Sed//===----------------------------------------------------------------------===// 8193323Sed// 9193323Sed// This file implements the ARM specific constantpool value class. 10193323Sed// 11193323Sed//===----------------------------------------------------------------------===// 12193323Sed 13193323Sed#include "ARMConstantPoolValue.h" 14193323Sed#include "llvm/ADT/FoldingSet.h" 15226633Sdim#include "llvm/CodeGen/MachineBasicBlock.h" 16341825Sdim#include "llvm/Config/llvm-config.h" 17249423Sdim#include "llvm/IR/Constant.h" 18249423Sdim#include "llvm/IR/Constants.h" 19249423Sdim#include "llvm/IR/GlobalValue.h" 20360784Sdim#include "llvm/IR/GlobalVariable.h" 21249423Sdim#include "llvm/IR/Type.h" 22321369Sdim#include "llvm/Support/Casting.h" 23321369Sdim#include "llvm/Support/Compiler.h" 24321369Sdim#include "llvm/Support/ErrorHandling.h" 25193323Sed#include "llvm/Support/raw_ostream.h" 26321369Sdim 27193323Sedusing namespace llvm; 28193323Sed 29226633Sdim//===----------------------------------------------------------------------===// 30226633Sdim// ARMConstantPoolValue 31226633Sdim//===----------------------------------------------------------------------===// 32226633Sdim 33226633SdimARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id, 34226633Sdim ARMCP::ARMCPKind kind, 35193323Sed unsigned char PCAdj, 36226633Sdim ARMCP::ARMCPModifier modifier, 37226633Sdim bool addCurrentAddress) 38226633Sdim : MachineConstantPoolValue(Ty), LabelId(id), Kind(kind), 39226633Sdim PCAdjust(PCAdj), Modifier(modifier), 40226633Sdim AddCurrentAddress(addCurrentAddress) {} 41193323Sed 42226633SdimARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, unsigned id, 43226633Sdim ARMCP::ARMCPKind kind, 44193323Sed unsigned char PCAdj, 45226633Sdim ARMCP::ARMCPModifier modifier, 46226633Sdim bool addCurrentAddress) 47226633Sdim : MachineConstantPoolValue((Type*)Type::getInt32Ty(C)), 48226633Sdim LabelId(id), Kind(kind), PCAdjust(PCAdj), Modifier(modifier), 49226633Sdim AddCurrentAddress(addCurrentAddress) {} 50193323Sed 51321369SdimARMConstantPoolValue::~ARMConstantPoolValue() = default; 52193323Sed 53314564SdimStringRef ARMConstantPoolValue::getModifierText() const { 54226633Sdim switch (Modifier) { 55226633Sdim // FIXME: Are these case sensitive? It'd be nice to lower-case all the 56226633Sdim // strings if that's legal. 57309124Sdim case ARMCP::no_modifier: 58309124Sdim return "none"; 59309124Sdim case ARMCP::TLSGD: 60309124Sdim return "tlsgd"; 61309124Sdim case ARMCP::GOT_PREL: 62309124Sdim return "GOT_PREL"; 63309124Sdim case ARMCP::GOTTPOFF: 64309124Sdim return "gottpoff"; 65309124Sdim case ARMCP::TPOFF: 66309124Sdim return "tpoff"; 67314564Sdim case ARMCP::SBREL: 68314564Sdim return "SBREL"; 69309124Sdim case ARMCP::SECREL: 70309124Sdim return "secrel32"; 71226633Sdim } 72234353Sdim llvm_unreachable("Unknown modifier!"); 73226633Sdim} 74226633Sdim 75226633Sdimint ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, 76226633Sdim unsigned Alignment) { 77234353Sdim llvm_unreachable("Shouldn't be calling this directly!"); 78226633Sdim} 79226633Sdim 80226633Sdimvoid 81226633SdimARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 82226633Sdim ID.AddInteger(LabelId); 83226633Sdim ID.AddInteger(PCAdjust); 84226633Sdim} 85226633Sdim 86226633Sdimbool 87226633SdimARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) { 88226633Sdim if (ACPV->Kind == Kind && 89226633Sdim ACPV->PCAdjust == PCAdjust && 90309124Sdim ACPV->Modifier == Modifier && 91309124Sdim ACPV->LabelId == LabelId && 92309124Sdim ACPV->AddCurrentAddress == AddCurrentAddress) { 93226633Sdim // Two PC relative constpool entries containing the same GV address or 94226633Sdim // external symbols. FIXME: What about blockaddress? 95226633Sdim if (Kind == ARMCP::CPValue || Kind == ARMCP::CPExtSymbol) 96226633Sdim return true; 97226633Sdim } 98226633Sdim return false; 99226633Sdim} 100226633Sdim 101321369Sdim#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 102309124SdimLLVM_DUMP_METHOD void ARMConstantPoolValue::dump() const { 103226633Sdim errs() << " " << *this; 104226633Sdim} 105321369Sdim#endif 106226633Sdim 107226633Sdimvoid ARMConstantPoolValue::print(raw_ostream &O) const { 108226633Sdim if (Modifier) O << "(" << getModifierText() << ")"; 109226633Sdim if (PCAdjust != 0) { 110226633Sdim O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust; 111226633Sdim if (AddCurrentAddress) O << "-."; 112226633Sdim O << ")"; 113226633Sdim } 114226633Sdim} 115226633Sdim 116226633Sdim//===----------------------------------------------------------------------===// 117226633Sdim// ARMConstantPoolConstant 118226633Sdim//===----------------------------------------------------------------------===// 119226633Sdim 120226633SdimARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty, 121226633Sdim const Constant *C, 122226633Sdim unsigned ID, 123226633Sdim ARMCP::ARMCPKind Kind, 124226633Sdim unsigned char PCAdj, 125226633Sdim ARMCP::ARMCPModifier Modifier, 126226633Sdim bool AddCurrentAddress) 127226633Sdim : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress), 128226633Sdim CVal(C) {} 129226633Sdim 130226633SdimARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C, 131226633Sdim unsigned ID, 132226633Sdim ARMCP::ARMCPKind Kind, 133226633Sdim unsigned char PCAdj, 134226633Sdim ARMCP::ARMCPModifier Modifier, 135226633Sdim bool AddCurrentAddress) 136226633Sdim : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier, 137226633Sdim AddCurrentAddress), 138226633Sdim CVal(C) {} 139226633Sdim 140314564SdimARMConstantPoolConstant::ARMConstantPoolConstant(const GlobalVariable *GV, 141314564Sdim const Constant *C) 142314564Sdim : ARMConstantPoolValue((Type *)C->getType(), 0, ARMCP::CPPromotedGlobal, 0, 143327952Sdim ARMCP::no_modifier, false), CVal(C) { 144327952Sdim GVars.insert(GV); 145327952Sdim} 146314564Sdim 147226633SdimARMConstantPoolConstant * 148226633SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID) { 149226633Sdim return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0, 150226633Sdim ARMCP::no_modifier, false); 151226633Sdim} 152226633Sdim 153226633SdimARMConstantPoolConstant * 154314564SdimARMConstantPoolConstant::Create(const GlobalVariable *GVar, 155314564Sdim const Constant *Initializer) { 156314564Sdim return new ARMConstantPoolConstant(GVar, Initializer); 157314564Sdim} 158314564Sdim 159314564SdimARMConstantPoolConstant * 160226633SdimARMConstantPoolConstant::Create(const GlobalValue *GV, 161226633Sdim ARMCP::ARMCPModifier Modifier) { 162226633Sdim return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()), 163226633Sdim GV, 0, ARMCP::CPValue, 0, 164226633Sdim Modifier, false); 165226633Sdim} 166226633Sdim 167226633SdimARMConstantPoolConstant * 168226633SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 169226633Sdim ARMCP::ARMCPKind Kind, unsigned char PCAdj) { 170226633Sdim return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, 171226633Sdim ARMCP::no_modifier, false); 172226633Sdim} 173226633Sdim 174226633SdimARMConstantPoolConstant * 175226633SdimARMConstantPoolConstant::Create(const Constant *C, unsigned ID, 176226633Sdim ARMCP::ARMCPKind Kind, unsigned char PCAdj, 177226633Sdim ARMCP::ARMCPModifier Modifier, 178226633Sdim bool AddCurrentAddress) { 179226633Sdim return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier, 180226633Sdim AddCurrentAddress); 181226633Sdim} 182226633Sdim 183226633Sdimconst GlobalValue *ARMConstantPoolConstant::getGV() const { 184198892Srdivacky return dyn_cast_or_null<GlobalValue>(CVal); 185198892Srdivacky} 186198892Srdivacky 187226633Sdimconst BlockAddress *ARMConstantPoolConstant::getBlockAddress() const { 188198892Srdivacky return dyn_cast_or_null<BlockAddress>(CVal); 189198892Srdivacky} 190198892Srdivacky 191226633Sdimint ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, 192226633Sdim unsigned Alignment) { 193327952Sdim int index = 194327952Sdim getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment); 195327952Sdim if (index != -1) { 196327952Sdim auto *CPV = static_cast<ARMConstantPoolValue*>( 197327952Sdim CP->getConstants()[index].Val.MachineCPVal); 198327952Sdim auto *Constant = cast<ARMConstantPoolConstant>(CPV); 199327952Sdim Constant->GVars.insert(GVars.begin(), GVars.end()); 200327952Sdim } 201327952Sdim return index; 202226633Sdim} 203226633Sdim 204226633Sdimbool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { 205226633Sdim const ARMConstantPoolConstant *ACPC = dyn_cast<ARMConstantPoolConstant>(ACPV); 206226633Sdim return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV); 207226633Sdim} 208226633Sdim 209226633Sdimvoid ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 210226633Sdim ID.AddPointer(CVal); 211327952Sdim for (const auto *GV : GVars) 212327952Sdim ID.AddPointer(GV); 213226633Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 214226633Sdim} 215226633Sdim 216226633Sdimvoid ARMConstantPoolConstant::print(raw_ostream &O) const { 217226633Sdim O << CVal->getName(); 218226633Sdim ARMConstantPoolValue::print(O); 219226633Sdim} 220226633Sdim 221226633Sdim//===----------------------------------------------------------------------===// 222226633Sdim// ARMConstantPoolSymbol 223226633Sdim//===----------------------------------------------------------------------===// 224226633Sdim 225314564SdimARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, StringRef s, 226314564Sdim unsigned id, unsigned char PCAdj, 227226633Sdim ARMCP::ARMCPModifier Modifier, 228226633Sdim bool AddCurrentAddress) 229314564Sdim : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier, 230314564Sdim AddCurrentAddress), 231314564Sdim S(s) {} 232226633Sdim 233314564SdimARMConstantPoolSymbol *ARMConstantPoolSymbol::Create(LLVMContext &C, 234314564Sdim StringRef s, unsigned ID, 235314564Sdim unsigned char PCAdj) { 236226633Sdim return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false); 237226633Sdim} 238226633Sdim 239226633Sdimint ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP, 240226633Sdim unsigned Alignment) { 241261991Sdim return getExistingMachineCPValueImpl<ARMConstantPoolSymbol>(CP, Alignment); 242193323Sed} 243193323Sed 244226633Sdimbool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) { 245226633Sdim const ARMConstantPoolSymbol *ACPS = dyn_cast<ARMConstantPoolSymbol>(ACPV); 246249423Sdim return ACPS && ACPS->S == S && ARMConstantPoolValue::hasSameValue(ACPV); 247198090Srdivacky} 248198090Srdivacky 249226633Sdimvoid ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 250249423Sdim ID.AddString(S); 251226633Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 252193323Sed} 253193323Sed 254226633Sdimvoid ARMConstantPoolSymbol::print(raw_ostream &O) const { 255226633Sdim O << S; 256226633Sdim ARMConstantPoolValue::print(O); 257199481Srdivacky} 258199481Srdivacky 259226633Sdim//===----------------------------------------------------------------------===// 260226633Sdim// ARMConstantPoolMBB 261226633Sdim//===----------------------------------------------------------------------===// 262226633Sdim 263226633SdimARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C, 264226633Sdim const MachineBasicBlock *mbb, 265226633Sdim unsigned id, unsigned char PCAdj, 266226633Sdim ARMCP::ARMCPModifier Modifier, 267226633Sdim bool AddCurrentAddress) 268226633Sdim : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj, 269226633Sdim Modifier, AddCurrentAddress), 270226633Sdim MBB(mbb) {} 271226633Sdim 272226633SdimARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C, 273226633Sdim const MachineBasicBlock *mbb, 274226633Sdim unsigned ID, 275226633Sdim unsigned char PCAdj) { 276226633Sdim return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false); 277193323Sed} 278193323Sed 279226633Sdimint ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP, 280226633Sdim unsigned Alignment) { 281261991Sdim return getExistingMachineCPValueImpl<ARMConstantPoolMBB>(CP, Alignment); 282193323Sed} 283226633Sdim 284226633Sdimbool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) { 285226633Sdim const ARMConstantPoolMBB *ACPMBB = dyn_cast<ARMConstantPoolMBB>(ACPV); 286226633Sdim return ACPMBB && ACPMBB->MBB == MBB && 287226633Sdim ARMConstantPoolValue::hasSameValue(ACPV); 288226633Sdim} 289226633Sdim 290226633Sdimvoid ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) { 291226633Sdim ID.AddPointer(MBB); 292226633Sdim ARMConstantPoolValue::addSelectionDAGCSEId(ID); 293226633Sdim} 294226633Sdim 295226633Sdimvoid ARMConstantPoolMBB::print(raw_ostream &O) const { 296327952Sdim O << printMBBReference(*MBB); 297226633Sdim ARMConstantPoolValue::print(O); 298226633Sdim} 299