Line data Source code
1 : //===- GVNExpression.h - GVN Expression classes -----------------*- 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 : /// \file
11 : ///
12 : /// The header file for the GVN pass that contains expression handling
13 : /// classes
14 : //
15 : //===----------------------------------------------------------------------===//
16 :
17 : #ifndef LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
18 : #define LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
19 :
20 : #include "llvm/ADT/Hashing.h"
21 : #include "llvm/ADT/iterator_range.h"
22 : #include "llvm/Analysis/MemorySSA.h"
23 : #include "llvm/IR/Constant.h"
24 : #include "llvm/IR/Instructions.h"
25 : #include "llvm/IR/Value.h"
26 : #include "llvm/Support/Allocator.h"
27 : #include "llvm/Support/ArrayRecycler.h"
28 : #include "llvm/Support/Casting.h"
29 : #include "llvm/Support/Compiler.h"
30 : #include "llvm/Support/raw_ostream.h"
31 : #include <algorithm>
32 : #include <cassert>
33 : #include <iterator>
34 : #include <utility>
35 :
36 : namespace llvm {
37 :
38 : class BasicBlock;
39 : class Type;
40 :
41 : namespace GVNExpression {
42 :
43 : enum ExpressionType {
44 : ET_Base,
45 : ET_Constant,
46 : ET_Variable,
47 : ET_Dead,
48 : ET_Unknown,
49 : ET_BasicStart,
50 : ET_Basic,
51 : ET_AggregateValue,
52 : ET_Phi,
53 : ET_MemoryStart,
54 : ET_Call,
55 : ET_Load,
56 : ET_Store,
57 : ET_MemoryEnd,
58 : ET_BasicEnd
59 : };
60 :
61 0 : class Expression {
62 : private:
63 : ExpressionType EType;
64 : unsigned Opcode;
65 : mutable hash_code HashVal = 0;
66 :
67 : public:
68 : Expression(ExpressionType ET = ET_Base, unsigned O = ~2U)
69 467 : : EType(ET), Opcode(O) {}
70 : Expression(const Expression &) = delete;
71 : Expression &operator=(const Expression &) = delete;
72 : virtual ~Expression();
73 :
74 : static unsigned getEmptyKey() { return ~0U; }
75 : static unsigned getTombstoneKey() { return ~1U; }
76 :
77 36 : bool operator!=(const Expression &Other) const { return !(*this == Other); }
78 867 : bool operator==(const Expression &Other) const {
79 867 : if (getOpcode() != Other.getOpcode())
80 : return false;
81 867 : if (getOpcode() == getEmptyKey() || getOpcode() == getTombstoneKey())
82 : return true;
83 : // Compare the expression type for anything but load and store.
84 : // For load and store we set the opcode to zero to make them equal.
85 867 : if (getExpressionType() != ET_Load && getExpressionType() != ET_Store &&
86 487 : getExpressionType() != Other.getExpressionType())
87 : return false;
88 :
89 867 : return equals(Other);
90 : }
91 :
92 : hash_code getComputedHash() const {
93 : // It's theoretically possible for a thing to hash to zero. In that case,
94 : // we will just compute the hash a few extra times, which is no worse that
95 : // we did before, which was to compute it always.
96 5281 : if (static_cast<unsigned>(HashVal) == 0)
97 3203 : HashVal = getHashValue();
98 5281 : return HashVal;
99 : }
100 :
101 0 : virtual bool equals(const Expression &Other) const { return true; }
102 :
103 : // Return true if the two expressions are exactly the same, including the
104 : // normally ignored fields.
105 246 : virtual bool exactlyEquals(const Expression &Other) const {
106 330 : return getExpressionType() == Other.getExpressionType() && equals(Other);
107 : }
108 :
109 0 : unsigned getOpcode() const { return Opcode; }
110 3158 : void setOpcode(unsigned opcode) { Opcode = opcode; }
111 0 : ExpressionType getExpressionType() const { return EType; }
112 :
113 : // We deliberately leave the expression type out of the hash value.
114 3203 : virtual hash_code getHashValue() const { return getOpcode(); }
115 :
116 : // Debugging support
117 0 : virtual void printInternal(raw_ostream &OS, bool PrintEType) const {
118 0 : if (PrintEType)
119 0 : OS << "etype = " << getExpressionType() << ",";
120 0 : OS << "opcode = " << getOpcode() << ", ";
121 0 : }
122 :
123 0 : void print(raw_ostream &OS) const {
124 0 : OS << "{ ";
125 0 : printInternal(OS, true);
126 0 : OS << "}";
127 0 : }
128 :
129 : LLVM_DUMP_METHOD void dump() const;
130 : };
131 :
132 : inline raw_ostream &operator<<(raw_ostream &OS, const Expression &E) {
133 : E.print(OS);
134 : return OS;
135 : }
136 :
137 0 : class BasicExpression : public Expression {
138 : private:
139 : using RecyclerType = ArrayRecycler<Value *>;
140 : using RecyclerCapacity = RecyclerType::Capacity;
141 :
142 : Value **Operands = nullptr;
143 : unsigned MaxOperands;
144 : unsigned NumOperands = 0;
145 : Type *ValueType = nullptr;
146 :
147 : public:
148 : BasicExpression(unsigned NumOperands)
149 : : BasicExpression(NumOperands, ET_Basic) {}
150 : BasicExpression(unsigned NumOperands, ExpressionType ET)
151 3488 : : Expression(ET), MaxOperands(NumOperands) {}
152 : BasicExpression() = delete;
153 : BasicExpression(const BasicExpression &) = delete;
154 : BasicExpression &operator=(const BasicExpression &) = delete;
155 : ~BasicExpression() override;
156 :
157 : static bool classof(const Expression *EB) {
158 : ExpressionType ET = EB->getExpressionType();
159 : return ET > ET_BasicStart && ET < ET_BasicEnd;
160 : }
161 :
162 : /// Swap two operands. Used during GVN to put commutative operands in
163 : /// order.
164 0 : void swapOperands(unsigned First, unsigned Second) {
165 0 : std::swap(Operands[First], Operands[Second]);
166 0 : }
167 :
168 0 : Value *getOperand(unsigned N) const {
169 : assert(Operands && "Operands not allocated");
170 : assert(N < NumOperands && "Operand out of range");
171 2248 : return Operands[N];
172 : }
173 :
174 : void setOperand(unsigned N, Value *V) {
175 : assert(Operands && "Operands not allocated before setting");
176 : assert(N < NumOperands && "Operand out of range");
177 : Operands[N] = V;
178 : }
179 :
180 0 : unsigned getNumOperands() const { return NumOperands; }
181 :
182 : using op_iterator = Value **;
183 : using const_op_iterator = Value *const *;
184 :
185 0 : op_iterator op_begin() { return Operands; }
186 380 : op_iterator op_end() { return Operands + NumOperands; }
187 0 : const_op_iterator op_begin() const { return Operands; }
188 3309 : const_op_iterator op_end() const { return Operands + NumOperands; }
189 : iterator_range<op_iterator> operands() {
190 674 : return iterator_range<op_iterator>(op_begin(), op_end());
191 : }
192 : iterator_range<const_op_iterator> operands() const {
193 : return iterator_range<const_op_iterator>(op_begin(), op_end());
194 : }
195 :
196 0 : void op_push_back(Value *Arg) {
197 : assert(NumOperands < MaxOperands && "Tried to add too many operands");
198 : assert(Operands && "Operandss not allocated before pushing");
199 621 : Operands[NumOperands++] = Arg;
200 0 : }
201 : bool op_empty() const { return getNumOperands() == 0; }
202 :
203 0 : void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator) {
204 : assert(!Operands && "Operands already allocated");
205 0 : Operands = Recycler.allocate(RecyclerCapacity::get(MaxOperands), Allocator);
206 0 : }
207 0 : void deallocateOperands(RecyclerType &Recycler) {
208 826 : Recycler.deallocate(RecyclerCapacity::get(MaxOperands), Operands);
209 0 : }
210 :
211 3407 : void setType(Type *T) { ValueType = T; }
212 0 : Type *getType() const { return ValueType; }
213 :
214 897 : bool equals(const Expression &Other) const override {
215 897 : if (getOpcode() != Other.getOpcode())
216 : return false;
217 :
218 : const auto &OE = cast<BasicExpression>(Other);
219 1794 : return getType() == OE.getType() && NumOperands == OE.NumOperands &&
220 897 : std::equal(op_begin(), op_end(), OE.op_begin());
221 : }
222 :
223 2412 : hash_code getHashValue() const override {
224 7236 : return hash_combine(this->Expression::getHashValue(), ValueType,
225 2412 : hash_combine_range(op_begin(), op_end()));
226 : }
227 :
228 : // Debugging support
229 0 : void printInternal(raw_ostream &OS, bool PrintEType) const override {
230 0 : if (PrintEType)
231 0 : OS << "ExpressionTypeBasic, ";
232 :
233 0 : this->Expression::printInternal(OS, false);
234 0 : OS << "operands = {";
235 0 : for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
236 0 : OS << "[" << i << "] = ";
237 0 : Operands[i]->printAsOperand(OS);
238 0 : OS << " ";
239 : }
240 0 : OS << "} ";
241 0 : }
242 : };
243 :
244 : class op_inserter
245 : : public std::iterator<std::output_iterator_tag, void, void, void, void> {
246 : private:
247 : using Container = BasicExpression;
248 :
249 : Container *BE;
250 :
251 : public:
252 : explicit op_inserter(BasicExpression &E) : BE(&E) {}
253 2173 : explicit op_inserter(BasicExpression *E) : BE(E) {}
254 :
255 : op_inserter &operator=(Value *val) {
256 3401 : BE->op_push_back(val);
257 : return *this;
258 : }
259 : op_inserter &operator*() { return *this; }
260 : op_inserter &operator++() { return *this; }
261 : op_inserter &operator++(int) { return *this; }
262 : };
263 :
264 0 : class MemoryExpression : public BasicExpression {
265 : private:
266 : const MemoryAccess *MemoryLeader;
267 :
268 : public:
269 : MemoryExpression(unsigned NumOperands, enum ExpressionType EType,
270 : const MemoryAccess *MemoryLeader)
271 2268 : : BasicExpression(NumOperands, EType), MemoryLeader(MemoryLeader) {}
272 : MemoryExpression() = delete;
273 : MemoryExpression(const MemoryExpression &) = delete;
274 : MemoryExpression &operator=(const MemoryExpression &) = delete;
275 :
276 : static bool classof(const Expression *EB) {
277 : return EB->getExpressionType() > ET_MemoryStart &&
278 : EB->getExpressionType() < ET_MemoryEnd;
279 : }
280 :
281 1131 : hash_code getHashValue() const override {
282 1131 : return hash_combine(this->BasicExpression::getHashValue(), MemoryLeader);
283 : }
284 :
285 19 : bool equals(const Expression &Other) const override {
286 483 : if (!this->BasicExpression::equals(Other))
287 : return false;
288 : const MemoryExpression &OtherMCE = cast<MemoryExpression>(Other);
289 :
290 463 : return MemoryLeader == OtherMCE.MemoryLeader;
291 : }
292 :
293 0 : const MemoryAccess *getMemoryLeader() const { return MemoryLeader; }
294 : void setMemoryLeader(const MemoryAccess *ML) { MemoryLeader = ML; }
295 : };
296 :
297 0 : class CallExpression final : public MemoryExpression {
298 : private:
299 : CallInst *Call;
300 :
301 : public:
302 : CallExpression(unsigned NumOperands, CallInst *C,
303 : const MemoryAccess *MemoryLeader)
304 108 : : MemoryExpression(NumOperands, ET_Call, MemoryLeader), Call(C) {}
305 : CallExpression() = delete;
306 : CallExpression(const CallExpression &) = delete;
307 : CallExpression &operator=(const CallExpression &) = delete;
308 : ~CallExpression() override;
309 :
310 : static bool classof(const Expression *EB) {
311 : return EB->getExpressionType() == ET_Call;
312 : }
313 :
314 : // Debugging support
315 0 : void printInternal(raw_ostream &OS, bool PrintEType) const override {
316 0 : if (PrintEType)
317 0 : OS << "ExpressionTypeCall, ";
318 0 : this->BasicExpression::printInternal(OS, false);
319 0 : OS << " represents call at ";
320 0 : Call->printAsOperand(OS);
321 0 : }
322 : };
323 :
324 0 : class LoadExpression final : public MemoryExpression {
325 : private:
326 : LoadInst *Load;
327 : unsigned Alignment;
328 :
329 : public:
330 : LoadExpression(unsigned NumOperands, LoadInst *L,
331 : const MemoryAccess *MemoryLeader)
332 : : LoadExpression(ET_Load, NumOperands, L, MemoryLeader) {}
333 :
334 : LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L,
335 : const MemoryAccess *MemoryLeader)
336 497 : : MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) {
337 994 : Alignment = L ? L->getAlignment() : 0;
338 : }
339 :
340 : LoadExpression() = delete;
341 : LoadExpression(const LoadExpression &) = delete;
342 : LoadExpression &operator=(const LoadExpression &) = delete;
343 : ~LoadExpression() override;
344 :
345 : static bool classof(const Expression *EB) {
346 464 : return EB->getExpressionType() == ET_Load;
347 : }
348 :
349 0 : LoadInst *getLoadInst() const { return Load; }
350 : void setLoadInst(LoadInst *L) { Load = L; }
351 :
352 : unsigned getAlignment() const { return Alignment; }
353 497 : void setAlignment(unsigned Align) { Alignment = Align; }
354 :
355 : bool equals(const Expression &Other) const override;
356 51 : bool exactlyEquals(const Expression &Other) const override {
357 51 : return Expression::exactlyEquals(Other) &&
358 45 : cast<LoadExpression>(Other).getLoadInst() == getLoadInst();
359 : }
360 :
361 : // Debugging support
362 0 : void printInternal(raw_ostream &OS, bool PrintEType) const override {
363 0 : if (PrintEType)
364 0 : OS << "ExpressionTypeLoad, ";
365 0 : this->BasicExpression::printInternal(OS, false);
366 0 : OS << " represents Load at ";
367 0 : Load->printAsOperand(OS);
368 0 : OS << " with MemoryLeader " << *getMemoryLeader();
369 0 : }
370 : };
371 :
372 0 : class StoreExpression final : public MemoryExpression {
373 : private:
374 : StoreInst *Store;
375 : Value *StoredValue;
376 :
377 : public:
378 : StoreExpression(unsigned NumOperands, StoreInst *S, Value *StoredValue,
379 : const MemoryAccess *MemoryLeader)
380 583 : : MemoryExpression(NumOperands, ET_Store, MemoryLeader), Store(S),
381 583 : StoredValue(StoredValue) {}
382 : StoreExpression() = delete;
383 : StoreExpression(const StoreExpression &) = delete;
384 : StoreExpression &operator=(const StoreExpression &) = delete;
385 : ~StoreExpression() override;
386 :
387 : static bool classof(const Expression *EB) {
388 239 : return EB->getExpressionType() == ET_Store;
389 : }
390 :
391 0 : StoreInst *getStoreInst() const { return Store; }
392 0 : Value *getStoredValue() const { return StoredValue; }
393 :
394 : bool equals(const Expression &Other) const override;
395 :
396 56 : bool exactlyEquals(const Expression &Other) const override {
397 56 : return Expression::exactlyEquals(Other) &&
398 28 : cast<StoreExpression>(Other).getStoreInst() == getStoreInst();
399 : }
400 :
401 : // Debugging support
402 0 : void printInternal(raw_ostream &OS, bool PrintEType) const override {
403 0 : if (PrintEType)
404 0 : OS << "ExpressionTypeStore, ";
405 0 : this->BasicExpression::printInternal(OS, false);
406 0 : OS << " represents Store " << *Store;
407 0 : OS << " with StoredValue ";
408 0 : StoredValue->printAsOperand(OS);
409 0 : OS << " and MemoryLeader " << *getMemoryLeader();
410 0 : }
411 : };
412 :
413 0 : class AggregateValueExpression final : public BasicExpression {
414 : private:
415 : unsigned MaxIntOperands;
416 : unsigned NumIntOperands = 0;
417 : unsigned *IntOperands = nullptr;
418 :
419 : public:
420 : AggregateValueExpression(unsigned NumOperands, unsigned NumIntOperands)
421 3 : : BasicExpression(NumOperands, ET_AggregateValue),
422 3 : MaxIntOperands(NumIntOperands) {}
423 : AggregateValueExpression() = delete;
424 : AggregateValueExpression(const AggregateValueExpression &) = delete;
425 : AggregateValueExpression &
426 : operator=(const AggregateValueExpression &) = delete;
427 : ~AggregateValueExpression() override;
428 :
429 : static bool classof(const Expression *EB) {
430 : return EB->getExpressionType() == ET_AggregateValue;
431 : }
432 :
433 : using int_arg_iterator = unsigned *;
434 : using const_int_arg_iterator = const unsigned *;
435 :
436 : int_arg_iterator int_op_begin() { return IntOperands; }
437 : int_arg_iterator int_op_end() { return IntOperands + NumIntOperands; }
438 0 : const_int_arg_iterator int_op_begin() const { return IntOperands; }
439 0 : const_int_arg_iterator int_op_end() const {
440 3 : return IntOperands + NumIntOperands;
441 : }
442 0 : unsigned int_op_size() const { return NumIntOperands; }
443 : bool int_op_empty() const { return NumIntOperands == 0; }
444 0 : void int_op_push_back(unsigned IntOperand) {
445 : assert(NumIntOperands < MaxIntOperands &&
446 : "Tried to add too many int operands");
447 : assert(IntOperands && "Operands not allocated before pushing");
448 3 : IntOperands[NumIntOperands++] = IntOperand;
449 0 : }
450 :
451 0 : virtual void allocateIntOperands(BumpPtrAllocator &Allocator) {
452 : assert(!IntOperands && "Operands already allocated");
453 3 : IntOperands = Allocator.Allocate<unsigned>(MaxIntOperands);
454 0 : }
455 :
456 0 : bool equals(const Expression &Other) const override {
457 0 : if (!this->BasicExpression::equals(Other))
458 : return false;
459 : const AggregateValueExpression &OE = cast<AggregateValueExpression>(Other);
460 0 : return NumIntOperands == OE.NumIntOperands &&
461 0 : std::equal(int_op_begin(), int_op_end(), OE.int_op_begin());
462 : }
463 :
464 3 : hash_code getHashValue() const override {
465 6 : return hash_combine(this->BasicExpression::getHashValue(),
466 3 : hash_combine_range(int_op_begin(), int_op_end()));
467 : }
468 :
469 : // Debugging support
470 0 : void printInternal(raw_ostream &OS, bool PrintEType) const override {
471 0 : if (PrintEType)
472 0 : OS << "ExpressionTypeAggregateValue, ";
473 0 : this->BasicExpression::printInternal(OS, false);
474 0 : OS << ", intoperands = {";
475 0 : for (unsigned i = 0, e = int_op_size(); i != e; ++i) {
476 0 : OS << "[" << i << "] = " << IntOperands[i] << " ";
477 : }
478 0 : OS << "}";
479 0 : }
480 : };
481 :
482 : class int_op_inserter
483 : : public std::iterator<std::output_iterator_tag, void, void, void, void> {
484 : private:
485 : using Container = AggregateValueExpression;
486 :
487 : Container *AVE;
488 :
489 : public:
490 : explicit int_op_inserter(AggregateValueExpression &E) : AVE(&E) {}
491 : explicit int_op_inserter(AggregateValueExpression *E) : AVE(E) {}
492 :
493 : int_op_inserter &operator=(unsigned int val) {
494 : AVE->int_op_push_back(val);
495 : return *this;
496 : }
497 : int_op_inserter &operator*() { return *this; }
498 : int_op_inserter &operator++() { return *this; }
499 : int_op_inserter &operator++(int) { return *this; }
500 : };
501 :
502 0 : class PHIExpression final : public BasicExpression {
503 : private:
504 : BasicBlock *BB;
505 :
506 : public:
507 : PHIExpression(unsigned NumOperands, BasicBlock *B)
508 1040 : : BasicExpression(NumOperands, ET_Phi), BB(B) {}
509 : PHIExpression() = delete;
510 : PHIExpression(const PHIExpression &) = delete;
511 : PHIExpression &operator=(const PHIExpression &) = delete;
512 : ~PHIExpression() override;
513 :
514 : static bool classof(const Expression *EB) {
515 28 : return EB->getExpressionType() == ET_Phi;
516 : }
517 :
518 103 : bool equals(const Expression &Other) const override {
519 103 : if (!this->BasicExpression::equals(Other))
520 : return false;
521 : const PHIExpression &OE = cast<PHIExpression>(Other);
522 101 : return BB == OE.BB;
523 : }
524 :
525 272 : hash_code getHashValue() const override {
526 272 : return hash_combine(this->BasicExpression::getHashValue(), BB);
527 : }
528 :
529 : // Debugging support
530 0 : void printInternal(raw_ostream &OS, bool PrintEType) const override {
531 0 : if (PrintEType)
532 0 : OS << "ExpressionTypePhi, ";
533 0 : this->BasicExpression::printInternal(OS, false);
534 0 : OS << "bb = " << BB;
535 0 : }
536 : };
537 :
538 : class DeadExpression final : public Expression {
539 : public:
540 325 : DeadExpression() : Expression(ET_Dead) {}
541 : DeadExpression(const DeadExpression &) = delete;
542 : DeadExpression &operator=(const DeadExpression &) = delete;
543 :
544 : static bool classof(const Expression *E) {
545 0 : return E->getExpressionType() == ET_Dead;
546 : }
547 : };
548 :
549 : class VariableExpression final : public Expression {
550 : private:
551 : Value *VariableValue;
552 :
553 : public:
554 560 : VariableExpression(Value *V) : Expression(ET_Variable), VariableValue(V) {}
555 : VariableExpression() = delete;
556 : VariableExpression(const VariableExpression &) = delete;
557 : VariableExpression &operator=(const VariableExpression &) = delete;
558 :
559 : static bool classof(const Expression *EB) {
560 3134 : return EB->getExpressionType() == ET_Variable;
561 : }
562 :
563 0 : Value *getVariableValue() const { return VariableValue; }
564 : void setVariableValue(Value *V) { VariableValue = V; }
565 :
566 0 : bool equals(const Expression &Other) const override {
567 : const VariableExpression &OC = cast<VariableExpression>(Other);
568 0 : return VariableValue == OC.VariableValue;
569 : }
570 :
571 54 : hash_code getHashValue() const override {
572 108 : return hash_combine(this->Expression::getHashValue(),
573 54 : VariableValue->getType(), VariableValue);
574 : }
575 :
576 : // Debugging support
577 0 : void printInternal(raw_ostream &OS, bool PrintEType) const override {
578 0 : if (PrintEType)
579 0 : OS << "ExpressionTypeVariable, ";
580 0 : this->Expression::printInternal(OS, false);
581 0 : OS << " variable = " << *VariableValue;
582 0 : }
583 : };
584 :
585 : class ConstantExpression final : public Expression {
586 : private:
587 : Constant *ConstantValue = nullptr;
588 :
589 : public:
590 : ConstantExpression() : Expression(ET_Constant) {}
591 : ConstantExpression(Constant *constantValue)
592 1066 : : Expression(ET_Constant), ConstantValue(constantValue) {}
593 : ConstantExpression(const ConstantExpression &) = delete;
594 : ConstantExpression &operator=(const ConstantExpression &) = delete;
595 :
596 : static bool classof(const Expression *EB) {
597 5280 : return EB->getExpressionType() == ET_Constant;
598 : }
599 :
600 0 : Constant *getConstantValue() const { return ConstantValue; }
601 : void setConstantValue(Constant *V) { ConstantValue = V; }
602 :
603 258 : bool equals(const Expression &Other) const override {
604 : const ConstantExpression &OC = cast<ConstantExpression>(Other);
605 258 : return ConstantValue == OC.ConstantValue;
606 : }
607 :
608 460 : hash_code getHashValue() const override {
609 920 : return hash_combine(this->Expression::getHashValue(),
610 460 : ConstantValue->getType(), ConstantValue);
611 : }
612 :
613 : // Debugging support
614 0 : void printInternal(raw_ostream &OS, bool PrintEType) const override {
615 0 : if (PrintEType)
616 0 : OS << "ExpressionTypeConstant, ";
617 0 : this->Expression::printInternal(OS, false);
618 0 : OS << " constant = " << *ConstantValue;
619 0 : }
620 : };
621 :
622 : class UnknownExpression final : public Expression {
623 : private:
624 : Instruction *Inst;
625 :
626 : public:
627 554 : UnknownExpression(Instruction *I) : Expression(ET_Unknown), Inst(I) {}
628 : UnknownExpression() = delete;
629 : UnknownExpression(const UnknownExpression &) = delete;
630 : UnknownExpression &operator=(const UnknownExpression &) = delete;
631 :
632 : static bool classof(const Expression *EB) {
633 : return EB->getExpressionType() == ET_Unknown;
634 : }
635 :
636 : Instruction *getInstruction() const { return Inst; }
637 : void setInstruction(Instruction *I) { Inst = I; }
638 :
639 25 : bool equals(const Expression &Other) const override {
640 : const auto &OU = cast<UnknownExpression>(Other);
641 25 : return Inst == OU.Inst;
642 : }
643 :
644 277 : hash_code getHashValue() const override {
645 277 : return hash_combine(this->Expression::getHashValue(), Inst);
646 : }
647 :
648 : // Debugging support
649 0 : void printInternal(raw_ostream &OS, bool PrintEType) const override {
650 0 : if (PrintEType)
651 0 : OS << "ExpressionTypeUnknown, ";
652 0 : this->Expression::printInternal(OS, false);
653 0 : OS << " inst = " << *Inst;
654 0 : }
655 : };
656 :
657 : } // end namespace GVNExpression
658 :
659 : } // end namespace llvm
660 :
661 : #endif // LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
|