1 //===-- ARMConstantPoolValue.h - ARM constantpool value ---------*- C++ -*-===// 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 #ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H 15 #define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H 16 17 #include "llvm/CodeGen/MachineConstantPool.h" 18 #include "llvm/Support/Casting.h" 19 #include "llvm/Support/ErrorHandling.h" 20 #include <cstddef> 21 22 namespace llvm { 23 24 class BlockAddress; 25 class Constant; 26 class GlobalValue; 27 class GlobalVariable; 28 class LLVMContext; 29 class MachineBasicBlock; 30 31 namespace ARMCP { 32 enum ARMCPKind { 33 CPValue, 34 CPExtSymbol, 35 CPBlockAddress, 36 CPLSDA, 37 CPMachineBasicBlock, 38 CPPromotedGlobal 39 }; 40 41 enum ARMCPModifier { 42 no_modifier, /// None 43 TLSGD, /// Thread Local Storage (General Dynamic Mode) 44 GOT_PREL, /// Global Offset Table, PC Relative 45 GOTTPOFF, /// Global Offset Table, Thread Pointer Offset 46 TPOFF, /// Thread Pointer Offset 47 SECREL, /// Section Relative (Windows TLS) 48 SBREL, /// Static Base Relative (RWPI) 49 }; 50 } 51 52 /// ARMConstantPoolValue - ARM specific constantpool value. This is used to 53 /// represent PC-relative displacement between the address of the load 54 /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). 55 class ARMConstantPoolValue : public MachineConstantPoolValue { 56 unsigned LabelId; // Label id of the load. 57 ARMCP::ARMCPKind Kind; // Kind of constant. 58 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative. 59 // 8 for ARM, 4 for Thumb. 60 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) 61 bool AddCurrentAddress; 62 63 protected: 64 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind, 65 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 66 bool AddCurrentAddress); 67 68 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind, 69 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 70 bool AddCurrentAddress); 71 72 template <typename Derived> 73 int getExistingMachineCPValueImpl(MachineConstantPool *CP, 74 unsigned Alignment) { 75 unsigned AlignMask = Alignment - 1; 76 const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants(); 77 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 78 if (Constants[i].isMachineConstantPoolEntry() && 79 (Constants[i].getAlignment() & AlignMask) == 0) { 80 ARMConstantPoolValue *CPV = 81 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; 82 if (Derived *APC = dyn_cast<Derived>(CPV)) 83 if (cast<Derived>(this)->equals(APC)) 84 return i; 85 } 86 } 87 88 return -1; 89 } 90 91 public: 92 ~ARMConstantPoolValue() override; 93 94 ARMCP::ARMCPModifier getModifier() const { return Modifier; } 95 StringRef getModifierText() const; 96 bool hasModifier() const { return Modifier != ARMCP::no_modifier; } 97 98 bool mustAddCurrentAddress() const { return AddCurrentAddress; } 99 100 unsigned getLabelId() const { return LabelId; } 101 unsigned char getPCAdjustment() const { return PCAdjust; } 102 103 bool isGlobalValue() const { return Kind == ARMCP::CPValue; } 104 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; } 105 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; } 106 bool isLSDA() const { return Kind == ARMCP::CPLSDA; } 107 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; } 108 bool isPromotedGlobal() const{ return Kind == ARMCP::CPPromotedGlobal; } 109 110 int getExistingMachineCPValue(MachineConstantPool *CP, 111 unsigned Alignment) override; 112 113 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 114 115 /// hasSameValue - Return true if this ARM constpool value can share the same 116 /// constantpool entry as another ARM constpool value. 117 virtual bool hasSameValue(ARMConstantPoolValue *ACPV); 118 119 bool equals(const ARMConstantPoolValue *A) const { 120 return this->LabelId == A->LabelId && 121 this->PCAdjust == A->PCAdjust && 122 this->Modifier == A->Modifier; 123 } 124 125 void print(raw_ostream &O) const override; 126 void print(raw_ostream *O) const { if (O) print(*O); } 127 void dump() const; 128 }; 129 130 inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { 131 V.print(O); 132 return O; 133 } 134 135 /// ARMConstantPoolConstant - ARM-specific constant pool values for Constants, 136 /// Functions, and BlockAddresses. 137 class ARMConstantPoolConstant : public ARMConstantPoolValue { 138 const Constant *CVal; // Constant being loaded. 139 const GlobalVariable *GVar = nullptr; 140 141 ARMConstantPoolConstant(const Constant *C, 142 unsigned ID, 143 ARMCP::ARMCPKind Kind, 144 unsigned char PCAdj, 145 ARMCP::ARMCPModifier Modifier, 146 bool AddCurrentAddress); 147 ARMConstantPoolConstant(Type *Ty, const Constant *C, 148 unsigned ID, 149 ARMCP::ARMCPKind Kind, 150 unsigned char PCAdj, 151 ARMCP::ARMCPModifier Modifier, 152 bool AddCurrentAddress); 153 ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *Init); 154 155 public: 156 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID); 157 static ARMConstantPoolConstant *Create(const GlobalValue *GV, 158 ARMCP::ARMCPModifier Modifier); 159 static ARMConstantPoolConstant *Create(const GlobalVariable *GV, 160 const Constant *Initializer); 161 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 162 ARMCP::ARMCPKind Kind, 163 unsigned char PCAdj); 164 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 165 ARMCP::ARMCPKind Kind, 166 unsigned char PCAdj, 167 ARMCP::ARMCPModifier Modifier, 168 bool AddCurrentAddress); 169 170 const GlobalValue *getGV() const; 171 const BlockAddress *getBlockAddress() const; 172 const GlobalVariable *getPromotedGlobal() const { 173 return dyn_cast_or_null<GlobalVariable>(GVar); 174 } 175 const Constant *getPromotedGlobalInit() const { 176 return CVal; 177 } 178 179 int getExistingMachineCPValue(MachineConstantPool *CP, 180 unsigned Alignment) override; 181 182 /// hasSameValue - Return true if this ARM constpool value can share the same 183 /// constantpool entry as another ARM constpool value. 184 bool hasSameValue(ARMConstantPoolValue *ACPV) override; 185 186 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 187 188 void print(raw_ostream &O) const override; 189 static bool classof(const ARMConstantPoolValue *APV) { 190 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA() || 191 APV->isPromotedGlobal(); 192 } 193 194 bool equals(const ARMConstantPoolConstant *A) const { 195 return CVal == A->CVal && ARMConstantPoolValue::equals(A); 196 } 197 }; 198 199 /// ARMConstantPoolSymbol - ARM-specific constantpool values for external 200 /// symbols. 201 class ARMConstantPoolSymbol : public ARMConstantPoolValue { 202 const std::string S; // ExtSymbol being loaded. 203 204 ARMConstantPoolSymbol(LLVMContext &C, StringRef s, unsigned id, 205 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 206 bool AddCurrentAddress); 207 208 public: 209 static ARMConstantPoolSymbol *Create(LLVMContext &C, StringRef s, unsigned ID, 210 unsigned char PCAdj); 211 212 StringRef getSymbol() const { return S; } 213 214 int getExistingMachineCPValue(MachineConstantPool *CP, 215 unsigned Alignment) override; 216 217 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 218 219 /// hasSameValue - Return true if this ARM constpool value can share the same 220 /// constantpool entry as another ARM constpool value. 221 bool hasSameValue(ARMConstantPoolValue *ACPV) override; 222 223 void print(raw_ostream &O) const override; 224 225 static bool classof(const ARMConstantPoolValue *ACPV) { 226 return ACPV->isExtSymbol(); 227 } 228 229 bool equals(const ARMConstantPoolSymbol *A) const { 230 return S == A->S && ARMConstantPoolValue::equals(A); 231 } 232 }; 233 234 /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic 235 /// block. 236 class ARMConstantPoolMBB : public ARMConstantPoolValue { 237 const MachineBasicBlock *MBB; // Machine basic block. 238 239 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id, 240 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 241 bool AddCurrentAddress); 242 243 public: 244 static ARMConstantPoolMBB *Create(LLVMContext &C, 245 const MachineBasicBlock *mbb, 246 unsigned ID, unsigned char PCAdj); 247 248 const MachineBasicBlock *getMBB() const { return MBB; } 249 250 int getExistingMachineCPValue(MachineConstantPool *CP, 251 unsigned Alignment) override; 252 253 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 254 255 /// hasSameValue - Return true if this ARM constpool value can share the same 256 /// constantpool entry as another ARM constpool value. 257 bool hasSameValue(ARMConstantPoolValue *ACPV) override; 258 259 void print(raw_ostream &O) const override; 260 261 static bool classof(const ARMConstantPoolValue *ACPV) { 262 return ACPV->isMachineBasicBlock(); 263 } 264 265 bool equals(const ARMConstantPoolMBB *A) const { 266 return MBB == A->MBB && ARMConstantPoolValue::equals(A); 267 } 268 }; 269 270 } // End llvm namespace 271 272 #endif 273