xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaConstantPoolValue.h (revision 3ceba58a7509418b47b8fca2d2b6bbf088714e26)
1 //===- XtensaConstantPoolValue.h - Xtensa constantpool value ----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Xtensa specific constantpool value class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_LIB_TARGET_XTENSA_XTENSACONSTANTPOOLVALUE_H
14 #define LLVM_LIB_TARGET_XTENSA_XTENSACONSTANTPOOLVALUE_H
15 
16 #include "llvm/CodeGen/MachineConstantPool.h"
17 #include "llvm/Support/Casting.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include <cstddef>
20 #include <string>
21 #include <vector>
22 
23 namespace llvm {
24 
25 class BlockAddress;
26 class Constant;
27 class GlobalValue;
28 class LLVMContext;
29 class MachineBasicBlock;
30 
31 namespace XtensaCP {
32 enum XtensaCPKind {
33   CPExtSymbol,
34   CPBlockAddress,
35   CPMachineBasicBlock,
36   CPJumpTable
37 };
38 
39 enum XtensaCPModifier {
40   no_modifier, // None
41   TPOFF        // Thread Pointer Offset
42 };
43 } // namespace XtensaCP
44 
45 /// XtensaConstantPoolValue - Xtensa specific constantpool value. This is used
46 /// to represent PC-relative displacement between the address of the load
47 /// instruction and the constant being loaded.
48 class XtensaConstantPoolValue : public MachineConstantPoolValue {
49   unsigned LabelId;                    // Label id of the load.
50   XtensaCP::XtensaCPKind Kind;         // Kind of constant.
51   XtensaCP::XtensaCPModifier Modifier; // Symbol name modifier
52                                        //(for example Global Variable name)
53 
54 protected:
55   XtensaConstantPoolValue(
56       Type *Ty, unsigned ID, XtensaCP::XtensaCPKind Kind,
57       XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier);
58 
59   XtensaConstantPoolValue(
60       LLVMContext &C, unsigned id, XtensaCP::XtensaCPKind Kind,
61       XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier);
62 
63   template <typename Derived>
64   int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) {
65     const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
66     for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
67       if (Constants[i].isMachineConstantPoolEntry() &&
68           (Constants[i].getAlign() >= Alignment)) {
69         auto *CPV = static_cast<XtensaConstantPoolValue *>(
70             Constants[i].Val.MachineCPVal);
71         if (Derived *APC = dyn_cast<Derived>(CPV))
72           if (cast<Derived>(this)->equals(APC))
73             return i;
74       }
75     }
76 
77     return -1;
78   }
79 
80 public:
81   ~XtensaConstantPoolValue() override;
82 
83   XtensaCP::XtensaCPModifier getModifier() const { return Modifier; }
84   bool hasModifier() const { return Modifier != XtensaCP::no_modifier; }
85   StringRef getModifierText() const;
86 
87   unsigned getLabelId() const { return LabelId; }
88   void setLabelId(unsigned ID) { LabelId = ID; }
89 
90   bool isExtSymbol() const { return Kind == XtensaCP::CPExtSymbol; }
91   bool isBlockAddress() const { return Kind == XtensaCP::CPBlockAddress; }
92   bool isMachineBasicBlock() const {
93     return Kind == XtensaCP::CPMachineBasicBlock;
94   }
95   bool isJumpTable() const { return Kind == XtensaCP::CPJumpTable; }
96 
97   int getExistingMachineCPValue(MachineConstantPool *CP,
98                                 Align Alignment) override;
99 
100   void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
101 
102   /// hasSameValue - Return true if this Xtensa constpool value can share the
103   /// same constantpool entry as another Xtensa constpool value.
104   virtual bool hasSameValue(XtensaConstantPoolValue *ACPV);
105 
106   bool equals(const XtensaConstantPoolValue *A) const {
107     return this->LabelId == A->LabelId && this->Modifier == A->Modifier;
108   }
109 
110   void print(raw_ostream &O) const override;
111 
112 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
113   void dump() const;
114 #endif
115 };
116 
117 inline raw_ostream &operator<<(raw_ostream &O,
118                                const XtensaConstantPoolValue &V) {
119   V.print(O);
120   return O;
121 }
122 
123 /// XtensaConstantPoolConstant - Xtensa-specific constant pool values for
124 /// Constants (for example BlockAddresses).
125 class XtensaConstantPoolConstant : public XtensaConstantPoolValue {
126   const Constant *CVal; // Constant being loaded.
127 
128   XtensaConstantPoolConstant(const Constant *C, unsigned ID,
129                              XtensaCP::XtensaCPKind Kind);
130 
131 public:
132   static XtensaConstantPoolConstant *Create(const Constant *C, unsigned ID,
133                                             XtensaCP::XtensaCPKind Kind);
134 
135   const BlockAddress *getBlockAddress() const;
136 
137   int getExistingMachineCPValue(MachineConstantPool *CP,
138                                 Align Alignment) override;
139 
140   /// hasSameValue - Return true if this Xtensa constpool value can share the
141   /// same constantpool entry as another Xtensa constpool value.
142   bool hasSameValue(XtensaConstantPoolValue *ACPV) override;
143 
144   void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
145 
146   void print(raw_ostream &O) const override;
147   static bool classof(const XtensaConstantPoolValue *APV) {
148     return APV->isBlockAddress();
149   }
150 
151   bool equals(const XtensaConstantPoolConstant *A) const {
152     return CVal == A->CVal && XtensaConstantPoolValue::equals(A);
153   }
154 };
155 
156 /// XtensaConstantPoolSymbol - Xtensa-specific constantpool values for external
157 /// symbols.
158 class XtensaConstantPoolSymbol : public XtensaConstantPoolValue {
159   const std::string S; // ExtSymbol being loaded.
160   bool PrivateLinkage;
161 
162   XtensaConstantPoolSymbol(
163       LLVMContext &C, const char *S, unsigned Id, bool PrivLinkage,
164       XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier);
165 
166 public:
167   static XtensaConstantPoolSymbol *
168   Create(LLVMContext &C, const char *S, unsigned ID, bool PrivLinkage,
169          XtensaCP::XtensaCPModifier Modifier = XtensaCP::no_modifier);
170 
171   const char *getSymbol() const { return S.c_str(); }
172 
173   int getExistingMachineCPValue(MachineConstantPool *CP,
174                                 Align Alignment) override;
175 
176   void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
177 
178   /// hasSameValue - Return true if this Xtensa constpool value can share the
179   /// same constantpool entry as another Xtensa constpool value.
180   bool hasSameValue(XtensaConstantPoolValue *ACPV) override;
181 
182   bool isPrivateLinkage() { return PrivateLinkage; }
183 
184   void print(raw_ostream &O) const override;
185 
186   static bool classof(const XtensaConstantPoolValue *ACPV) {
187     return ACPV->isExtSymbol();
188   }
189 
190   bool equals(const XtensaConstantPoolSymbol *A) const {
191     return S == A->S && XtensaConstantPoolValue::equals(A);
192   }
193 };
194 
195 /// XtensaConstantPoolMBB - Xtensa-specific constantpool value of a machine
196 /// basic block.
197 class XtensaConstantPoolMBB : public XtensaConstantPoolValue {
198   const MachineBasicBlock *MBB; // Machine basic block.
199 
200   XtensaConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *M,
201                         unsigned ID);
202 
203 public:
204   static XtensaConstantPoolMBB *Create(LLVMContext &C,
205                                        const MachineBasicBlock *M, unsigned ID);
206 
207   const MachineBasicBlock *getMBB() const { return MBB; }
208 
209   int getExistingMachineCPValue(MachineConstantPool *CP,
210                                 Align Alignment) override;
211 
212   void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
213 
214   /// hasSameValue - Return true if this Xtensa constpool value can share the
215   /// same constantpool entry as another Xtensa constpool value.
216   bool hasSameValue(XtensaConstantPoolValue *ACPV) override;
217 
218   void print(raw_ostream &O) const override;
219 
220   static bool classof(const XtensaConstantPoolValue *ACPV) {
221     return ACPV->isMachineBasicBlock();
222   }
223 
224   bool equals(const XtensaConstantPoolMBB *A) const {
225     return MBB == A->MBB && XtensaConstantPoolValue::equals(A);
226   }
227 };
228 
229 /// XtensaConstantPoolJumpTable - Xtensa-specific constantpool values for Jump
230 /// Table symbols.
231 class XtensaConstantPoolJumpTable : public XtensaConstantPoolValue {
232   unsigned Idx; // Jump Table Index.
233 
234   XtensaConstantPoolJumpTable(LLVMContext &C, unsigned Idx);
235 
236 public:
237   static XtensaConstantPoolJumpTable *Create(LLVMContext &C, unsigned Idx);
238 
239   unsigned getIndex() const { return Idx; }
240 
241   int getExistingMachineCPValue(MachineConstantPool *CP,
242                                 Align Alignment) override;
243 
244   void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
245 
246   /// hasSameValue - Return true if this Xtensa constpool value can share the
247   /// same constantpool entry as another Xtensa constpool value.
248   bool hasSameValue(XtensaConstantPoolValue *ACPV) override;
249 
250   void print(raw_ostream &O) const override;
251 
252   static bool classof(const XtensaConstantPoolValue *ACPV) {
253     return ACPV->isJumpTable();
254   }
255 
256   bool equals(const XtensaConstantPoolJumpTable *A) const {
257     return Idx == A->Idx && XtensaConstantPoolValue::equals(A);
258   }
259 };
260 
261 } // namespace llvm
262 
263 #endif /* LLVM_LIB_TARGET_XTENSA_XTENSACONSTANTPOOLVALUE_H */
264