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