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