LCOV - code coverage report
Current view: top level - include/llvm/Transforms/Scalar - GVNExpression.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 85 209 40.7 %
Date: 2018-10-20 13:21:21 Functions: 16 72 22.2 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.13