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