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 | |