Home | History | Annotate | Download | only in ARM
      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_TARGET_ARM_CONSTANTPOOLVALUE_H
     15 #define LLVM_TARGET_ARM_CONSTANTPOOLVALUE_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,
     43     GOTOFF,
     44     GOTTPOFF,
     45     TPOFF
     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>
     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   virtual ~ARMConstantPoolValue();
     90 
     91   ARMCP::ARMCPModifier getModifier() const { return Modifier; }
     92   const char *getModifierText() const;
     93   bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
     94 
     95   bool mustAddCurrentAddress() const { return AddCurrentAddress; }
     96 
     97   unsigned getLabelId() const { return LabelId; }
     98   unsigned char getPCAdjustment() const { return PCAdjust; }
     99 
    100   bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
    101   bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
    102   bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
    103   bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
    104   bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; }
    105 
    106   unsigned getRelocationInfo() const override { return 2; }
    107 
    108   int getExistingMachineCPValue(MachineConstantPool *CP,
    109                                 unsigned Alignment) override;
    110 
    111   void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
    112 
    113   /// hasSameValue - Return true if this ARM constpool value can share the same
    114   /// constantpool entry as another ARM constpool value.
    115   virtual bool hasSameValue(ARMConstantPoolValue *ACPV);
    116 
    117   bool equals(const ARMConstantPoolValue *A) const {
    118     return this->LabelId == A->LabelId &&
    119       this->PCAdjust == A->PCAdjust &&
    120       this->Modifier == A->Modifier;
    121   }
    122 
    123   void print(raw_ostream &O) const override;
    124   void print(raw_ostream *O) const { if (O) print(*O); }
    125   void dump() const;
    126 };
    127 
    128 inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) {
    129   V.print(O);
    130   return O;
    131 }
    132 
    133 /// ARMConstantPoolConstant - ARM-specific constant pool values for Constants,
    134 /// Functions, and BlockAddresses.
    135 class ARMConstantPoolConstant : public ARMConstantPoolValue {
    136   const Constant *CVal;         // Constant being loaded.
    137 
    138   ARMConstantPoolConstant(const Constant *C,
    139                           unsigned ID,
    140                           ARMCP::ARMCPKind Kind,
    141                           unsigned char PCAdj,
    142                           ARMCP::ARMCPModifier Modifier,
    143                           bool AddCurrentAddress);
    144   ARMConstantPoolConstant(Type *Ty, const Constant *C,
    145                           unsigned ID,
    146                           ARMCP::ARMCPKind Kind,
    147                           unsigned char PCAdj,
    148                           ARMCP::ARMCPModifier Modifier,
    149                           bool AddCurrentAddress);
    150 
    151 public:
    152   static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID);
    153   static ARMConstantPoolConstant *Create(const GlobalValue *GV,
    154                                          ARMCP::ARMCPModifier Modifier);
    155   static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
    156                                          ARMCP::ARMCPKind Kind,
    157                                          unsigned char PCAdj);
    158   static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID,
    159                                          ARMCP::ARMCPKind Kind,
    160                                          unsigned char PCAdj,
    161                                          ARMCP::ARMCPModifier Modifier,
    162                                          bool AddCurrentAddress);
    163 
    164   const GlobalValue *getGV() const;
    165   const BlockAddress *getBlockAddress() const;
    166 
    167   int getExistingMachineCPValue(MachineConstantPool *CP,
    168                                 unsigned Alignment) override;
    169 
    170   /// hasSameValue - Return true if this ARM constpool value can share the same
    171   /// constantpool entry as another ARM constpool value.
    172   bool hasSameValue(ARMConstantPoolValue *ACPV) override;
    173 
    174   void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
    175 
    176   void print(raw_ostream &O) const override;
    177   static bool classof(const ARMConstantPoolValue *APV) {
    178     return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA();
    179   }
    180 
    181   bool equals(const ARMConstantPoolConstant *A) const {
    182     return CVal == A->CVal && ARMConstantPoolValue::equals(A);
    183   }
    184 };
    185 
    186 /// ARMConstantPoolSymbol - ARM-specific constantpool values for external
    187 /// symbols.
    188 class ARMConstantPoolSymbol : public ARMConstantPoolValue {
    189   const std::string S;          // ExtSymbol being loaded.
    190 
    191   ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id,
    192                         unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
    193                         bool AddCurrentAddress);
    194 
    195 public:
    196   static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s,
    197                                        unsigned ID, unsigned char PCAdj);
    198 
    199   const char *getSymbol() const { return S.c_str(); }
    200 
    201   int getExistingMachineCPValue(MachineConstantPool *CP,
    202                                 unsigned Alignment) override;
    203 
    204   void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
    205 
    206   /// hasSameValue - Return true if this ARM constpool value can share the same
    207   /// constantpool entry as another ARM constpool value.
    208   bool hasSameValue(ARMConstantPoolValue *ACPV) override;
    209 
    210   void print(raw_ostream &O) const override;
    211 
    212   static bool classof(const ARMConstantPoolValue *ACPV) {
    213     return ACPV->isExtSymbol();
    214   }
    215 
    216   bool equals(const ARMConstantPoolSymbol *A) const {
    217     return S == A->S && ARMConstantPoolValue::equals(A);
    218   }
    219 };
    220 
    221 /// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic
    222 /// block.
    223 class ARMConstantPoolMBB : public ARMConstantPoolValue {
    224   const MachineBasicBlock *MBB; // Machine basic block.
    225 
    226   ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id,
    227                      unsigned char PCAdj, ARMCP::ARMCPModifier Modifier,
    228                      bool AddCurrentAddress);
    229 
    230 public:
    231   static ARMConstantPoolMBB *Create(LLVMContext &C,
    232                                     const MachineBasicBlock *mbb,
    233                                     unsigned ID, unsigned char PCAdj);
    234 
    235   const MachineBasicBlock *getMBB() const { return MBB; }
    236 
    237   int getExistingMachineCPValue(MachineConstantPool *CP,
    238                                 unsigned Alignment) override;
    239 
    240   void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
    241 
    242   /// hasSameValue - Return true if this ARM constpool value can share the same
    243   /// constantpool entry as another ARM constpool value.
    244   bool hasSameValue(ARMConstantPoolValue *ACPV) override;
    245 
    246   void print(raw_ostream &O) const override;
    247 
    248   static bool classof(const ARMConstantPoolValue *ACPV) {
    249     return ACPV->isMachineBasicBlock();
    250   }
    251 
    252   bool equals(const ARMConstantPoolMBB *A) const {
    253     return MBB == A->MBB && ARMConstantPoolValue::equals(A);
    254   }
    255 };
    256 
    257 } // End llvm namespace
    258 
    259 #endif
    260