annotate include/llvm/Transforms/Scalar/GVNExpression.h @ 148:63bd29f05246

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