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>
getExistingMachineCPValueImpl(MachineConstantPool * CP,unsigned Alignment)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 
getModifier()91   ARMCP::ARMCPModifier getModifier() const { return Modifier; }
92   const char *getModifierText() const;
hasModifier()93   bool hasModifier() const { return Modifier != ARMCP::no_modifier; }
94 
mustAddCurrentAddress()95   bool mustAddCurrentAddress() const { return AddCurrentAddress; }
96 
getLabelId()97   unsigned getLabelId() const { return LabelId; }
getPCAdjustment()98   unsigned char getPCAdjustment() const { return PCAdjust; }
99 
isGlobalValue()100   bool isGlobalValue() const { return Kind == ARMCP::CPValue; }
isExtSymbol()101   bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; }
isBlockAddress()102   bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; }
isLSDA()103   bool isLSDA() const { return Kind == ARMCP::CPLSDA; }
isMachineBasicBlock()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 
equals(const ARMConstantPoolValue * A)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;
print(raw_ostream * O)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;
classof(const ARMConstantPoolValue * APV)175   static bool classof(const ARMConstantPoolValue *APV) {
176     return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA();
177   }
178 
equals(const ARMConstantPoolConstant * A)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 
getSymbol()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 
classof(const ARMConstantPoolValue * ACPV)210   static bool classof(const ARMConstantPoolValue *ACPV) {
211     return ACPV->isExtSymbol();
212   }
213 
equals(const ARMConstantPoolSymbol * A)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 
getMBB()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 
classof(const ARMConstantPoolValue * ACPV)246   static bool classof(const ARMConstantPoolValue *ACPV) {
247     return ACPV->isMachineBasicBlock();
248   }
249 
equals(const ARMConstantPoolMBB * A)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