Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:41

0001 //===- GVNExpression.h - GVN Expression classes -----------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 /// \file
0010 ///
0011 /// The header file for the GVN pass that contains expression handling
0012 /// classes
0013 //
0014 //===----------------------------------------------------------------------===//
0015 
0016 #ifndef LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
0017 #define LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
0018 
0019 #include "llvm/ADT/Hashing.h"
0020 #include "llvm/ADT/iterator_range.h"
0021 #include "llvm/Analysis/MemorySSA.h"
0022 #include "llvm/IR/Constant.h"
0023 #include "llvm/IR/Instructions.h"
0024 #include "llvm/IR/Value.h"
0025 #include "llvm/Support/Allocator.h"
0026 #include "llvm/Support/ArrayRecycler.h"
0027 #include "llvm/Support/Casting.h"
0028 #include "llvm/Support/Compiler.h"
0029 #include "llvm/Support/raw_ostream.h"
0030 #include <algorithm>
0031 #include <cassert>
0032 #include <iterator>
0033 #include <utility>
0034 
0035 namespace llvm {
0036 
0037 class BasicBlock;
0038 class Type;
0039 
0040 namespace GVNExpression {
0041 
0042 enum ExpressionType {
0043   ET_Base,
0044   ET_Constant,
0045   ET_Variable,
0046   ET_Dead,
0047   ET_Unknown,
0048   ET_BasicStart,
0049   ET_Basic,
0050   ET_AggregateValue,
0051   ET_Phi,
0052   ET_MemoryStart,
0053   ET_Call,
0054   ET_Load,
0055   ET_Store,
0056   ET_MemoryEnd,
0057   ET_BasicEnd
0058 };
0059 
0060 class Expression {
0061 private:
0062   ExpressionType EType;
0063   unsigned Opcode;
0064   mutable hash_code HashVal = 0;
0065 
0066 public:
0067   Expression(ExpressionType ET = ET_Base, unsigned O = ~2U)
0068       : EType(ET), Opcode(O) {}
0069   Expression(const Expression &) = delete;
0070   Expression &operator=(const Expression &) = delete;
0071   virtual ~Expression();
0072 
0073   static unsigned getEmptyKey() { return ~0U; }
0074   static unsigned getTombstoneKey() { return ~1U; }
0075 
0076   bool operator!=(const Expression &Other) const { return !(*this == Other); }
0077   bool operator==(const Expression &Other) const {
0078     if (getOpcode() != Other.getOpcode())
0079       return false;
0080     if (getOpcode() == getEmptyKey() || getOpcode() == getTombstoneKey())
0081       return true;
0082     // Compare the expression type for anything but load and store.
0083     // For load and store we set the opcode to zero to make them equal.
0084     if (getExpressionType() != ET_Load && getExpressionType() != ET_Store &&
0085         getExpressionType() != Other.getExpressionType())
0086       return false;
0087 
0088     return equals(Other);
0089   }
0090 
0091   hash_code getComputedHash() const {
0092     // It's theoretically possible for a thing to hash to zero.  In that case,
0093     // we will just compute the hash a few extra times, which is no worse that
0094     // we did before, which was to compute it always.
0095     if (static_cast<unsigned>(HashVal) == 0)
0096       HashVal = getHashValue();
0097     return HashVal;
0098   }
0099 
0100   virtual bool equals(const Expression &Other) const { return true; }
0101 
0102   // Return true if the two expressions are exactly the same, including the
0103   // normally ignored fields.
0104   virtual bool exactlyEquals(const Expression &Other) const {
0105     return getExpressionType() == Other.getExpressionType() && equals(Other);
0106   }
0107 
0108   unsigned getOpcode() const { return Opcode; }
0109   void setOpcode(unsigned opcode) { Opcode = opcode; }
0110   ExpressionType getExpressionType() const { return EType; }
0111 
0112   // We deliberately leave the expression type out of the hash value.
0113   virtual hash_code getHashValue() const { return getOpcode(); }
0114 
0115   // Debugging support
0116   virtual void printInternal(raw_ostream &OS, bool PrintEType) const {
0117     if (PrintEType)
0118       OS << "etype = " << getExpressionType() << ",";
0119     OS << "opcode = " << getOpcode() << ", ";
0120   }
0121 
0122   void print(raw_ostream &OS) const {
0123     OS << "{ ";
0124     printInternal(OS, true);
0125     OS << "}";
0126   }
0127 
0128   LLVM_DUMP_METHOD void dump() const;
0129 };
0130 
0131 inline raw_ostream &operator<<(raw_ostream &OS, const Expression &E) {
0132   E.print(OS);
0133   return OS;
0134 }
0135 
0136 class BasicExpression : public Expression {
0137 private:
0138   using RecyclerType = ArrayRecycler<Value *>;
0139   using RecyclerCapacity = RecyclerType::Capacity;
0140 
0141   Value **Operands = nullptr;
0142   unsigned MaxOperands;
0143   unsigned NumOperands = 0;
0144   Type *ValueType = nullptr;
0145 
0146 public:
0147   BasicExpression(unsigned NumOperands)
0148       : BasicExpression(NumOperands, ET_Basic) {}
0149   BasicExpression(unsigned NumOperands, ExpressionType ET)
0150       : Expression(ET), MaxOperands(NumOperands) {}
0151   BasicExpression() = delete;
0152   BasicExpression(const BasicExpression &) = delete;
0153   BasicExpression &operator=(const BasicExpression &) = delete;
0154   ~BasicExpression() override;
0155 
0156   static bool classof(const Expression *EB) {
0157     ExpressionType ET = EB->getExpressionType();
0158     return ET > ET_BasicStart && ET < ET_BasicEnd;
0159   }
0160 
0161   /// Swap two operands. Used during GVN to put commutative operands in
0162   /// order.
0163   void swapOperands(unsigned First, unsigned Second) {
0164     std::swap(Operands[First], Operands[Second]);
0165   }
0166 
0167   Value *getOperand(unsigned N) const {
0168     assert(Operands && "Operands not allocated");
0169     assert(N < NumOperands && "Operand out of range");
0170     return Operands[N];
0171   }
0172 
0173   void setOperand(unsigned N, Value *V) {
0174     assert(Operands && "Operands not allocated before setting");
0175     assert(N < NumOperands && "Operand out of range");
0176     Operands[N] = V;
0177   }
0178 
0179   unsigned getNumOperands() const { return NumOperands; }
0180 
0181   using op_iterator = Value **;
0182   using const_op_iterator = Value *const *;
0183 
0184   op_iterator op_begin() { return Operands; }
0185   op_iterator op_end() { return Operands + NumOperands; }
0186   const_op_iterator op_begin() const { return Operands; }
0187   const_op_iterator op_end() const { return Operands + NumOperands; }
0188   iterator_range<op_iterator> operands() {
0189     return iterator_range<op_iterator>(op_begin(), op_end());
0190   }
0191   iterator_range<const_op_iterator> operands() const {
0192     return iterator_range<const_op_iterator>(op_begin(), op_end());
0193   }
0194 
0195   void op_push_back(Value *Arg) {
0196     assert(NumOperands < MaxOperands && "Tried to add too many operands");
0197     assert(Operands && "Operandss not allocated before pushing");
0198     Operands[NumOperands++] = Arg;
0199   }
0200   bool op_empty() const { return getNumOperands() == 0; }
0201 
0202   void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator) {
0203     assert(!Operands && "Operands already allocated");
0204     Operands = Recycler.allocate(RecyclerCapacity::get(MaxOperands), Allocator);
0205   }
0206   void deallocateOperands(RecyclerType &Recycler) {
0207     Recycler.deallocate(RecyclerCapacity::get(MaxOperands), Operands);
0208   }
0209 
0210   void setType(Type *T) { ValueType = T; }
0211   Type *getType() const { return ValueType; }
0212 
0213   bool equals(const Expression &Other) const override {
0214     if (getOpcode() != Other.getOpcode())
0215       return false;
0216 
0217     const auto &OE = cast<BasicExpression>(Other);
0218     return getType() == OE.getType() && NumOperands == OE.NumOperands &&
0219            std::equal(op_begin(), op_end(), OE.op_begin());
0220   }
0221 
0222   hash_code getHashValue() const override {
0223     return hash_combine(this->Expression::getHashValue(), ValueType,
0224                         hash_combine_range(op_begin(), op_end()));
0225   }
0226 
0227   // Debugging support
0228   void printInternal(raw_ostream &OS, bool PrintEType) const override {
0229     if (PrintEType)
0230       OS << "ExpressionTypeBasic, ";
0231 
0232     this->Expression::printInternal(OS, false);
0233     OS << "operands = {";
0234     for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
0235       OS << "[" << i << "] = ";
0236       Operands[i]->printAsOperand(OS);
0237       OS << "  ";
0238     }
0239     OS << "} ";
0240   }
0241 };
0242 
0243 class op_inserter {
0244 private:
0245   using Container = BasicExpression;
0246 
0247   Container *BE;
0248 
0249 public:
0250   using iterator_category = std::output_iterator_tag;
0251   using value_type = void;
0252   using difference_type = void;
0253   using pointer = void;
0254   using reference = void;
0255 
0256   explicit op_inserter(BasicExpression &E) : BE(&E) {}
0257   explicit op_inserter(BasicExpression *E) : BE(E) {}
0258 
0259   op_inserter &operator=(Value *val) {
0260     BE->op_push_back(val);
0261     return *this;
0262   }
0263   op_inserter &operator*() { return *this; }
0264   op_inserter &operator++() { return *this; }
0265   op_inserter &operator++(int) { return *this; }
0266 };
0267 
0268 class MemoryExpression : public BasicExpression {
0269 private:
0270   const MemoryAccess *MemoryLeader;
0271 
0272 public:
0273   MemoryExpression(unsigned NumOperands, enum ExpressionType EType,
0274                    const MemoryAccess *MemoryLeader)
0275       : BasicExpression(NumOperands, EType), MemoryLeader(MemoryLeader) {}
0276   MemoryExpression() = delete;
0277   MemoryExpression(const MemoryExpression &) = delete;
0278   MemoryExpression &operator=(const MemoryExpression &) = delete;
0279 
0280   static bool classof(const Expression *EB) {
0281     return EB->getExpressionType() > ET_MemoryStart &&
0282            EB->getExpressionType() < ET_MemoryEnd;
0283   }
0284 
0285   hash_code getHashValue() const override {
0286     return hash_combine(this->BasicExpression::getHashValue(), MemoryLeader);
0287   }
0288 
0289   bool equals(const Expression &Other) const override {
0290     if (!this->BasicExpression::equals(Other))
0291       return false;
0292     const MemoryExpression &OtherMCE = cast<MemoryExpression>(Other);
0293 
0294     return MemoryLeader == OtherMCE.MemoryLeader;
0295   }
0296 
0297   const MemoryAccess *getMemoryLeader() const { return MemoryLeader; }
0298   void setMemoryLeader(const MemoryAccess *ML) { MemoryLeader = ML; }
0299 };
0300 
0301 class CallExpression final : public MemoryExpression {
0302 private:
0303   CallInst *Call;
0304 
0305 public:
0306   CallExpression(unsigned NumOperands, CallInst *C,
0307                  const MemoryAccess *MemoryLeader)
0308       : MemoryExpression(NumOperands, ET_Call, MemoryLeader), Call(C) {}
0309   CallExpression() = delete;
0310   CallExpression(const CallExpression &) = delete;
0311   CallExpression &operator=(const CallExpression &) = delete;
0312   ~CallExpression() override;
0313 
0314   static bool classof(const Expression *EB) {
0315     return EB->getExpressionType() == ET_Call;
0316   }
0317 
0318   bool equals(const Expression &Other) const override;
0319   bool exactlyEquals(const Expression &Other) const override {
0320     return Expression::exactlyEquals(Other) &&
0321            cast<CallExpression>(Other).Call == Call;
0322   }
0323 
0324   // Debugging support
0325   void printInternal(raw_ostream &OS, bool PrintEType) const override {
0326     if (PrintEType)
0327       OS << "ExpressionTypeCall, ";
0328     this->BasicExpression::printInternal(OS, false);
0329     OS << " represents call at ";
0330     Call->printAsOperand(OS);
0331   }
0332 };
0333 
0334 class LoadExpression final : public MemoryExpression {
0335 private:
0336   LoadInst *Load;
0337 
0338 public:
0339   LoadExpression(unsigned NumOperands, LoadInst *L,
0340                  const MemoryAccess *MemoryLeader)
0341       : LoadExpression(ET_Load, NumOperands, L, MemoryLeader) {}
0342 
0343   LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L,
0344                  const MemoryAccess *MemoryLeader)
0345       : MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) {}
0346 
0347   LoadExpression() = delete;
0348   LoadExpression(const LoadExpression &) = delete;
0349   LoadExpression &operator=(const LoadExpression &) = delete;
0350   ~LoadExpression() override;
0351 
0352   static bool classof(const Expression *EB) {
0353     return EB->getExpressionType() == ET_Load;
0354   }
0355 
0356   LoadInst *getLoadInst() const { return Load; }
0357   void setLoadInst(LoadInst *L) { Load = L; }
0358 
0359   bool equals(const Expression &Other) const override;
0360   bool exactlyEquals(const Expression &Other) const override {
0361     return Expression::exactlyEquals(Other) &&
0362            cast<LoadExpression>(Other).getLoadInst() == getLoadInst();
0363   }
0364 
0365   // Debugging support
0366   void printInternal(raw_ostream &OS, bool PrintEType) const override {
0367     if (PrintEType)
0368       OS << "ExpressionTypeLoad, ";
0369     this->BasicExpression::printInternal(OS, false);
0370     OS << " represents Load at ";
0371     Load->printAsOperand(OS);
0372     OS << " with MemoryLeader " << *getMemoryLeader();
0373   }
0374 };
0375 
0376 class StoreExpression final : public MemoryExpression {
0377 private:
0378   StoreInst *Store;
0379   Value *StoredValue;
0380 
0381 public:
0382   StoreExpression(unsigned NumOperands, StoreInst *S, Value *StoredValue,
0383                   const MemoryAccess *MemoryLeader)
0384       : MemoryExpression(NumOperands, ET_Store, MemoryLeader), Store(S),
0385         StoredValue(StoredValue) {}
0386   StoreExpression() = delete;
0387   StoreExpression(const StoreExpression &) = delete;
0388   StoreExpression &operator=(const StoreExpression &) = delete;
0389   ~StoreExpression() override;
0390 
0391   static bool classof(const Expression *EB) {
0392     return EB->getExpressionType() == ET_Store;
0393   }
0394 
0395   StoreInst *getStoreInst() const { return Store; }
0396   Value *getStoredValue() const { return StoredValue; }
0397 
0398   bool equals(const Expression &Other) const override;
0399 
0400   bool exactlyEquals(const Expression &Other) const override {
0401     return Expression::exactlyEquals(Other) &&
0402            cast<StoreExpression>(Other).getStoreInst() == getStoreInst();
0403   }
0404 
0405   // Debugging support
0406   void printInternal(raw_ostream &OS, bool PrintEType) const override {
0407     if (PrintEType)
0408       OS << "ExpressionTypeStore, ";
0409     this->BasicExpression::printInternal(OS, false);
0410     OS << " represents Store  " << *Store;
0411     OS << " with StoredValue ";
0412     StoredValue->printAsOperand(OS);
0413     OS << " and MemoryLeader " << *getMemoryLeader();
0414   }
0415 };
0416 
0417 class AggregateValueExpression final : public BasicExpression {
0418 private:
0419   unsigned MaxIntOperands;
0420   unsigned NumIntOperands = 0;
0421   unsigned *IntOperands = nullptr;
0422 
0423 public:
0424   AggregateValueExpression(unsigned NumOperands, unsigned NumIntOperands)
0425       : BasicExpression(NumOperands, ET_AggregateValue),
0426         MaxIntOperands(NumIntOperands) {}
0427   AggregateValueExpression() = delete;
0428   AggregateValueExpression(const AggregateValueExpression &) = delete;
0429   AggregateValueExpression &
0430   operator=(const AggregateValueExpression &) = delete;
0431   ~AggregateValueExpression() override;
0432 
0433   static bool classof(const Expression *EB) {
0434     return EB->getExpressionType() == ET_AggregateValue;
0435   }
0436 
0437   using int_arg_iterator = unsigned *;
0438   using const_int_arg_iterator = const unsigned *;
0439 
0440   int_arg_iterator int_op_begin() { return IntOperands; }
0441   int_arg_iterator int_op_end() { return IntOperands + NumIntOperands; }
0442   const_int_arg_iterator int_op_begin() const { return IntOperands; }
0443   const_int_arg_iterator int_op_end() const {
0444     return IntOperands + NumIntOperands;
0445   }
0446   unsigned int_op_size() const { return NumIntOperands; }
0447   bool int_op_empty() const { return NumIntOperands == 0; }
0448   void int_op_push_back(unsigned IntOperand) {
0449     assert(NumIntOperands < MaxIntOperands &&
0450            "Tried to add too many int operands");
0451     assert(IntOperands && "Operands not allocated before pushing");
0452     IntOperands[NumIntOperands++] = IntOperand;
0453   }
0454 
0455   virtual void allocateIntOperands(BumpPtrAllocator &Allocator) {
0456     assert(!IntOperands && "Operands already allocated");
0457     IntOperands = Allocator.Allocate<unsigned>(MaxIntOperands);
0458   }
0459 
0460   bool equals(const Expression &Other) const override {
0461     if (!this->BasicExpression::equals(Other))
0462       return false;
0463     const AggregateValueExpression &OE = cast<AggregateValueExpression>(Other);
0464     return NumIntOperands == OE.NumIntOperands &&
0465            std::equal(int_op_begin(), int_op_end(), OE.int_op_begin());
0466   }
0467 
0468   hash_code getHashValue() const override {
0469     return hash_combine(this->BasicExpression::getHashValue(),
0470                         hash_combine_range(int_op_begin(), int_op_end()));
0471   }
0472 
0473   // Debugging support
0474   void printInternal(raw_ostream &OS, bool PrintEType) const override {
0475     if (PrintEType)
0476       OS << "ExpressionTypeAggregateValue, ";
0477     this->BasicExpression::printInternal(OS, false);
0478     OS << ", intoperands = {";
0479     for (unsigned i = 0, e = int_op_size(); i != e; ++i) {
0480       OS << "[" << i << "] = " << IntOperands[i] << "  ";
0481     }
0482     OS << "}";
0483   }
0484 };
0485 
0486 class int_op_inserter {
0487 private:
0488   using Container = AggregateValueExpression;
0489 
0490   Container *AVE;
0491 
0492 public:
0493   using iterator_category = std::output_iterator_tag;
0494   using value_type = void;
0495   using difference_type = void;
0496   using pointer = void;
0497   using reference = void;
0498 
0499   explicit int_op_inserter(AggregateValueExpression &E) : AVE(&E) {}
0500   explicit int_op_inserter(AggregateValueExpression *E) : AVE(E) {}
0501 
0502   int_op_inserter &operator=(unsigned int val) {
0503     AVE->int_op_push_back(val);
0504     return *this;
0505   }
0506   int_op_inserter &operator*() { return *this; }
0507   int_op_inserter &operator++() { return *this; }
0508   int_op_inserter &operator++(int) { return *this; }
0509 };
0510 
0511 class PHIExpression final : public BasicExpression {
0512 private:
0513   BasicBlock *BB;
0514 
0515 public:
0516   PHIExpression(unsigned NumOperands, BasicBlock *B)
0517       : BasicExpression(NumOperands, ET_Phi), BB(B) {}
0518   PHIExpression() = delete;
0519   PHIExpression(const PHIExpression &) = delete;
0520   PHIExpression &operator=(const PHIExpression &) = delete;
0521   ~PHIExpression() override;
0522 
0523   static bool classof(const Expression *EB) {
0524     return EB->getExpressionType() == ET_Phi;
0525   }
0526 
0527   bool equals(const Expression &Other) const override {
0528     if (!this->BasicExpression::equals(Other))
0529       return false;
0530     const PHIExpression &OE = cast<PHIExpression>(Other);
0531     return BB == OE.BB;
0532   }
0533 
0534   hash_code getHashValue() const override {
0535     return hash_combine(this->BasicExpression::getHashValue(), BB);
0536   }
0537 
0538   // Debugging support
0539   void printInternal(raw_ostream &OS, bool PrintEType) const override {
0540     if (PrintEType)
0541       OS << "ExpressionTypePhi, ";
0542     this->BasicExpression::printInternal(OS, false);
0543     OS << "bb = " << BB;
0544   }
0545 };
0546 
0547 class DeadExpression final : public Expression {
0548 public:
0549   DeadExpression() : Expression(ET_Dead) {}
0550   DeadExpression(const DeadExpression &) = delete;
0551   DeadExpression &operator=(const DeadExpression &) = delete;
0552 
0553   static bool classof(const Expression *E) {
0554     return E->getExpressionType() == ET_Dead;
0555   }
0556 };
0557 
0558 class VariableExpression final : public Expression {
0559 private:
0560   Value *VariableValue;
0561 
0562 public:
0563   VariableExpression(Value *V) : Expression(ET_Variable), VariableValue(V) {}
0564   VariableExpression() = delete;
0565   VariableExpression(const VariableExpression &) = delete;
0566   VariableExpression &operator=(const VariableExpression &) = delete;
0567 
0568   static bool classof(const Expression *EB) {
0569     return EB->getExpressionType() == ET_Variable;
0570   }
0571 
0572   Value *getVariableValue() const { return VariableValue; }
0573   void setVariableValue(Value *V) { VariableValue = V; }
0574 
0575   bool equals(const Expression &Other) const override {
0576     const VariableExpression &OC = cast<VariableExpression>(Other);
0577     return VariableValue == OC.VariableValue;
0578   }
0579 
0580   hash_code getHashValue() const override {
0581     return hash_combine(this->Expression::getHashValue(),
0582                         VariableValue->getType(), VariableValue);
0583   }
0584 
0585   // Debugging support
0586   void printInternal(raw_ostream &OS, bool PrintEType) const override {
0587     if (PrintEType)
0588       OS << "ExpressionTypeVariable, ";
0589     this->Expression::printInternal(OS, false);
0590     OS << " variable = " << *VariableValue;
0591   }
0592 };
0593 
0594 class ConstantExpression final : public Expression {
0595 private:
0596   Constant *ConstantValue = nullptr;
0597 
0598 public:
0599   ConstantExpression() : Expression(ET_Constant) {}
0600   ConstantExpression(Constant *constantValue)
0601       : Expression(ET_Constant), ConstantValue(constantValue) {}
0602   ConstantExpression(const ConstantExpression &) = delete;
0603   ConstantExpression &operator=(const ConstantExpression &) = delete;
0604 
0605   static bool classof(const Expression *EB) {
0606     return EB->getExpressionType() == ET_Constant;
0607   }
0608 
0609   Constant *getConstantValue() const { return ConstantValue; }
0610   void setConstantValue(Constant *V) { ConstantValue = V; }
0611 
0612   bool equals(const Expression &Other) const override {
0613     const ConstantExpression &OC = cast<ConstantExpression>(Other);
0614     return ConstantValue == OC.ConstantValue;
0615   }
0616 
0617   hash_code getHashValue() const override {
0618     return hash_combine(this->Expression::getHashValue(),
0619                         ConstantValue->getType(), ConstantValue);
0620   }
0621 
0622   // Debugging support
0623   void printInternal(raw_ostream &OS, bool PrintEType) const override {
0624     if (PrintEType)
0625       OS << "ExpressionTypeConstant, ";
0626     this->Expression::printInternal(OS, false);
0627     OS << " constant = " << *ConstantValue;
0628   }
0629 };
0630 
0631 class UnknownExpression final : public Expression {
0632 private:
0633   Instruction *Inst;
0634 
0635 public:
0636   UnknownExpression(Instruction *I) : Expression(ET_Unknown), Inst(I) {}
0637   UnknownExpression() = delete;
0638   UnknownExpression(const UnknownExpression &) = delete;
0639   UnknownExpression &operator=(const UnknownExpression &) = delete;
0640 
0641   static bool classof(const Expression *EB) {
0642     return EB->getExpressionType() == ET_Unknown;
0643   }
0644 
0645   Instruction *getInstruction() const { return Inst; }
0646   void setInstruction(Instruction *I) { Inst = I; }
0647 
0648   bool equals(const Expression &Other) const override {
0649     const auto &OU = cast<UnknownExpression>(Other);
0650     return Inst == OU.Inst;
0651   }
0652 
0653   hash_code getHashValue() const override {
0654     return hash_combine(this->Expression::getHashValue(), Inst);
0655   }
0656 
0657   // Debugging support
0658   void printInternal(raw_ostream &OS, bool PrintEType) const override {
0659     if (PrintEType)
0660       OS << "ExpressionTypeUnknown, ";
0661     this->Expression::printInternal(OS, false);
0662     OS << " inst = " << *Inst;
0663   }
0664 };
0665 
0666 } // end namespace GVNExpression
0667 
0668 } // end namespace llvm
0669 
0670 #endif // LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H