annotate include/llvm/Transforms/Scalar/GVNExpression.h @ 121:803732b1fca8

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