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