2017-01-18 01:57:48 +01:00
|
|
|
//======- GVNExpression.h - GVN Expression classes --------------*- C++ -*-===//
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// \file
|
|
|
|
///
|
|
|
|
/// The header file for the GVN pass that contains expression handling
|
|
|
|
/// classes
|
|
|
|
///
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
|
|
|
|
#define LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
|
|
|
|
|
|
|
|
#include "llvm/ADT/Hashing.h"
|
2017-01-18 01:57:48 +01:00
|
|
|
#include "llvm/ADT/iterator_range.h"
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
#include "llvm/IR/Constant.h"
|
|
|
|
#include "llvm/IR/Instructions.h"
|
|
|
|
#include "llvm/IR/Value.h"
|
|
|
|
#include "llvm/Support/Allocator.h"
|
|
|
|
#include "llvm/Support/ArrayRecycler.h"
|
2017-01-18 01:57:48 +01:00
|
|
|
#include "llvm/Support/Casting.h"
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2016-12-31 08:34:36 +01:00
|
|
|
#include "llvm/Transforms/Utils/MemorySSA.h"
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
#include <algorithm>
|
2017-01-18 01:57:48 +01:00
|
|
|
#include <cassert>
|
|
|
|
#include <iterator>
|
|
|
|
#include <utility>
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
|
|
|
namespace GVNExpression {
|
|
|
|
|
|
|
|
enum ExpressionType {
|
|
|
|
ET_Base,
|
|
|
|
ET_Constant,
|
|
|
|
ET_Variable,
|
2017-01-02 19:00:53 +01:00
|
|
|
ET_Unknown,
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
ET_BasicStart,
|
|
|
|
ET_Basic,
|
|
|
|
ET_Call,
|
|
|
|
ET_AggregateValue,
|
|
|
|
ET_Phi,
|
|
|
|
ET_Load,
|
|
|
|
ET_Store,
|
|
|
|
ET_BasicEnd
|
|
|
|
};
|
|
|
|
|
|
|
|
class Expression {
|
|
|
|
private:
|
|
|
|
ExpressionType EType;
|
|
|
|
unsigned Opcode;
|
|
|
|
|
|
|
|
public:
|
|
|
|
Expression(ExpressionType ET = ET_Base, unsigned O = ~2U)
|
|
|
|
: EType(ET), Opcode(O) {}
|
2017-01-18 01:57:48 +01:00
|
|
|
Expression(const Expression &) = delete;
|
|
|
|
Expression &operator=(const Expression &) = delete;
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
virtual ~Expression();
|
|
|
|
|
|
|
|
static unsigned getEmptyKey() { return ~0U; }
|
|
|
|
static unsigned getTombstoneKey() { return ~1U; }
|
|
|
|
|
|
|
|
bool operator==(const Expression &Other) const {
|
|
|
|
if (getOpcode() != Other.getOpcode())
|
|
|
|
return false;
|
|
|
|
if (getOpcode() == getEmptyKey() || getOpcode() == getTombstoneKey())
|
|
|
|
return true;
|
|
|
|
// Compare the expression type for anything but load and store.
|
|
|
|
// For load and store we set the opcode to zero.
|
|
|
|
// This is needed for load coercion.
|
2016-12-26 21:06:58 +01:00
|
|
|
if (getExpressionType() != ET_Load && getExpressionType() != ET_Store &&
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
getExpressionType() != Other.getExpressionType())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return equals(Other);
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool equals(const Expression &Other) const { return true; }
|
|
|
|
|
|
|
|
unsigned getOpcode() const { return Opcode; }
|
|
|
|
void setOpcode(unsigned opcode) { Opcode = opcode; }
|
|
|
|
ExpressionType getExpressionType() const { return EType; }
|
|
|
|
|
|
|
|
virtual hash_code getHashValue() const {
|
|
|
|
return hash_combine(getExpressionType(), getOpcode());
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Debugging support
|
|
|
|
//
|
|
|
|
virtual void printInternal(raw_ostream &OS, bool PrintEType) const {
|
|
|
|
if (PrintEType)
|
|
|
|
OS << "etype = " << getExpressionType() << ",";
|
|
|
|
OS << "opcode = " << getOpcode() << ", ";
|
|
|
|
}
|
|
|
|
|
|
|
|
void print(raw_ostream &OS) const {
|
|
|
|
OS << "{ ";
|
|
|
|
printInternal(OS, true);
|
|
|
|
OS << "}";
|
|
|
|
}
|
2017-01-18 01:57:48 +01:00
|
|
|
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
void dump() const { print(dbgs()); }
|
|
|
|
};
|
|
|
|
|
|
|
|
inline raw_ostream &operator<<(raw_ostream &OS, const Expression &E) {
|
|
|
|
E.print(OS);
|
|
|
|
return OS;
|
|
|
|
}
|
|
|
|
|
|
|
|
class BasicExpression : public Expression {
|
|
|
|
private:
|
|
|
|
typedef ArrayRecycler<Value *> RecyclerType;
|
|
|
|
typedef RecyclerType::Capacity RecyclerCapacity;
|
|
|
|
Value **Operands;
|
|
|
|
unsigned MaxOperands;
|
|
|
|
unsigned NumOperands;
|
|
|
|
Type *ValueType;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BasicExpression(unsigned NumOperands)
|
|
|
|
: BasicExpression(NumOperands, ET_Basic) {}
|
|
|
|
BasicExpression(unsigned NumOperands, ExpressionType ET)
|
|
|
|
: Expression(ET), Operands(nullptr), MaxOperands(NumOperands),
|
|
|
|
NumOperands(0), ValueType(nullptr) {}
|
|
|
|
BasicExpression() = delete;
|
2017-01-18 01:57:48 +01:00
|
|
|
BasicExpression(const BasicExpression &) = delete;
|
|
|
|
BasicExpression &operator=(const BasicExpression &) = delete;
|
|
|
|
~BasicExpression() override;
|
|
|
|
|
|
|
|
static bool classof(const Expression *EB) {
|
|
|
|
ExpressionType ET = EB->getExpressionType();
|
|
|
|
return ET > ET_BasicStart && ET < ET_BasicEnd;
|
|
|
|
}
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
|
|
|
/// \brief Swap two operands. Used during GVN to put commutative operands in
|
|
|
|
/// order.
|
|
|
|
void swapOperands(unsigned First, unsigned Second) {
|
|
|
|
std::swap(Operands[First], Operands[Second]);
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *getOperand(unsigned N) const {
|
|
|
|
assert(Operands && "Operands not allocated");
|
|
|
|
assert(N < NumOperands && "Operand out of range");
|
|
|
|
return Operands[N];
|
|
|
|
}
|
|
|
|
|
|
|
|
void setOperand(unsigned N, Value *V) {
|
|
|
|
assert(Operands && "Operands not allocated before setting");
|
|
|
|
assert(N < NumOperands && "Operand out of range");
|
|
|
|
Operands[N] = V;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned getNumOperands() const { return NumOperands; }
|
|
|
|
|
|
|
|
typedef Value **op_iterator;
|
2016-12-25 23:10:37 +01:00
|
|
|
typedef Value *const *const_op_iterator;
|
|
|
|
op_iterator op_begin() { return Operands; }
|
|
|
|
op_iterator op_end() { return Operands + NumOperands; }
|
|
|
|
const_op_iterator op_begin() const { return Operands; }
|
|
|
|
const_op_iterator op_end() const { return Operands + NumOperands; }
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
iterator_range<op_iterator> operands() {
|
2016-12-25 23:10:37 +01:00
|
|
|
return iterator_range<op_iterator>(op_begin(), op_end());
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
2016-12-25 23:10:37 +01:00
|
|
|
iterator_range<const_op_iterator> operands() const {
|
|
|
|
return iterator_range<const_op_iterator>(op_begin(), op_end());
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
|
|
|
|
2016-12-25 23:10:37 +01:00
|
|
|
void op_push_back(Value *Arg) {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
assert(NumOperands < MaxOperands && "Tried to add too many operands");
|
|
|
|
assert(Operands && "Operandss not allocated before pushing");
|
|
|
|
Operands[NumOperands++] = Arg;
|
|
|
|
}
|
2016-12-25 23:10:37 +01:00
|
|
|
bool op_empty() const { return getNumOperands() == 0; }
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
|
|
|
void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator) {
|
|
|
|
assert(!Operands && "Operands already allocated");
|
|
|
|
Operands = Recycler.allocate(RecyclerCapacity::get(MaxOperands), Allocator);
|
|
|
|
}
|
|
|
|
void deallocateOperands(RecyclerType &Recycler) {
|
|
|
|
Recycler.deallocate(RecyclerCapacity::get(MaxOperands), Operands);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setType(Type *T) { ValueType = T; }
|
|
|
|
Type *getType() const { return ValueType; }
|
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
bool equals(const Expression &Other) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (getOpcode() != Other.getOpcode())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
const auto &OE = cast<BasicExpression>(Other);
|
2016-12-24 18:14:19 +01:00
|
|
|
return getType() == OE.getType() && NumOperands == OE.NumOperands &&
|
2016-12-26 21:06:58 +01:00
|
|
|
std::equal(op_begin(), op_end(), OE.op_begin());
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
hash_code getHashValue() const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
return hash_combine(getExpressionType(), getOpcode(), ValueType,
|
2016-12-25 23:10:37 +01:00
|
|
|
hash_combine_range(op_begin(), op_end()));
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Debugging support
|
|
|
|
//
|
2017-01-18 01:57:48 +01:00
|
|
|
void printInternal(raw_ostream &OS, bool PrintEType) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (PrintEType)
|
|
|
|
OS << "ExpressionTypeBasic, ";
|
|
|
|
|
|
|
|
this->Expression::printInternal(OS, false);
|
|
|
|
OS << "operands = {";
|
|
|
|
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
|
|
|
|
OS << "[" << i << "] = ";
|
|
|
|
Operands[i]->printAsOperand(OS);
|
|
|
|
OS << " ";
|
|
|
|
}
|
|
|
|
OS << "} ";
|
|
|
|
}
|
|
|
|
};
|
2017-01-18 01:57:48 +01:00
|
|
|
|
2016-12-26 20:57:25 +01:00
|
|
|
class op_inserter
|
|
|
|
: public std::iterator<std::output_iterator_tag, void, void, void, void> {
|
|
|
|
private:
|
|
|
|
typedef BasicExpression Container;
|
|
|
|
Container *BE;
|
2016-12-26 21:06:58 +01:00
|
|
|
|
2016-12-26 20:57:25 +01:00
|
|
|
public:
|
|
|
|
explicit op_inserter(BasicExpression &E) : BE(&E) {}
|
|
|
|
explicit op_inserter(BasicExpression *E) : BE(E) {}
|
|
|
|
|
|
|
|
op_inserter &operator=(Value *val) {
|
|
|
|
BE->op_push_back(val);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
op_inserter &operator*() { return *this; }
|
|
|
|
op_inserter &operator++() { return *this; }
|
|
|
|
op_inserter &operator++(int) { return *this; }
|
|
|
|
};
|
|
|
|
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
class CallExpression final : public BasicExpression {
|
|
|
|
private:
|
|
|
|
CallInst *Call;
|
|
|
|
MemoryAccess *DefiningAccess;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CallExpression(unsigned NumOperands, CallInst *C, MemoryAccess *DA)
|
2016-12-26 21:06:58 +01:00
|
|
|
: BasicExpression(NumOperands, ET_Call), Call(C), DefiningAccess(DA) {}
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
CallExpression() = delete;
|
2017-01-18 01:57:48 +01:00
|
|
|
CallExpression(const CallExpression &) = delete;
|
|
|
|
CallExpression &operator=(const CallExpression &) = delete;
|
|
|
|
~CallExpression() override;
|
|
|
|
|
|
|
|
static bool classof(const Expression *EB) {
|
|
|
|
return EB->getExpressionType() == ET_Call;
|
|
|
|
}
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
bool equals(const Expression &Other) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (!this->BasicExpression::equals(Other))
|
|
|
|
return false;
|
|
|
|
const auto &OE = cast<CallExpression>(Other);
|
|
|
|
return DefiningAccess == OE.DefiningAccess;
|
|
|
|
}
|
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
hash_code getHashValue() const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
return hash_combine(this->BasicExpression::getHashValue(), DefiningAccess);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Debugging support
|
|
|
|
//
|
2017-01-18 01:57:48 +01:00
|
|
|
void printInternal(raw_ostream &OS, bool PrintEType) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (PrintEType)
|
|
|
|
OS << "ExpressionTypeCall, ";
|
|
|
|
this->BasicExpression::printInternal(OS, false);
|
|
|
|
OS << " represents call at " << Call;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class LoadExpression final : public BasicExpression {
|
|
|
|
private:
|
|
|
|
LoadInst *Load;
|
|
|
|
MemoryAccess *DefiningAccess;
|
|
|
|
unsigned Alignment;
|
|
|
|
|
|
|
|
public:
|
|
|
|
LoadExpression(unsigned NumOperands, LoadInst *L, MemoryAccess *DA)
|
|
|
|
: LoadExpression(ET_Load, NumOperands, L, DA) {}
|
2016-12-26 21:06:58 +01:00
|
|
|
LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L,
|
|
|
|
MemoryAccess *DA)
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
: BasicExpression(NumOperands, EType), Load(L), DefiningAccess(DA) {
|
|
|
|
Alignment = L ? L->getAlignment() : 0;
|
|
|
|
}
|
|
|
|
LoadExpression() = delete;
|
2017-01-18 01:57:48 +01:00
|
|
|
LoadExpression(const LoadExpression &) = delete;
|
|
|
|
LoadExpression &operator=(const LoadExpression &) = delete;
|
|
|
|
~LoadExpression() override;
|
|
|
|
|
|
|
|
static bool classof(const Expression *EB) {
|
|
|
|
return EB->getExpressionType() == ET_Load;
|
|
|
|
}
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
|
|
|
LoadInst *getLoadInst() const { return Load; }
|
|
|
|
void setLoadInst(LoadInst *L) { Load = L; }
|
|
|
|
|
|
|
|
MemoryAccess *getDefiningAccess() const { return DefiningAccess; }
|
|
|
|
void setDefiningAccess(MemoryAccess *MA) { DefiningAccess = MA; }
|
|
|
|
unsigned getAlignment() const { return Alignment; }
|
|
|
|
void setAlignment(unsigned Align) { Alignment = Align; }
|
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
bool equals(const Expression &Other) const override;
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
hash_code getHashValue() const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
return hash_combine(getOpcode(), getType(), DefiningAccess,
|
2016-12-25 23:10:37 +01:00
|
|
|
hash_combine_range(op_begin(), op_end()));
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Debugging support
|
|
|
|
//
|
2017-01-18 01:57:48 +01:00
|
|
|
void printInternal(raw_ostream &OS, bool PrintEType) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (PrintEType)
|
|
|
|
OS << "ExpressionTypeLoad, ";
|
|
|
|
this->BasicExpression::printInternal(OS, false);
|
|
|
|
OS << " represents Load at " << Load;
|
2016-12-31 08:34:36 +01:00
|
|
|
OS << " with DefiningAccess " << *DefiningAccess;
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class StoreExpression final : public BasicExpression {
|
|
|
|
private:
|
|
|
|
StoreInst *Store;
|
NewGVN: Fix PR 31686 and PR 31698 by rewriting store leader handling.
Summary:
This rewrites store expression/leader handling. We no longer use the
value operand as the leader, instead, we store it separately. We also
now store the stored value as part of the expression, and compare it
when comparing stores for equality. This enables us to get rid of a
bunch of our previous hacks and machinations, as the existing
machinery takes care of everything *except* updating the stored value
on classes. The only time we have to update it is if the storecount
goes to 0, and when we do, we destroy it.
Since we no longer use the value operand as the leader, during elimination, we have to use the value operand. Doing this also fixes a bunch of store forwarding cases we were missing.
Any value operand we use is guaranteed to either be updated by previous eliminations, or minimized by future ones.
(IE the fact that we don't use the most dominating value operand when it's not a constant does not affect anything).
Sadly, this change also exposes that we didn't pay attention to the
output of the pr31594.ll test, as it also very clearly exposes the
same store leader bug we are fixing here.
(I added pr31682.ll anyway, but maybe we think that's too large to be useful)
On the plus side, propagate-ir-flags.ll now passes due to the
corrected store forwarding.
This change was 3 stage'd on darwin and linux, with the full test-suite.
Reviewers:
davide
Subscribers:
llvm-commits
llvm-svn: 292648
2017-01-20 22:04:30 +01:00
|
|
|
Value *StoredValue;
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
MemoryAccess *DefiningAccess;
|
|
|
|
|
|
|
|
public:
|
NewGVN: Fix PR 31686 and PR 31698 by rewriting store leader handling.
Summary:
This rewrites store expression/leader handling. We no longer use the
value operand as the leader, instead, we store it separately. We also
now store the stored value as part of the expression, and compare it
when comparing stores for equality. This enables us to get rid of a
bunch of our previous hacks and machinations, as the existing
machinery takes care of everything *except* updating the stored value
on classes. The only time we have to update it is if the storecount
goes to 0, and when we do, we destroy it.
Since we no longer use the value operand as the leader, during elimination, we have to use the value operand. Doing this also fixes a bunch of store forwarding cases we were missing.
Any value operand we use is guaranteed to either be updated by previous eliminations, or minimized by future ones.
(IE the fact that we don't use the most dominating value operand when it's not a constant does not affect anything).
Sadly, this change also exposes that we didn't pay attention to the
output of the pr31594.ll test, as it also very clearly exposes the
same store leader bug we are fixing here.
(I added pr31682.ll anyway, but maybe we think that's too large to be useful)
On the plus side, propagate-ir-flags.ll now passes due to the
corrected store forwarding.
This change was 3 stage'd on darwin and linux, with the full test-suite.
Reviewers:
davide
Subscribers:
llvm-commits
llvm-svn: 292648
2017-01-20 22:04:30 +01:00
|
|
|
StoreExpression(unsigned NumOperands, StoreInst *S, Value *StoredValue,
|
|
|
|
MemoryAccess *DA)
|
|
|
|
: BasicExpression(NumOperands, ET_Store), Store(S),
|
|
|
|
StoredValue(StoredValue), DefiningAccess(DA) {}
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
StoreExpression() = delete;
|
2017-01-18 01:57:48 +01:00
|
|
|
StoreExpression(const StoreExpression &) = delete;
|
|
|
|
StoreExpression &operator=(const StoreExpression &) = delete;
|
|
|
|
~StoreExpression() override;
|
|
|
|
|
|
|
|
static bool classof(const Expression *EB) {
|
|
|
|
return EB->getExpressionType() == ET_Store;
|
|
|
|
}
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
|
|
|
StoreInst *getStoreInst() const { return Store; }
|
|
|
|
MemoryAccess *getDefiningAccess() const { return DefiningAccess; }
|
NewGVN: Fix PR 31686 and PR 31698 by rewriting store leader handling.
Summary:
This rewrites store expression/leader handling. We no longer use the
value operand as the leader, instead, we store it separately. We also
now store the stored value as part of the expression, and compare it
when comparing stores for equality. This enables us to get rid of a
bunch of our previous hacks and machinations, as the existing
machinery takes care of everything *except* updating the stored value
on classes. The only time we have to update it is if the storecount
goes to 0, and when we do, we destroy it.
Since we no longer use the value operand as the leader, during elimination, we have to use the value operand. Doing this also fixes a bunch of store forwarding cases we were missing.
Any value operand we use is guaranteed to either be updated by previous eliminations, or minimized by future ones.
(IE the fact that we don't use the most dominating value operand when it's not a constant does not affect anything).
Sadly, this change also exposes that we didn't pay attention to the
output of the pr31594.ll test, as it also very clearly exposes the
same store leader bug we are fixing here.
(I added pr31682.ll anyway, but maybe we think that's too large to be useful)
On the plus side, propagate-ir-flags.ll now passes due to the
corrected store forwarding.
This change was 3 stage'd on darwin and linux, with the full test-suite.
Reviewers:
davide
Subscribers:
llvm-commits
llvm-svn: 292648
2017-01-20 22:04:30 +01:00
|
|
|
Value *getStoredValue() const { return StoredValue; }
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
bool equals(const Expression &Other) const override;
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
hash_code getHashValue() const override {
|
NewGVN: Fix PR 31686 and PR 31698 by rewriting store leader handling.
Summary:
This rewrites store expression/leader handling. We no longer use the
value operand as the leader, instead, we store it separately. We also
now store the stored value as part of the expression, and compare it
when comparing stores for equality. This enables us to get rid of a
bunch of our previous hacks and machinations, as the existing
machinery takes care of everything *except* updating the stored value
on classes. The only time we have to update it is if the storecount
goes to 0, and when we do, we destroy it.
Since we no longer use the value operand as the leader, during elimination, we have to use the value operand. Doing this also fixes a bunch of store forwarding cases we were missing.
Any value operand we use is guaranteed to either be updated by previous eliminations, or minimized by future ones.
(IE the fact that we don't use the most dominating value operand when it's not a constant does not affect anything).
Sadly, this change also exposes that we didn't pay attention to the
output of the pr31594.ll test, as it also very clearly exposes the
same store leader bug we are fixing here.
(I added pr31682.ll anyway, but maybe we think that's too large to be useful)
On the plus side, propagate-ir-flags.ll now passes due to the
corrected store forwarding.
This change was 3 stage'd on darwin and linux, with the full test-suite.
Reviewers:
davide
Subscribers:
llvm-commits
llvm-svn: 292648
2017-01-20 22:04:30 +01:00
|
|
|
// This deliberately does not include the stored value we compare it as part
|
|
|
|
// of equals, and only against other stores.
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
return hash_combine(getOpcode(), getType(), DefiningAccess,
|
2016-12-25 23:10:37 +01:00
|
|
|
hash_combine_range(op_begin(), op_end()));
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Debugging support
|
|
|
|
//
|
2017-01-18 01:57:48 +01:00
|
|
|
void printInternal(raw_ostream &OS, bool PrintEType) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (PrintEType)
|
|
|
|
OS << "ExpressionTypeStore, ";
|
|
|
|
this->BasicExpression::printInternal(OS, false);
|
|
|
|
OS << " represents Store at " << Store;
|
2016-12-31 08:34:36 +01:00
|
|
|
OS << " with DefiningAccess " << *DefiningAccess;
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class AggregateValueExpression final : public BasicExpression {
|
|
|
|
private:
|
|
|
|
unsigned MaxIntOperands;
|
|
|
|
unsigned NumIntOperands;
|
|
|
|
unsigned *IntOperands;
|
|
|
|
|
|
|
|
public:
|
2016-12-26 21:06:58 +01:00
|
|
|
AggregateValueExpression(unsigned NumOperands, unsigned NumIntOperands)
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
: BasicExpression(NumOperands, ET_AggregateValue),
|
|
|
|
MaxIntOperands(NumIntOperands), NumIntOperands(0),
|
|
|
|
IntOperands(nullptr) {}
|
|
|
|
AggregateValueExpression() = delete;
|
2017-01-18 01:57:48 +01:00
|
|
|
AggregateValueExpression(const AggregateValueExpression &) = delete;
|
|
|
|
AggregateValueExpression &
|
|
|
|
operator=(const AggregateValueExpression &) = delete;
|
|
|
|
~AggregateValueExpression() override;
|
|
|
|
|
|
|
|
static bool classof(const Expression *EB) {
|
|
|
|
return EB->getExpressionType() == ET_AggregateValue;
|
|
|
|
}
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
|
|
|
typedef unsigned *int_arg_iterator;
|
|
|
|
typedef const unsigned *const_int_arg_iterator;
|
|
|
|
|
2016-12-25 23:10:37 +01:00
|
|
|
int_arg_iterator int_op_begin() { return IntOperands; }
|
|
|
|
int_arg_iterator int_op_end() { return IntOperands + NumIntOperands; }
|
|
|
|
const_int_arg_iterator int_op_begin() const { return IntOperands; }
|
|
|
|
const_int_arg_iterator int_op_end() const {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
return IntOperands + NumIntOperands;
|
|
|
|
}
|
2016-12-25 23:10:37 +01:00
|
|
|
unsigned int_op_size() const { return NumIntOperands; }
|
|
|
|
bool int_op_empty() const { return NumIntOperands == 0; }
|
|
|
|
void int_op_push_back(unsigned IntOperand) {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
assert(NumIntOperands < MaxIntOperands &&
|
|
|
|
"Tried to add too many int operands");
|
|
|
|
assert(IntOperands && "Operands not allocated before pushing");
|
|
|
|
IntOperands[NumIntOperands++] = IntOperand;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void allocateIntOperands(BumpPtrAllocator &Allocator) {
|
|
|
|
assert(!IntOperands && "Operands already allocated");
|
|
|
|
IntOperands = Allocator.Allocate<unsigned>(MaxIntOperands);
|
|
|
|
}
|
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
bool equals(const Expression &Other) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (!this->BasicExpression::equals(Other))
|
|
|
|
return false;
|
|
|
|
const AggregateValueExpression &OE = cast<AggregateValueExpression>(Other);
|
2016-12-24 18:14:19 +01:00
|
|
|
return NumIntOperands == OE.NumIntOperands &&
|
2016-12-26 21:06:58 +01:00
|
|
|
std::equal(int_op_begin(), int_op_end(), OE.int_op_begin());
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
hash_code getHashValue() const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
return hash_combine(this->BasicExpression::getHashValue(),
|
2016-12-25 23:10:37 +01:00
|
|
|
hash_combine_range(int_op_begin(), int_op_end()));
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Debugging support
|
|
|
|
//
|
2017-01-18 01:57:48 +01:00
|
|
|
void printInternal(raw_ostream &OS, bool PrintEType) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (PrintEType)
|
|
|
|
OS << "ExpressionTypeAggregateValue, ";
|
|
|
|
this->BasicExpression::printInternal(OS, false);
|
|
|
|
OS << ", intoperands = {";
|
2016-12-25 23:10:37 +01:00
|
|
|
for (unsigned i = 0, e = int_op_size(); i != e; ++i) {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
OS << "[" << i << "] = " << IntOperands[i] << " ";
|
|
|
|
}
|
|
|
|
OS << "}";
|
|
|
|
}
|
|
|
|
};
|
2017-01-18 01:57:48 +01:00
|
|
|
|
2016-12-26 20:57:25 +01:00
|
|
|
class int_op_inserter
|
|
|
|
: public std::iterator<std::output_iterator_tag, void, void, void, void> {
|
|
|
|
private:
|
|
|
|
typedef AggregateValueExpression Container;
|
|
|
|
Container *AVE;
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit int_op_inserter(AggregateValueExpression &E) : AVE(&E) {}
|
|
|
|
explicit int_op_inserter(AggregateValueExpression *E) : AVE(E) {}
|
2017-01-18 01:57:48 +01:00
|
|
|
|
2016-12-26 20:57:25 +01:00
|
|
|
int_op_inserter &operator=(unsigned int val) {
|
|
|
|
AVE->int_op_push_back(val);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
int_op_inserter &operator*() { return *this; }
|
|
|
|
int_op_inserter &operator++() { return *this; }
|
|
|
|
int_op_inserter &operator++(int) { return *this; }
|
|
|
|
};
|
|
|
|
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
class PHIExpression final : public BasicExpression {
|
|
|
|
private:
|
|
|
|
BasicBlock *BB;
|
|
|
|
|
|
|
|
public:
|
|
|
|
PHIExpression(unsigned NumOperands, BasicBlock *B)
|
|
|
|
: BasicExpression(NumOperands, ET_Phi), BB(B) {}
|
|
|
|
PHIExpression() = delete;
|
2017-01-18 01:57:48 +01:00
|
|
|
PHIExpression(const PHIExpression &) = delete;
|
|
|
|
PHIExpression &operator=(const PHIExpression &) = delete;
|
|
|
|
~PHIExpression() override;
|
|
|
|
|
|
|
|
static bool classof(const Expression *EB) {
|
|
|
|
return EB->getExpressionType() == ET_Phi;
|
|
|
|
}
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
bool equals(const Expression &Other) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (!this->BasicExpression::equals(Other))
|
|
|
|
return false;
|
|
|
|
const PHIExpression &OE = cast<PHIExpression>(Other);
|
2016-12-24 18:14:19 +01:00
|
|
|
return BB == OE.BB;
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
hash_code getHashValue() const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
return hash_combine(this->BasicExpression::getHashValue(), BB);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Debugging support
|
|
|
|
//
|
2017-01-18 01:57:48 +01:00
|
|
|
void printInternal(raw_ostream &OS, bool PrintEType) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (PrintEType)
|
|
|
|
OS << "ExpressionTypePhi, ";
|
|
|
|
this->BasicExpression::printInternal(OS, false);
|
|
|
|
OS << "bb = " << BB;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class VariableExpression final : public Expression {
|
|
|
|
private:
|
|
|
|
Value *VariableValue;
|
|
|
|
|
|
|
|
public:
|
2017-01-18 01:57:48 +01:00
|
|
|
VariableExpression(Value *V) : Expression(ET_Variable), VariableValue(V) {}
|
|
|
|
VariableExpression() = delete;
|
|
|
|
VariableExpression(const VariableExpression &) = delete;
|
|
|
|
VariableExpression &operator=(const VariableExpression &) = delete;
|
|
|
|
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
static bool classof(const Expression *EB) {
|
|
|
|
return EB->getExpressionType() == ET_Variable;
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *getVariableValue() const { return VariableValue; }
|
|
|
|
void setVariableValue(Value *V) { VariableValue = V; }
|
2017-01-18 01:57:48 +01:00
|
|
|
|
|
|
|
bool equals(const Expression &Other) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
const VariableExpression &OC = cast<VariableExpression>(Other);
|
2016-12-24 18:14:19 +01:00
|
|
|
return VariableValue == OC.VariableValue;
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
}
|
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
hash_code getHashValue() const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
return hash_combine(getExpressionType(), VariableValue->getType(),
|
|
|
|
VariableValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Debugging support
|
|
|
|
//
|
2017-01-18 01:57:48 +01:00
|
|
|
void printInternal(raw_ostream &OS, bool PrintEType) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (PrintEType)
|
|
|
|
OS << "ExpressionTypeVariable, ";
|
|
|
|
this->Expression::printInternal(OS, false);
|
|
|
|
OS << " variable = " << *VariableValue;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class ConstantExpression final : public Expression {
|
|
|
|
private:
|
2017-01-18 01:57:48 +01:00
|
|
|
Constant *ConstantValue = nullptr;
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
|
|
|
public:
|
2017-01-18 01:57:48 +01:00
|
|
|
ConstantExpression() : Expression(ET_Constant) {}
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
ConstantExpression(Constant *constantValue)
|
|
|
|
: Expression(ET_Constant), ConstantValue(constantValue) {}
|
|
|
|
ConstantExpression(const ConstantExpression &) = delete;
|
2017-01-18 01:57:48 +01:00
|
|
|
ConstantExpression &operator=(const ConstantExpression &) = delete;
|
|
|
|
|
|
|
|
static bool classof(const Expression *EB) {
|
|
|
|
return EB->getExpressionType() == ET_Constant;
|
|
|
|
}
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
|
|
|
Constant *getConstantValue() const { return ConstantValue; }
|
|
|
|
void setConstantValue(Constant *V) { ConstantValue = V; }
|
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
bool equals(const Expression &Other) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
const ConstantExpression &OC = cast<ConstantExpression>(Other);
|
|
|
|
return ConstantValue == OC.ConstantValue;
|
|
|
|
}
|
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
hash_code getHashValue() const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
return hash_combine(getExpressionType(), ConstantValue->getType(),
|
|
|
|
ConstantValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Debugging support
|
|
|
|
//
|
2017-01-18 01:57:48 +01:00
|
|
|
void printInternal(raw_ostream &OS, bool PrintEType) const override {
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
if (PrintEType)
|
|
|
|
OS << "ExpressionTypeConstant, ";
|
|
|
|
this->Expression::printInternal(OS, false);
|
|
|
|
OS << " constant = " << *ConstantValue;
|
|
|
|
}
|
|
|
|
};
|
2017-01-02 19:00:53 +01:00
|
|
|
|
|
|
|
class UnknownExpression final : public Expression {
|
|
|
|
private:
|
|
|
|
Instruction *Inst;
|
|
|
|
|
|
|
|
public:
|
2017-01-18 01:57:48 +01:00
|
|
|
UnknownExpression(Instruction *I) : Expression(ET_Unknown), Inst(I) {}
|
|
|
|
UnknownExpression() = delete;
|
|
|
|
UnknownExpression(const UnknownExpression &) = delete;
|
|
|
|
UnknownExpression &operator=(const UnknownExpression &) = delete;
|
|
|
|
|
2017-01-02 19:00:53 +01:00
|
|
|
static bool classof(const Expression *EB) {
|
|
|
|
return EB->getExpressionType() == ET_Unknown;
|
|
|
|
}
|
|
|
|
|
|
|
|
Instruction *getInstruction() const { return Inst; }
|
|
|
|
void setInstruction(Instruction *I) { Inst = I; }
|
2017-01-18 01:57:48 +01:00
|
|
|
|
|
|
|
bool equals(const Expression &Other) const override {
|
2017-01-02 19:00:53 +01:00
|
|
|
const auto &OU = cast<UnknownExpression>(Other);
|
|
|
|
return Inst == OU.Inst;
|
|
|
|
}
|
2017-01-18 01:57:48 +01:00
|
|
|
|
|
|
|
hash_code getHashValue() const override {
|
2017-01-02 19:00:53 +01:00
|
|
|
return hash_combine(getExpressionType(), Inst);
|
|
|
|
}
|
2017-01-18 01:57:48 +01:00
|
|
|
|
2017-01-02 19:00:53 +01:00
|
|
|
//
|
|
|
|
// Debugging support
|
|
|
|
//
|
2017-01-18 01:57:48 +01:00
|
|
|
void printInternal(raw_ostream &OS, bool PrintEType) const override {
|
2017-01-02 19:00:53 +01:00
|
|
|
if (PrintEType)
|
|
|
|
OS << "ExpressionTypeUnknown, ";
|
|
|
|
this->Expression::printInternal(OS, false);
|
|
|
|
OS << " inst = " << *Inst;
|
|
|
|
}
|
|
|
|
};
|
[GVN] Initial check-in of a new global value numbering algorithm.
The code have been developed by Daniel Berlin over the years, and
the new implementation goal is that of addressing shortcomings of
the current GVN infrastructure, i.e. long compile time for large
testcases, lack of phi predication, no load/store value numbering
etc...
The current code just implements the "core" GVN algorithm, although
other pieces (load coercion, phi handling, predicate system) are
already implemented in a branch out of tree. Once the core is stable,
we'll start adding pieces on top of the base framework.
The test currently living in test/Transform/NewGVN are a copy
of the ones in GVN, with proper `XFAIL` (missing features in NewGVN).
A flag will be added in a future commit to enable NewGVN, so that
interested parties can exercise this code easily.
Differential Revision: https://reviews.llvm.org/D26224
llvm-svn: 290346
2016-12-22 17:03:48 +01:00
|
|
|
|
2017-01-18 01:57:48 +01:00
|
|
|
} // end namespace GVNExpression
|
|
|
|
|
|
|
|
} // end namespace llvm
|
|
|
|
|
|
|
|
#endif // LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H
|