LLVM API Documentation

ARMConstantPoolValue.h
Go to the documentation of this file.
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