Coverage Report

Created: 2019-07-24 05:18

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