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