LLVM API Documentation
00001 //===-- ARMConstantPoolValue.h - ARM constantpool value ---------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the ARM specific constantpool value class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H 00015 #define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H 00016 00017 #include "llvm/CodeGen/MachineConstantPool.h" 00018 #include "llvm/Support/Casting.h" 00019 #include "llvm/Support/ErrorHandling.h" 00020 #include <cstddef> 00021 00022 namespace llvm { 00023 00024 class BlockAddress; 00025 class Constant; 00026 class GlobalValue; 00027 class LLVMContext; 00028 class MachineBasicBlock; 00029 00030 namespace ARMCP { 00031 enum ARMCPKind { 00032 CPValue, 00033 CPExtSymbol, 00034 CPBlockAddress, 00035 CPLSDA, 00036 CPMachineBasicBlock 00037 }; 00038 00039 enum ARMCPModifier { 00040 no_modifier, 00041 TLSGD, 00042 GOT, 00043 GOTOFF, 00044 GOTTPOFF, 00045 TPOFF 00046 }; 00047 } 00048 00049 /// ARMConstantPoolValue - ARM specific constantpool value. This is used to 00050 /// represent PC-relative displacement between the address of the load 00051 /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). 00052 class ARMConstantPoolValue : public MachineConstantPoolValue { 00053 unsigned LabelId; // Label id of the load. 00054 ARMCP::ARMCPKind Kind; // Kind of constant. 00055 unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative. 00056 // 8 for ARM, 4 for Thumb. 00057 ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) 00058 bool AddCurrentAddress; 00059 00060 protected: 00061 ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind, 00062 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 00063 bool AddCurrentAddress); 00064 00065 ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind, 00066 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 00067 bool AddCurrentAddress); 00068 00069 template <typename Derived> 00070 int getExistingMachineCPValueImpl(MachineConstantPool *CP, 00071 unsigned Alignment) { 00072 unsigned AlignMask = Alignment - 1; 00073 const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants(); 00074 for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 00075 if (Constants[i].isMachineConstantPoolEntry() && 00076 (Constants[i].getAlignment() & AlignMask) == 0) { 00077 ARMConstantPoolValue *CPV = 00078 (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; 00079 if (Derived *APC = dyn_cast<Derived>(CPV)) 00080 if (cast<Derived>(this)->equals(APC)) 00081 return i; 00082 } 00083 } 00084 00085 return -1; 00086 } 00087 00088 public: 00089 virtual ~ARMConstantPoolValue(); 00090 00091 ARMCP::ARMCPModifier getModifier() const { return Modifier; } 00092 const char *getModifierText() const; 00093 bool hasModifier() const { return Modifier != ARMCP::no_modifier; } 00094 00095 bool mustAddCurrentAddress() const { return AddCurrentAddress; } 00096 00097 unsigned getLabelId() const { return LabelId; } 00098 unsigned char getPCAdjustment() const { return PCAdjust; } 00099 00100 bool isGlobalValue() const { return Kind == ARMCP::CPValue; } 00101 bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; } 00102 bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; } 00103 bool isLSDA() const { return Kind == ARMCP::CPLSDA; } 00104 bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; } 00105 00106 unsigned getRelocationInfo() const override { return 2; } 00107 00108 int getExistingMachineCPValue(MachineConstantPool *CP, 00109 unsigned Alignment) override; 00110 00111 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 00112 00113 /// hasSameValue - Return true if this ARM constpool value can share the same 00114 /// constantpool entry as another ARM constpool value. 00115 virtual bool hasSameValue(ARMConstantPoolValue *ACPV); 00116 00117 bool equals(const ARMConstantPoolValue *A) const { 00118 return this->LabelId == A->LabelId && 00119 this->PCAdjust == A->PCAdjust && 00120 this->Modifier == A->Modifier; 00121 } 00122 00123 void print(raw_ostream &O) const override; 00124 void print(raw_ostream *O) const { if (O) print(*O); } 00125 void dump() const; 00126 }; 00127 00128 inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { 00129 V.print(O); 00130 return O; 00131 } 00132 00133 /// ARMConstantPoolConstant - ARM-specific constant pool values for Constants, 00134 /// Functions, and BlockAddresses. 00135 class ARMConstantPoolConstant : public ARMConstantPoolValue { 00136 const Constant *CVal; // Constant being loaded. 00137 00138 ARMConstantPoolConstant(const Constant *C, 00139 unsigned ID, 00140 ARMCP::ARMCPKind Kind, 00141 unsigned char PCAdj, 00142 ARMCP::ARMCPModifier Modifier, 00143 bool AddCurrentAddress); 00144 ARMConstantPoolConstant(Type *Ty, const Constant *C, 00145 unsigned ID, 00146 ARMCP::ARMCPKind Kind, 00147 unsigned char PCAdj, 00148 ARMCP::ARMCPModifier Modifier, 00149 bool AddCurrentAddress); 00150 00151 public: 00152 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID); 00153 static ARMConstantPoolConstant *Create(const GlobalValue *GV, 00154 ARMCP::ARMCPModifier Modifier); 00155 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 00156 ARMCP::ARMCPKind Kind, 00157 unsigned char PCAdj); 00158 static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, 00159 ARMCP::ARMCPKind Kind, 00160 unsigned char PCAdj, 00161 ARMCP::ARMCPModifier Modifier, 00162 bool AddCurrentAddress); 00163 00164 const GlobalValue *getGV() const; 00165 const BlockAddress *getBlockAddress() const; 00166 00167 int getExistingMachineCPValue(MachineConstantPool *CP, 00168 unsigned Alignment) override; 00169 00170 /// hasSameValue - Return true if this ARM constpool value can share the same 00171 /// constantpool entry as another ARM constpool value. 00172 bool hasSameValue(ARMConstantPoolValue *ACPV) override; 00173 00174 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 00175 00176 void print(raw_ostream &O) const override; 00177 static bool classof(const ARMConstantPoolValue *APV) { 00178 return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA(); 00179 } 00180 00181 bool equals(const ARMConstantPoolConstant *A) const { 00182 return CVal == A->CVal && ARMConstantPoolValue::equals(A); 00183 } 00184 }; 00185 00186 /// ARMConstantPoolSymbol - ARM-specific constantpool values for external 00187 /// symbols. 00188 class ARMConstantPoolSymbol : public ARMConstantPoolValue { 00189 const std::string S; // ExtSymbol being loaded. 00190 00191 ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id, 00192 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 00193 bool AddCurrentAddress); 00194 00195 public: 00196 static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s, 00197 unsigned ID, unsigned char PCAdj); 00198 00199 const char *getSymbol() const { return S.c_str(); } 00200 00201 int getExistingMachineCPValue(MachineConstantPool *CP, 00202 unsigned Alignment) override; 00203 00204 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 00205 00206 /// hasSameValue - Return true if this ARM constpool value can share the same 00207 /// constantpool entry as another ARM constpool value. 00208 bool hasSameValue(ARMConstantPoolValue *ACPV) override; 00209 00210 void print(raw_ostream &O) const override; 00211 00212 static bool classof(const ARMConstantPoolValue *ACPV) { 00213 return ACPV->isExtSymbol(); 00214 } 00215 00216 bool equals(const ARMConstantPoolSymbol *A) const { 00217 return S == A->S && ARMConstantPoolValue::equals(A); 00218 } 00219 }; 00220 00221 /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic 00222 /// block. 00223 class ARMConstantPoolMBB : public ARMConstantPoolValue { 00224 const MachineBasicBlock *MBB; // Machine basic block. 00225 00226 ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id, 00227 unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, 00228 bool AddCurrentAddress); 00229 00230 public: 00231 static ARMConstantPoolMBB *Create(LLVMContext &C, 00232 const MachineBasicBlock *mbb, 00233 unsigned ID, unsigned char PCAdj); 00234 00235 const MachineBasicBlock *getMBB() const { return MBB; } 00236 00237 int getExistingMachineCPValue(MachineConstantPool *CP, 00238 unsigned Alignment) override; 00239 00240 void addSelectionDAGCSEId(FoldingSetNodeID &ID) override; 00241 00242 /// hasSameValue - Return true if this ARM constpool value can share the same 00243 /// constantpool entry as another ARM constpool value. 00244 bool hasSameValue(ARMConstantPoolValue *ACPV) override; 00245 00246 void print(raw_ostream &O) const override; 00247 00248 static bool classof(const ARMConstantPoolValue *ACPV) { 00249 return ACPV->isMachineBasicBlock(); 00250 } 00251 00252 bool equals(const ARMConstantPoolMBB *A) const { 00253 return MBB == A->MBB && ARMConstantPoolValue::equals(A); 00254 } 00255 }; 00256 00257 } // End llvm namespace 00258 00259 #endif