- //===- GVNExpression.h - GVN Expression classes -----------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- /// \file 
- /// 
- /// The header file for the GVN pass that contains expression handling 
- /// classes 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H 
- #define LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H 
-   
- #include "llvm/ADT/Hashing.h" 
- #include "llvm/ADT/iterator_range.h" 
- #include "llvm/Analysis/MemorySSA.h" 
- #include "llvm/IR/Constant.h" 
- #include "llvm/IR/Instructions.h" 
- #include "llvm/IR/Value.h" 
- #include "llvm/Support/Allocator.h" 
- #include "llvm/Support/ArrayRecycler.h" 
- #include "llvm/Support/Casting.h" 
- #include "llvm/Support/Compiler.h" 
- #include "llvm/Support/raw_ostream.h" 
- #include <algorithm> 
- #include <cassert> 
- #include <iterator> 
- #include <utility> 
-   
- namespace llvm { 
-   
- class BasicBlock; 
- class Type; 
-   
- namespace GVNExpression { 
-   
- enum ExpressionType { 
-   ET_Base, 
-   ET_Constant, 
-   ET_Variable, 
-   ET_Dead, 
-   ET_Unknown, 
-   ET_BasicStart, 
-   ET_Basic, 
-   ET_AggregateValue, 
-   ET_Phi, 
-   ET_MemoryStart, 
-   ET_Call, 
-   ET_Load, 
-   ET_Store, 
-   ET_MemoryEnd, 
-   ET_BasicEnd 
- }; 
-   
- class Expression { 
- private: 
-   ExpressionType EType; 
-   unsigned Opcode; 
-   mutable hash_code HashVal = 0; 
-   
- public: 
-   Expression(ExpressionType ET = ET_Base, unsigned O = ~2U) 
-       : EType(ET), Opcode(O) {} 
-   Expression(const Expression &) = delete; 
-   Expression &operator=(const Expression &) = delete; 
-   virtual ~Expression(); 
-   
-   static unsigned getEmptyKey() { return ~0U; } 
-   static unsigned getTombstoneKey() { return ~1U; } 
-   
-   bool operator!=(const Expression &Other) const { return !(*this == Other); } 
-   bool operator==(const Expression &Other) const { 
-     if (getOpcode() != Other.getOpcode()) 
-       return false; 
-     if (getOpcode() == getEmptyKey() || getOpcode() == getTombstoneKey()) 
-       return true; 
-     // Compare the expression type for anything but load and store. 
-     // For load and store we set the opcode to zero to make them equal. 
-     if (getExpressionType() != ET_Load && getExpressionType() != ET_Store && 
-         getExpressionType() != Other.getExpressionType()) 
-       return false; 
-   
-     return equals(Other); 
-   } 
-   
-   hash_code getComputedHash() const { 
-     // It's theoretically possible for a thing to hash to zero.  In that case, 
-     // we will just compute the hash a few extra times, which is no worse that 
-     // we did before, which was to compute it always. 
-     if (static_cast<unsigned>(HashVal) == 0) 
-       HashVal = getHashValue(); 
-     return HashVal; 
-   } 
-   
-   virtual bool equals(const Expression &Other) const { return true; } 
-   
-   // Return true if the two expressions are exactly the same, including the 
-   // normally ignored fields. 
-   virtual bool exactlyEquals(const Expression &Other) const { 
-     return getExpressionType() == Other.getExpressionType() && equals(Other); 
-   } 
-   
-   unsigned getOpcode() const { return Opcode; } 
-   void setOpcode(unsigned opcode) { Opcode = opcode; } 
-   ExpressionType getExpressionType() const { return EType; } 
-   
-   // We deliberately leave the expression type out of the hash value. 
-   virtual hash_code getHashValue() const { return getOpcode(); } 
-   
-   // Debugging support 
-   virtual void printInternal(raw_ostream &OS, bool PrintEType) const { 
-     if (PrintEType) 
-       OS << "etype = " << getExpressionType() << ","; 
-     OS << "opcode = " << getOpcode() << ", "; 
-   } 
-   
-   void print(raw_ostream &OS) const { 
-     OS << "{ "; 
-     printInternal(OS, true); 
-     OS << "}"; 
-   } 
-   
-   LLVM_DUMP_METHOD void dump() const; 
- }; 
-   
- inline raw_ostream &operator<<(raw_ostream &OS, const Expression &E) { 
-   E.print(OS); 
-   return OS; 
- } 
-   
- class BasicExpression : public Expression { 
- private: 
-   using RecyclerType = ArrayRecycler<Value *>; 
-   using RecyclerCapacity = RecyclerType::Capacity; 
-   
-   Value **Operands = nullptr; 
-   unsigned MaxOperands; 
-   unsigned NumOperands = 0; 
-   Type *ValueType = nullptr; 
-   
- public: 
-   BasicExpression(unsigned NumOperands) 
-       : BasicExpression(NumOperands, ET_Basic) {} 
-   BasicExpression(unsigned NumOperands, ExpressionType ET) 
-       : Expression(ET), MaxOperands(NumOperands) {} 
-   BasicExpression() = delete; 
-   BasicExpression(const BasicExpression &) = delete; 
-   BasicExpression &operator=(const BasicExpression &) = delete; 
-   ~BasicExpression() override; 
-   
-   static bool classof(const Expression *EB) { 
-     ExpressionType ET = EB->getExpressionType(); 
-     return ET > ET_BasicStart && ET < ET_BasicEnd; 
-   } 
-   
-   /// Swap two operands. Used during GVN to put commutative operands in 
-   /// order. 
-   void swapOperands(unsigned First, unsigned Second) { 
-     std::swap(Operands[First], Operands[Second]); 
-   } 
-   
-   Value *getOperand(unsigned N) const { 
-     assert(Operands && "Operands not allocated"); 
-     assert(N < NumOperands && "Operand out of range"); 
-     return Operands[N]; 
-   } 
-   
-   void setOperand(unsigned N, Value *V) { 
-     assert(Operands && "Operands not allocated before setting"); 
-     assert(N < NumOperands && "Operand out of range"); 
-     Operands[N] = V; 
-   } 
-   
-   unsigned getNumOperands() const { return NumOperands; } 
-   
-   using op_iterator = Value **; 
-   using const_op_iterator = Value *const *; 
-   
-   op_iterator op_begin() { return Operands; } 
-   op_iterator op_end() { return Operands + NumOperands; } 
-   const_op_iterator op_begin() const { return Operands; } 
-   const_op_iterator op_end() const { return Operands + NumOperands; } 
-   iterator_range<op_iterator> operands() { 
-     return iterator_range<op_iterator>(op_begin(), op_end()); 
-   } 
-   iterator_range<const_op_iterator> operands() const { 
-     return iterator_range<const_op_iterator>(op_begin(), op_end()); 
-   } 
-   
-   void op_push_back(Value *Arg) { 
-     assert(NumOperands < MaxOperands && "Tried to add too many operands"); 
-     assert(Operands && "Operandss not allocated before pushing"); 
-     Operands[NumOperands++] = Arg; 
-   } 
-   bool op_empty() const { return getNumOperands() == 0; } 
-   
-   void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator) { 
-     assert(!Operands && "Operands already allocated"); 
-     Operands = Recycler.allocate(RecyclerCapacity::get(MaxOperands), Allocator); 
-   } 
-   void deallocateOperands(RecyclerType &Recycler) { 
-     Recycler.deallocate(RecyclerCapacity::get(MaxOperands), Operands); 
-   } 
-   
-   void setType(Type *T) { ValueType = T; } 
-   Type *getType() const { return ValueType; } 
-   
-   bool equals(const Expression &Other) const override { 
-     if (getOpcode() != Other.getOpcode()) 
-       return false; 
-   
-     const auto &OE = cast<BasicExpression>(Other); 
-     return getType() == OE.getType() && NumOperands == OE.NumOperands && 
-            std::equal(op_begin(), op_end(), OE.op_begin()); 
-   } 
-   
-   hash_code getHashValue() const override { 
-     return hash_combine(this->Expression::getHashValue(), ValueType, 
-                         hash_combine_range(op_begin(), op_end())); 
-   } 
-   
-   // Debugging support 
-   void printInternal(raw_ostream &OS, bool PrintEType) const override { 
-     if (PrintEType) 
-       OS << "ExpressionTypeBasic, "; 
-   
-     this->Expression::printInternal(OS, false); 
-     OS << "operands = {"; 
-     for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 
-       OS << "[" << i << "] = "; 
-       Operands[i]->printAsOperand(OS); 
-       OS << "  "; 
-     } 
-     OS << "} "; 
-   } 
- }; 
-   
- class op_inserter { 
- private: 
-   using Container = BasicExpression; 
-   
-   Container *BE; 
-   
- public: 
-   using iterator_category = std::output_iterator_tag; 
-   using value_type = void; 
-   using difference_type = void; 
-   using pointer = void; 
-   using reference = void; 
-   
-   explicit op_inserter(BasicExpression &E) : BE(&E) {} 
-   explicit op_inserter(BasicExpression *E) : BE(E) {} 
-   
-   op_inserter &operator=(Value *val) { 
-     BE->op_push_back(val); 
-     return *this; 
-   } 
-   op_inserter &operator*() { return *this; } 
-   op_inserter &operator++() { return *this; } 
-   op_inserter &operator++(int) { return *this; } 
- }; 
-   
- class MemoryExpression : public BasicExpression { 
- private: 
-   const MemoryAccess *MemoryLeader; 
-   
- public: 
-   MemoryExpression(unsigned NumOperands, enum ExpressionType EType, 
-                    const MemoryAccess *MemoryLeader) 
-       : BasicExpression(NumOperands, EType), MemoryLeader(MemoryLeader) {} 
-   MemoryExpression() = delete; 
-   MemoryExpression(const MemoryExpression &) = delete; 
-   MemoryExpression &operator=(const MemoryExpression &) = delete; 
-   
-   static bool classof(const Expression *EB) { 
-     return EB->getExpressionType() > ET_MemoryStart && 
-            EB->getExpressionType() < ET_MemoryEnd; 
-   } 
-   
-   hash_code getHashValue() const override { 
-     return hash_combine(this->BasicExpression::getHashValue(), MemoryLeader); 
-   } 
-   
-   bool equals(const Expression &Other) const override { 
-     if (!this->BasicExpression::equals(Other)) 
-       return false; 
-     const MemoryExpression &OtherMCE = cast<MemoryExpression>(Other); 
-   
-     return MemoryLeader == OtherMCE.MemoryLeader; 
-   } 
-   
-   const MemoryAccess *getMemoryLeader() const { return MemoryLeader; } 
-   void setMemoryLeader(const MemoryAccess *ML) { MemoryLeader = ML; } 
- }; 
-   
- class CallExpression final : public MemoryExpression { 
- private: 
-   CallInst *Call; 
-   
- public: 
-   CallExpression(unsigned NumOperands, CallInst *C, 
-                  const MemoryAccess *MemoryLeader) 
-       : MemoryExpression(NumOperands, ET_Call, MemoryLeader), Call(C) {} 
-   CallExpression() = delete; 
-   CallExpression(const CallExpression &) = delete; 
-   CallExpression &operator=(const CallExpression &) = delete; 
-   ~CallExpression() override; 
-   
-   static bool classof(const Expression *EB) { 
-     return EB->getExpressionType() == ET_Call; 
-   } 
-   
-   // Debugging support 
-   void printInternal(raw_ostream &OS, bool PrintEType) const override { 
-     if (PrintEType) 
-       OS << "ExpressionTypeCall, "; 
-     this->BasicExpression::printInternal(OS, false); 
-     OS << " represents call at "; 
-     Call->printAsOperand(OS); 
-   } 
- }; 
-   
- class LoadExpression final : public MemoryExpression { 
- private: 
-   LoadInst *Load; 
-   
- public: 
-   LoadExpression(unsigned NumOperands, LoadInst *L, 
-                  const MemoryAccess *MemoryLeader) 
-       : LoadExpression(ET_Load, NumOperands, L, MemoryLeader) {} 
-   
-   LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L, 
-                  const MemoryAccess *MemoryLeader) 
-       : MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) {} 
-   
-   LoadExpression() = delete; 
-   LoadExpression(const LoadExpression &) = delete; 
-   LoadExpression &operator=(const LoadExpression &) = delete; 
-   ~LoadExpression() override; 
-   
-   static bool classof(const Expression *EB) { 
-     return EB->getExpressionType() == ET_Load; 
-   } 
-   
-   LoadInst *getLoadInst() const { return Load; } 
-   void setLoadInst(LoadInst *L) { Load = L; } 
-   
-   bool equals(const Expression &Other) const override; 
-   bool exactlyEquals(const Expression &Other) const override { 
-     return Expression::exactlyEquals(Other) && 
-            cast<LoadExpression>(Other).getLoadInst() == getLoadInst(); 
-   } 
-   
-   // Debugging support 
-   void printInternal(raw_ostream &OS, bool PrintEType) const override { 
-     if (PrintEType) 
-       OS << "ExpressionTypeLoad, "; 
-     this->BasicExpression::printInternal(OS, false); 
-     OS << " represents Load at "; 
-     Load->printAsOperand(OS); 
-     OS << " with MemoryLeader " << *getMemoryLeader(); 
-   } 
- }; 
-   
- class StoreExpression final : public MemoryExpression { 
- private: 
-   StoreInst *Store; 
-   Value *StoredValue; 
-   
- public: 
-   StoreExpression(unsigned NumOperands, StoreInst *S, Value *StoredValue, 
-                   const MemoryAccess *MemoryLeader) 
-       : MemoryExpression(NumOperands, ET_Store, MemoryLeader), Store(S), 
-         StoredValue(StoredValue) {} 
-   StoreExpression() = delete; 
-   StoreExpression(const StoreExpression &) = delete; 
-   StoreExpression &operator=(const StoreExpression &) = delete; 
-   ~StoreExpression() override; 
-   
-   static bool classof(const Expression *EB) { 
-     return EB->getExpressionType() == ET_Store; 
-   } 
-   
-   StoreInst *getStoreInst() const { return Store; } 
-   Value *getStoredValue() const { return StoredValue; } 
-   
-   bool equals(const Expression &Other) const override; 
-   
-   bool exactlyEquals(const Expression &Other) const override { 
-     return Expression::exactlyEquals(Other) && 
-            cast<StoreExpression>(Other).getStoreInst() == getStoreInst(); 
-   } 
-   
-   // Debugging support 
-   void printInternal(raw_ostream &OS, bool PrintEType) const override { 
-     if (PrintEType) 
-       OS << "ExpressionTypeStore, "; 
-     this->BasicExpression::printInternal(OS, false); 
-     OS << " represents Store  " << *Store; 
-     OS << " with StoredValue "; 
-     StoredValue->printAsOperand(OS); 
-     OS << " and MemoryLeader " << *getMemoryLeader(); 
-   } 
- }; 
-   
- class AggregateValueExpression final : public BasicExpression { 
- private: 
-   unsigned MaxIntOperands; 
-   unsigned NumIntOperands = 0; 
-   unsigned *IntOperands = nullptr; 
-   
- public: 
-   AggregateValueExpression(unsigned NumOperands, unsigned NumIntOperands) 
-       : BasicExpression(NumOperands, ET_AggregateValue), 
-         MaxIntOperands(NumIntOperands) {} 
-   AggregateValueExpression() = delete; 
-   AggregateValueExpression(const AggregateValueExpression &) = delete; 
-   AggregateValueExpression & 
-   operator=(const AggregateValueExpression &) = delete; 
-   ~AggregateValueExpression() override; 
-   
-   static bool classof(const Expression *EB) { 
-     return EB->getExpressionType() == ET_AggregateValue; 
-   } 
-   
-   using int_arg_iterator = unsigned *; 
-   using const_int_arg_iterator = const unsigned *; 
-   
-   int_arg_iterator int_op_begin() { return IntOperands; } 
-   int_arg_iterator int_op_end() { return IntOperands + NumIntOperands; } 
-   const_int_arg_iterator int_op_begin() const { return IntOperands; } 
-   const_int_arg_iterator int_op_end() const { 
-     return IntOperands + NumIntOperands; 
-   } 
-   unsigned int_op_size() const { return NumIntOperands; } 
-   bool int_op_empty() const { return NumIntOperands == 0; } 
-   void int_op_push_back(unsigned IntOperand) { 
-     assert(NumIntOperands < MaxIntOperands && 
-            "Tried to add too many int operands"); 
-     assert(IntOperands && "Operands not allocated before pushing"); 
-     IntOperands[NumIntOperands++] = IntOperand; 
-   } 
-   
-   virtual void allocateIntOperands(BumpPtrAllocator &Allocator) { 
-     assert(!IntOperands && "Operands already allocated"); 
-     IntOperands = Allocator.Allocate<unsigned>(MaxIntOperands); 
-   } 
-   
-   bool equals(const Expression &Other) const override { 
-     if (!this->BasicExpression::equals(Other)) 
-       return false; 
-     const AggregateValueExpression &OE = cast<AggregateValueExpression>(Other); 
-     return NumIntOperands == OE.NumIntOperands && 
-            std::equal(int_op_begin(), int_op_end(), OE.int_op_begin()); 
-   } 
-   
-   hash_code getHashValue() const override { 
-     return hash_combine(this->BasicExpression::getHashValue(), 
-                         hash_combine_range(int_op_begin(), int_op_end())); 
-   } 
-   
-   // Debugging support 
-   void printInternal(raw_ostream &OS, bool PrintEType) const override { 
-     if (PrintEType) 
-       OS << "ExpressionTypeAggregateValue, "; 
-     this->BasicExpression::printInternal(OS, false); 
-     OS << ", intoperands = {"; 
-     for (unsigned i = 0, e = int_op_size(); i != e; ++i) { 
-       OS << "[" << i << "] = " << IntOperands[i] << "  "; 
-     } 
-     OS << "}"; 
-   } 
- }; 
-   
- class int_op_inserter { 
- private: 
-   using Container = AggregateValueExpression; 
-   
-   Container *AVE; 
-   
- public: 
-   using iterator_category = std::output_iterator_tag; 
-   using value_type = void; 
-   using difference_type = void; 
-   using pointer = void; 
-   using reference = void; 
-   
-   explicit int_op_inserter(AggregateValueExpression &E) : AVE(&E) {} 
-   explicit int_op_inserter(AggregateValueExpression *E) : AVE(E) {} 
-   
-   int_op_inserter &operator=(unsigned int val) { 
-     AVE->int_op_push_back(val); 
-     return *this; 
-   } 
-   int_op_inserter &operator*() { return *this; } 
-   int_op_inserter &operator++() { return *this; } 
-   int_op_inserter &operator++(int) { return *this; } 
- }; 
-   
- class PHIExpression final : public BasicExpression { 
- private: 
-   BasicBlock *BB; 
-   
- public: 
-   PHIExpression(unsigned NumOperands, BasicBlock *B) 
-       : BasicExpression(NumOperands, ET_Phi), BB(B) {} 
-   PHIExpression() = delete; 
-   PHIExpression(const PHIExpression &) = delete; 
-   PHIExpression &operator=(const PHIExpression &) = delete; 
-   ~PHIExpression() override; 
-   
-   static bool classof(const Expression *EB) { 
-     return EB->getExpressionType() == ET_Phi; 
-   } 
-   
-   bool equals(const Expression &Other) const override { 
-     if (!this->BasicExpression::equals(Other)) 
-       return false; 
-     const PHIExpression &OE = cast<PHIExpression>(Other); 
-     return BB == OE.BB; 
-   } 
-   
-   hash_code getHashValue() const override { 
-     return hash_combine(this->BasicExpression::getHashValue(), BB); 
-   } 
-   
-   // Debugging support 
-   void printInternal(raw_ostream &OS, bool PrintEType) const override { 
-     if (PrintEType) 
-       OS << "ExpressionTypePhi, "; 
-     this->BasicExpression::printInternal(OS, false); 
-     OS << "bb = " << BB; 
-   } 
- }; 
-   
- class DeadExpression final : public Expression { 
- public: 
-   DeadExpression() : Expression(ET_Dead) {} 
-   DeadExpression(const DeadExpression &) = delete; 
-   DeadExpression &operator=(const DeadExpression &) = delete; 
-   
-   static bool classof(const Expression *E) { 
-     return E->getExpressionType() == ET_Dead; 
-   } 
- }; 
-   
- class VariableExpression final : public Expression { 
- private: 
-   Value *VariableValue; 
-   
- public: 
-   VariableExpression(Value *V) : Expression(ET_Variable), VariableValue(V) {} 
-   VariableExpression() = delete; 
-   VariableExpression(const VariableExpression &) = delete; 
-   VariableExpression &operator=(const VariableExpression &) = delete; 
-   
-   static bool classof(const Expression *EB) { 
-     return EB->getExpressionType() == ET_Variable; 
-   } 
-   
-   Value *getVariableValue() const { return VariableValue; } 
-   void setVariableValue(Value *V) { VariableValue = V; } 
-   
-   bool equals(const Expression &Other) const override { 
-     const VariableExpression &OC = cast<VariableExpression>(Other); 
-     return VariableValue == OC.VariableValue; 
-   } 
-   
-   hash_code getHashValue() const override { 
-     return hash_combine(this->Expression::getHashValue(), 
-                         VariableValue->getType(), VariableValue); 
-   } 
-   
-   // Debugging support 
-   void printInternal(raw_ostream &OS, bool PrintEType) const override { 
-     if (PrintEType) 
-       OS << "ExpressionTypeVariable, "; 
-     this->Expression::printInternal(OS, false); 
-     OS << " variable = " << *VariableValue; 
-   } 
- }; 
-   
- class ConstantExpression final : public Expression { 
- private: 
-   Constant *ConstantValue = nullptr; 
-   
- public: 
-   ConstantExpression() : Expression(ET_Constant) {} 
-   ConstantExpression(Constant *constantValue) 
-       : Expression(ET_Constant), ConstantValue(constantValue) {} 
-   ConstantExpression(const ConstantExpression &) = delete; 
-   ConstantExpression &operator=(const ConstantExpression &) = delete; 
-   
-   static bool classof(const Expression *EB) { 
-     return EB->getExpressionType() == ET_Constant; 
-   } 
-   
-   Constant *getConstantValue() const { return ConstantValue; } 
-   void setConstantValue(Constant *V) { ConstantValue = V; } 
-   
-   bool equals(const Expression &Other) const override { 
-     const ConstantExpression &OC = cast<ConstantExpression>(Other); 
-     return ConstantValue == OC.ConstantValue; 
-   } 
-   
-   hash_code getHashValue() const override { 
-     return hash_combine(this->Expression::getHashValue(), 
-                         ConstantValue->getType(), ConstantValue); 
-   } 
-   
-   // Debugging support 
-   void printInternal(raw_ostream &OS, bool PrintEType) const override { 
-     if (PrintEType) 
-       OS << "ExpressionTypeConstant, "; 
-     this->Expression::printInternal(OS, false); 
-     OS << " constant = " << *ConstantValue; 
-   } 
- }; 
-   
- class UnknownExpression final : public Expression { 
- private: 
-   Instruction *Inst; 
-   
- public: 
-   UnknownExpression(Instruction *I) : Expression(ET_Unknown), Inst(I) {} 
-   UnknownExpression() = delete; 
-   UnknownExpression(const UnknownExpression &) = delete; 
-   UnknownExpression &operator=(const UnknownExpression &) = delete; 
-   
-   static bool classof(const Expression *EB) { 
-     return EB->getExpressionType() == ET_Unknown; 
-   } 
-   
-   Instruction *getInstruction() const { return Inst; } 
-   void setInstruction(Instruction *I) { Inst = I; } 
-   
-   bool equals(const Expression &Other) const override { 
-     const auto &OU = cast<UnknownExpression>(Other); 
-     return Inst == OU.Inst; 
-   } 
-   
-   hash_code getHashValue() const override { 
-     return hash_combine(this->Expression::getHashValue(), Inst); 
-   } 
-   
-   // Debugging support 
-   void printInternal(raw_ostream &OS, bool PrintEType) const override { 
-     if (PrintEType) 
-       OS << "ExpressionTypeUnknown, "; 
-     this->Expression::printInternal(OS, false); 
-     OS << " inst = " << *Inst; 
-   } 
- }; 
-   
- } // end namespace GVNExpression 
-   
- } // end namespace llvm 
-   
- #endif // LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H 
-