1 //===------ Math.h - PBQP Vector and Matrix classes -------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_CODEGEN_PBQP_MATH_H
11 #define LLVM_CODEGEN_PBQP_MATH_H
13 #include "llvm/ADT/Hashing.h"
21 typedef float PBQPNum;
23 /// \brief PBQP Vector class.
25 friend hash_code hash_value(const Vector &);
28 /// \brief Construct a PBQP vector of the given size.
29 explicit Vector(unsigned Length)
30 : Length(Length), Data(llvm::make_unique<PBQPNum []>(Length)) {}
32 /// \brief Construct a PBQP vector with initializer.
33 Vector(unsigned Length, PBQPNum InitVal)
34 : Length(Length), Data(llvm::make_unique<PBQPNum []>(Length)) {
35 std::fill(Data.get(), Data.get() + Length, InitVal);
38 /// \brief Copy construct a PBQP vector.
39 Vector(const Vector &V)
40 : Length(V.Length), Data(llvm::make_unique<PBQPNum []>(Length)) {
41 std::copy(V.Data.get(), V.Data.get() + Length, Data.get());
44 /// \brief Move construct a PBQP vector.
46 : Length(V.Length), Data(std::move(V.Data)) {
50 /// \brief Comparison operator.
51 bool operator==(const Vector &V) const {
52 assert(Length != 0 && Data && "Invalid vector");
53 if (Length != V.Length)
55 return std::equal(Data.get(), Data.get() + Length, V.Data.get());
58 /// \brief Return the length of the vector
59 unsigned getLength() const {
60 assert(Length != 0 && Data && "Invalid vector");
64 /// \brief Element access.
65 PBQPNum& operator[](unsigned Index) {
66 assert(Length != 0 && Data && "Invalid vector");
67 assert(Index < Length && "Vector element access out of bounds.");
71 /// \brief Const element access.
72 const PBQPNum& operator[](unsigned Index) const {
73 assert(Length != 0 && Data && "Invalid vector");
74 assert(Index < Length && "Vector element access out of bounds.");
78 /// \brief Add another vector to this one.
79 Vector& operator+=(const Vector &V) {
80 assert(Length != 0 && Data && "Invalid vector");
81 assert(Length == V.Length && "Vector length mismatch.");
82 std::transform(Data.get(), Data.get() + Length, V.Data.get(), Data.get(),
83 std::plus<PBQPNum>());
87 /// \brief Returns the index of the minimum value in this vector
88 unsigned minIndex() const {
89 assert(Length != 0 && Data && "Invalid vector");
90 return std::min_element(Data.get(), Data.get() + Length) - Data.get();
95 std::unique_ptr<PBQPNum []> Data;
98 /// \brief Return a hash_value for the given vector.
99 inline hash_code hash_value(const Vector &V) {
100 unsigned *VBegin = reinterpret_cast<unsigned*>(V.Data.get());
101 unsigned *VEnd = reinterpret_cast<unsigned*>(V.Data.get() + V.Length);
102 return hash_combine(V.Length, hash_combine_range(VBegin, VEnd));
105 /// \brief Output a textual representation of the given vector on the given
107 template <typename OStream>
108 OStream& operator<<(OStream &OS, const Vector &V) {
109 assert((V.getLength() != 0) && "Zero-length vector badness.");
112 for (unsigned i = 1; i < V.getLength(); ++i)
119 /// \brief PBQP Matrix class
122 friend hash_code hash_value(const Matrix &);
125 /// \brief Construct a PBQP Matrix with the given dimensions.
126 Matrix(unsigned Rows, unsigned Cols) :
127 Rows(Rows), Cols(Cols), Data(llvm::make_unique<PBQPNum []>(Rows * Cols)) {
130 /// \brief Construct a PBQP Matrix with the given dimensions and initial
132 Matrix(unsigned Rows, unsigned Cols, PBQPNum InitVal)
133 : Rows(Rows), Cols(Cols),
134 Data(llvm::make_unique<PBQPNum []>(Rows * Cols)) {
135 std::fill(Data.get(), Data.get() + (Rows * Cols), InitVal);
138 /// \brief Copy construct a PBQP matrix.
139 Matrix(const Matrix &M)
140 : Rows(M.Rows), Cols(M.Cols),
141 Data(llvm::make_unique<PBQPNum []>(Rows * Cols)) {
142 std::copy(M.Data.get(), M.Data.get() + (Rows * Cols), Data.get());
145 /// \brief Move construct a PBQP matrix.
147 : Rows(M.Rows), Cols(M.Cols), Data(std::move(M.Data)) {
151 /// \brief Comparison operator.
152 bool operator==(const Matrix &M) const {
153 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
154 if (Rows != M.Rows || Cols != M.Cols)
156 return std::equal(Data.get(), Data.get() + (Rows * Cols), M.Data.get());
159 /// \brief Return the number of rows in this matrix.
160 unsigned getRows() const {
161 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
165 /// \brief Return the number of cols in this matrix.
166 unsigned getCols() const {
167 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
171 /// \brief Matrix element access.
172 PBQPNum* operator[](unsigned R) {
173 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
174 assert(R < Rows && "Row out of bounds.");
175 return Data.get() + (R * Cols);
178 /// \brief Matrix element access.
179 const PBQPNum* operator[](unsigned R) const {
180 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
181 assert(R < Rows && "Row out of bounds.");
182 return Data.get() + (R * Cols);
185 /// \brief Returns the given row as a vector.
186 Vector getRowAsVector(unsigned R) const {
187 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
189 for (unsigned C = 0; C < Cols; ++C)
190 V[C] = (*this)[R][C];
194 /// \brief Returns the given column as a vector.
195 Vector getColAsVector(unsigned C) const {
196 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
198 for (unsigned R = 0; R < Rows; ++R)
199 V[R] = (*this)[R][C];
203 /// \brief Matrix transpose.
204 Matrix transpose() const {
205 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
206 Matrix M(Cols, Rows);
207 for (unsigned r = 0; r < Rows; ++r)
208 for (unsigned c = 0; c < Cols; ++c)
209 M[c][r] = (*this)[r][c];
213 /// \brief Add the given matrix to this one.
214 Matrix& operator+=(const Matrix &M) {
215 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
216 assert(Rows == M.Rows && Cols == M.Cols &&
217 "Matrix dimensions mismatch.");
218 std::transform(Data.get(), Data.get() + (Rows * Cols), M.Data.get(),
219 Data.get(), std::plus<PBQPNum>());
223 Matrix operator+(const Matrix &M) {
224 assert(Rows != 0 && Cols != 0 && Data && "Invalid matrix");
232 std::unique_ptr<PBQPNum []> Data;
235 /// \brief Return a hash_code for the given matrix.
236 inline hash_code hash_value(const Matrix &M) {
237 unsigned *MBegin = reinterpret_cast<unsigned*>(M.Data.get());
239 reinterpret_cast<unsigned*>(M.Data.get() + (M.Rows * M.Cols));
240 return hash_combine(M.Rows, M.Cols, hash_combine_range(MBegin, MEnd));
243 /// \brief Output a textual representation of the given matrix on the given
245 template <typename OStream>
246 OStream& operator<<(OStream &OS, const Matrix &M) {
247 assert((M.getRows() != 0) && "Zero-row matrix badness.");
248 for (unsigned i = 0; i < M.getRows(); ++i)
249 OS << M.getRowAsVector(i) << "\n";
253 template <typename Metadata>
254 class MDVector : public Vector {
256 MDVector(const Vector &v) : Vector(v), md(*this) { }
257 MDVector(Vector &&v) : Vector(std::move(v)), md(*this) { }
258 const Metadata& getMetadata() const { return md; }
263 template <typename Metadata>
264 inline hash_code hash_value(const MDVector<Metadata> &V) {
265 return hash_value(static_cast<const Vector&>(V));
268 template <typename Metadata>
269 class MDMatrix : public Matrix {
271 MDMatrix(const Matrix &m) : Matrix(m), md(*this) { }
272 MDMatrix(Matrix &&m) : Matrix(std::move(m)), md(*this) { }
273 const Metadata& getMetadata() const { return md; }
278 template <typename Metadata>
279 inline hash_code hash_value(const MDMatrix<Metadata> &M) {
280 return hash_value(static_cast<const Matrix&>(M));
286 #endif // LLVM_CODEGEN_PBQP_MATH_H