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_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>
     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 
     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   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 
    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;
    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;
    175   static bool classof(const ARMConstantPoolValue *APV) {
    176     return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA();
    177   }
    178 
    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 
    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 
    210   static bool classof(const ARMConstantPoolValue *ACPV) {
    211     return ACPV->isExtSymbol();
    212   }
    213 
    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 
    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 
    246   static bool classof(const ARMConstantPoolValue *ACPV) {
    247     return ACPV->isMachineBasicBlock();
    248   }
    249 
    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