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