1 //======- GVNExpression.h - GVN Expression classes --------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// The header file for the GVN pass that contains expression handling
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
17 #define LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
19 #include "llvm/ADT/Hashing.h"
20 #include "llvm/ADT/iterator_range.h"
21 #include "llvm/Analysis/MemorySSA.h"
22 #include "llvm/IR/Constant.h"
23 #include "llvm/IR/Instructions.h"
24 #include "llvm/IR/Value.h"
25 #include "llvm/Support/Allocator.h"
26 #include "llvm/Support/ArrayRecycler.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/raw_ostream.h"
37 namespace GVNExpression {
62 Expression(ExpressionType ET = ET_Base, unsigned O = ~2U)
63 : EType(ET), Opcode(O) {}
64 Expression(const Expression &) = delete;
65 Expression &operator=(const Expression &) = delete;
66 virtual ~Expression();
68 static unsigned getEmptyKey() { return ~0U; }
69 static unsigned getTombstoneKey() { return ~1U; }
70 bool operator!=(const Expression &Other) const { return !(*this == Other); }
71 bool operator==(const Expression &Other) const {
72 if (getOpcode() != Other.getOpcode())
74 if (getOpcode() == getEmptyKey() || getOpcode() == getTombstoneKey())
76 // Compare the expression type for anything but load and store.
77 // For load and store we set the opcode to zero to make them equal.
78 if (getExpressionType() != ET_Load && getExpressionType() != ET_Store &&
79 getExpressionType() != Other.getExpressionType())
85 virtual bool equals(const Expression &Other) const { return true; }
87 unsigned getOpcode() const { return Opcode; }
88 void setOpcode(unsigned opcode) { Opcode = opcode; }
89 ExpressionType getExpressionType() const { return EType; }
91 // We deliberately leave the expression type out of the hash value.
92 virtual hash_code getHashValue() const { return getOpcode(); }
97 virtual void printInternal(raw_ostream &OS, bool PrintEType) const {
99 OS << "etype = " << getExpressionType() << ",";
100 OS << "opcode = " << getOpcode() << ", ";
103 void print(raw_ostream &OS) const {
105 printInternal(OS, true);
109 LLVM_DUMP_METHOD void dump() const {
115 inline raw_ostream &operator<<(raw_ostream &OS, const Expression &E) {
120 class BasicExpression : public Expression {
122 typedef ArrayRecycler<Value *> RecyclerType;
123 typedef RecyclerType::Capacity RecyclerCapacity;
125 unsigned MaxOperands;
126 unsigned NumOperands;
130 BasicExpression(unsigned NumOperands)
131 : BasicExpression(NumOperands, ET_Basic) {}
132 BasicExpression(unsigned NumOperands, ExpressionType ET)
133 : Expression(ET), Operands(nullptr), MaxOperands(NumOperands),
134 NumOperands(0), ValueType(nullptr) {}
135 BasicExpression() = delete;
136 BasicExpression(const BasicExpression &) = delete;
137 BasicExpression &operator=(const BasicExpression &) = delete;
138 ~BasicExpression() override;
140 static bool classof(const Expression *EB) {
141 ExpressionType ET = EB->getExpressionType();
142 return ET > ET_BasicStart && ET < ET_BasicEnd;
145 /// \brief Swap two operands. Used during GVN to put commutative operands in
147 void swapOperands(unsigned First, unsigned Second) {
148 std::swap(Operands[First], Operands[Second]);
151 Value *getOperand(unsigned N) const {
152 assert(Operands && "Operands not allocated");
153 assert(N < NumOperands && "Operand out of range");
157 void setOperand(unsigned N, Value *V) {
158 assert(Operands && "Operands not allocated before setting");
159 assert(N < NumOperands && "Operand out of range");
163 unsigned getNumOperands() const { return NumOperands; }
165 typedef Value **op_iterator;
166 typedef Value *const *const_op_iterator;
167 op_iterator op_begin() { return Operands; }
168 op_iterator op_end() { return Operands + NumOperands; }
169 const_op_iterator op_begin() const { return Operands; }
170 const_op_iterator op_end() const { return Operands + NumOperands; }
171 iterator_range<op_iterator> operands() {
172 return iterator_range<op_iterator>(op_begin(), op_end());
174 iterator_range<const_op_iterator> operands() const {
175 return iterator_range<const_op_iterator>(op_begin(), op_end());
178 void op_push_back(Value *Arg) {
179 assert(NumOperands < MaxOperands && "Tried to add too many operands");
180 assert(Operands && "Operandss not allocated before pushing");
181 Operands[NumOperands++] = Arg;
183 bool op_empty() const { return getNumOperands() == 0; }
185 void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator) {
186 assert(!Operands && "Operands already allocated");
187 Operands = Recycler.allocate(RecyclerCapacity::get(MaxOperands), Allocator);
189 void deallocateOperands(RecyclerType &Recycler) {
190 Recycler.deallocate(RecyclerCapacity::get(MaxOperands), Operands);
193 void setType(Type *T) { ValueType = T; }
194 Type *getType() const { return ValueType; }
196 bool equals(const Expression &Other) const override {
197 if (getOpcode() != Other.getOpcode())
200 const auto &OE = cast<BasicExpression>(Other);
201 return getType() == OE.getType() && NumOperands == OE.NumOperands &&
202 std::equal(op_begin(), op_end(), OE.op_begin());
205 hash_code getHashValue() const override {
206 return hash_combine(this->Expression::getHashValue(), ValueType,
207 hash_combine_range(op_begin(), op_end()));
213 void printInternal(raw_ostream &OS, bool PrintEType) const override {
215 OS << "ExpressionTypeBasic, ";
217 this->Expression::printInternal(OS, false);
218 OS << "operands = {";
219 for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
220 OS << "[" << i << "] = ";
221 Operands[i]->printAsOperand(OS);
229 : public std::iterator<std::output_iterator_tag, void, void, void, void> {
231 typedef BasicExpression Container;
235 explicit op_inserter(BasicExpression &E) : BE(&E) {}
236 explicit op_inserter(BasicExpression *E) : BE(E) {}
238 op_inserter &operator=(Value *val) {
239 BE->op_push_back(val);
242 op_inserter &operator*() { return *this; }
243 op_inserter &operator++() { return *this; }
244 op_inserter &operator++(int) { return *this; }
247 class MemoryExpression : public BasicExpression {
249 const MemoryAccess *MemoryLeader;
252 MemoryExpression(unsigned NumOperands, enum ExpressionType EType,
253 const MemoryAccess *MemoryLeader)
254 : BasicExpression(NumOperands, EType), MemoryLeader(MemoryLeader){};
256 MemoryExpression() = delete;
257 MemoryExpression(const MemoryExpression &) = delete;
258 MemoryExpression &operator=(const MemoryExpression &) = delete;
259 static bool classof(const Expression *EB) {
260 return EB->getExpressionType() > ET_MemoryStart &&
261 EB->getExpressionType() < ET_MemoryEnd;
263 hash_code getHashValue() const override {
264 return hash_combine(this->BasicExpression::getHashValue(), MemoryLeader);
267 bool equals(const Expression &Other) const override {
268 if (!this->BasicExpression::equals(Other))
270 const MemoryExpression &OtherMCE = cast<MemoryExpression>(Other);
272 return MemoryLeader == OtherMCE.MemoryLeader;
275 const MemoryAccess *getMemoryLeader() const { return MemoryLeader; }
276 void setMemoryLeader(const MemoryAccess *ML) { MemoryLeader = ML; }
279 class CallExpression final : public MemoryExpression {
284 CallExpression(unsigned NumOperands, CallInst *C,
285 const MemoryAccess *MemoryLeader)
286 : MemoryExpression(NumOperands, ET_Call, MemoryLeader), Call(C) {}
287 CallExpression() = delete;
288 CallExpression(const CallExpression &) = delete;
289 CallExpression &operator=(const CallExpression &) = delete;
290 ~CallExpression() override;
292 static bool classof(const Expression *EB) {
293 return EB->getExpressionType() == ET_Call;
299 void printInternal(raw_ostream &OS, bool PrintEType) const override {
301 OS << "ExpressionTypeCall, ";
302 this->BasicExpression::printInternal(OS, false);
303 OS << " represents call at ";
304 Call->printAsOperand(OS);
308 class LoadExpression final : public MemoryExpression {
314 LoadExpression(unsigned NumOperands, LoadInst *L,
315 const MemoryAccess *MemoryLeader)
316 : LoadExpression(ET_Load, NumOperands, L, MemoryLeader) {}
317 LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L,
318 const MemoryAccess *MemoryLeader)
319 : MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) {
320 Alignment = L ? L->getAlignment() : 0;
322 LoadExpression() = delete;
323 LoadExpression(const LoadExpression &) = delete;
324 LoadExpression &operator=(const LoadExpression &) = delete;
325 ~LoadExpression() override;
327 static bool classof(const Expression *EB) {
328 return EB->getExpressionType() == ET_Load;
331 LoadInst *getLoadInst() const { return Load; }
332 void setLoadInst(LoadInst *L) { Load = L; }
334 unsigned getAlignment() const { return Alignment; }
335 void setAlignment(unsigned Align) { Alignment = Align; }
337 bool equals(const Expression &Other) const override;
342 void printInternal(raw_ostream &OS, bool PrintEType) const override {
344 OS << "ExpressionTypeLoad, ";
345 this->BasicExpression::printInternal(OS, false);
346 OS << " represents Load at ";
347 Load->printAsOperand(OS);
348 OS << " with MemoryLeader " << *getMemoryLeader();
352 class StoreExpression final : public MemoryExpression {
358 StoreExpression(unsigned NumOperands, StoreInst *S, Value *StoredValue,
359 const MemoryAccess *MemoryLeader)
360 : MemoryExpression(NumOperands, ET_Store, MemoryLeader), Store(S),
361 StoredValue(StoredValue) {}
362 StoreExpression() = delete;
363 StoreExpression(const StoreExpression &) = delete;
364 StoreExpression &operator=(const StoreExpression &) = delete;
365 ~StoreExpression() override;
367 static bool classof(const Expression *EB) {
368 return EB->getExpressionType() == ET_Store;
371 StoreInst *getStoreInst() const { return Store; }
372 Value *getStoredValue() const { return StoredValue; }
374 bool equals(const Expression &Other) const override;
378 void printInternal(raw_ostream &OS, bool PrintEType) const override {
380 OS << "ExpressionTypeStore, ";
381 this->BasicExpression::printInternal(OS, false);
382 OS << " represents Store " << *Store;
383 OS << " with MemoryLeader " << *getMemoryLeader();
387 class AggregateValueExpression final : public BasicExpression {
389 unsigned MaxIntOperands;
390 unsigned NumIntOperands;
391 unsigned *IntOperands;
394 AggregateValueExpression(unsigned NumOperands, unsigned NumIntOperands)
395 : BasicExpression(NumOperands, ET_AggregateValue),
396 MaxIntOperands(NumIntOperands), NumIntOperands(0),
397 IntOperands(nullptr) {}
398 AggregateValueExpression() = delete;
399 AggregateValueExpression(const AggregateValueExpression &) = delete;
400 AggregateValueExpression &
401 operator=(const AggregateValueExpression &) = delete;
402 ~AggregateValueExpression() override;
404 static bool classof(const Expression *EB) {
405 return EB->getExpressionType() == ET_AggregateValue;
408 typedef unsigned *int_arg_iterator;
409 typedef const unsigned *const_int_arg_iterator;
411 int_arg_iterator int_op_begin() { return IntOperands; }
412 int_arg_iterator int_op_end() { return IntOperands + NumIntOperands; }
413 const_int_arg_iterator int_op_begin() const { return IntOperands; }
414 const_int_arg_iterator int_op_end() const {
415 return IntOperands + NumIntOperands;
417 unsigned int_op_size() const { return NumIntOperands; }
418 bool int_op_empty() const { return NumIntOperands == 0; }
419 void int_op_push_back(unsigned IntOperand) {
420 assert(NumIntOperands < MaxIntOperands &&
421 "Tried to add too many int operands");
422 assert(IntOperands && "Operands not allocated before pushing");
423 IntOperands[NumIntOperands++] = IntOperand;
426 virtual void allocateIntOperands(BumpPtrAllocator &Allocator) {
427 assert(!IntOperands && "Operands already allocated");
428 IntOperands = Allocator.Allocate<unsigned>(MaxIntOperands);
431 bool equals(const Expression &Other) const override {
432 if (!this->BasicExpression::equals(Other))
434 const AggregateValueExpression &OE = cast<AggregateValueExpression>(Other);
435 return NumIntOperands == OE.NumIntOperands &&
436 std::equal(int_op_begin(), int_op_end(), OE.int_op_begin());
439 hash_code getHashValue() const override {
440 return hash_combine(this->BasicExpression::getHashValue(),
441 hash_combine_range(int_op_begin(), int_op_end()));
447 void printInternal(raw_ostream &OS, bool PrintEType) const override {
449 OS << "ExpressionTypeAggregateValue, ";
450 this->BasicExpression::printInternal(OS, false);
451 OS << ", intoperands = {";
452 for (unsigned i = 0, e = int_op_size(); i != e; ++i) {
453 OS << "[" << i << "] = " << IntOperands[i] << " ";
459 class int_op_inserter
460 : public std::iterator<std::output_iterator_tag, void, void, void, void> {
462 typedef AggregateValueExpression Container;
466 explicit int_op_inserter(AggregateValueExpression &E) : AVE(&E) {}
467 explicit int_op_inserter(AggregateValueExpression *E) : AVE(E) {}
469 int_op_inserter &operator=(unsigned int val) {
470 AVE->int_op_push_back(val);
473 int_op_inserter &operator*() { return *this; }
474 int_op_inserter &operator++() { return *this; }
475 int_op_inserter &operator++(int) { return *this; }
478 class PHIExpression final : public BasicExpression {
483 PHIExpression(unsigned NumOperands, BasicBlock *B)
484 : BasicExpression(NumOperands, ET_Phi), BB(B) {}
485 PHIExpression() = delete;
486 PHIExpression(const PHIExpression &) = delete;
487 PHIExpression &operator=(const PHIExpression &) = delete;
488 ~PHIExpression() override;
490 static bool classof(const Expression *EB) {
491 return EB->getExpressionType() == ET_Phi;
494 bool equals(const Expression &Other) const override {
495 if (!this->BasicExpression::equals(Other))
497 const PHIExpression &OE = cast<PHIExpression>(Other);
501 hash_code getHashValue() const override {
502 return hash_combine(this->BasicExpression::getHashValue(), BB);
508 void printInternal(raw_ostream &OS, bool PrintEType) const override {
510 OS << "ExpressionTypePhi, ";
511 this->BasicExpression::printInternal(OS, false);
516 class VariableExpression final : public Expression {
518 Value *VariableValue;
521 VariableExpression(Value *V) : Expression(ET_Variable), VariableValue(V) {}
522 VariableExpression() = delete;
523 VariableExpression(const VariableExpression &) = delete;
524 VariableExpression &operator=(const VariableExpression &) = delete;
526 static bool classof(const Expression *EB) {
527 return EB->getExpressionType() == ET_Variable;
530 Value *getVariableValue() const { return VariableValue; }
531 void setVariableValue(Value *V) { VariableValue = V; }
533 bool equals(const Expression &Other) const override {
534 const VariableExpression &OC = cast<VariableExpression>(Other);
535 return VariableValue == OC.VariableValue;
538 hash_code getHashValue() const override {
539 return hash_combine(this->Expression::getHashValue(),
540 VariableValue->getType(), VariableValue);
546 void printInternal(raw_ostream &OS, bool PrintEType) const override {
548 OS << "ExpressionTypeVariable, ";
549 this->Expression::printInternal(OS, false);
550 OS << " variable = " << *VariableValue;
554 class ConstantExpression final : public Expression {
556 Constant *ConstantValue = nullptr;
559 ConstantExpression() : Expression(ET_Constant) {}
560 ConstantExpression(Constant *constantValue)
561 : Expression(ET_Constant), ConstantValue(constantValue) {}
562 ConstantExpression(const ConstantExpression &) = delete;
563 ConstantExpression &operator=(const ConstantExpression &) = delete;
565 static bool classof(const Expression *EB) {
566 return EB->getExpressionType() == ET_Constant;
569 Constant *getConstantValue() const { return ConstantValue; }
570 void setConstantValue(Constant *V) { ConstantValue = V; }
572 bool equals(const Expression &Other) const override {
573 const ConstantExpression &OC = cast<ConstantExpression>(Other);
574 return ConstantValue == OC.ConstantValue;
577 hash_code getHashValue() const override {
578 return hash_combine(this->Expression::getHashValue(),
579 ConstantValue->getType(), ConstantValue);
585 void printInternal(raw_ostream &OS, bool PrintEType) const override {
587 OS << "ExpressionTypeConstant, ";
588 this->Expression::printInternal(OS, false);
589 OS << " constant = " << *ConstantValue;
593 class UnknownExpression final : public Expression {
598 UnknownExpression(Instruction *I) : Expression(ET_Unknown), Inst(I) {}
599 UnknownExpression() = delete;
600 UnknownExpression(const UnknownExpression &) = delete;
601 UnknownExpression &operator=(const UnknownExpression &) = delete;
603 static bool classof(const Expression *EB) {
604 return EB->getExpressionType() == ET_Unknown;
607 Instruction *getInstruction() const { return Inst; }
608 void setInstruction(Instruction *I) { Inst = I; }
610 bool equals(const Expression &Other) const override {
611 const auto &OU = cast<UnknownExpression>(Other);
612 return Inst == OU.Inst;
615 hash_code getHashValue() const override {
616 return hash_combine(this->Expression::getHashValue(), Inst);
622 void printInternal(raw_ostream &OS, bool PrintEType) const override {
624 OS << "ExpressionTypeUnknown, ";
625 this->Expression::printInternal(OS, false);
626 OS << " inst = " << *Inst;
630 } // end namespace GVNExpression
632 } // end namespace llvm
634 #endif // LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H