Commit 78f9e5d0 authored by Nicolas Vasilache's avatar Nicolas Vasilache
Browse files

[mlir] Add padding to 1-D Vector in CRunnerUtils.h

Summary:
This revision adds padding for 1-D Vector in the common case of x86
execution with a stadard data layout. This supports properly interfacing
codegen with arrays of e.g. `vector<9xf32>`.

Such vectors are already assumed padded to the next power of 2 by LLVM
codegen with the default x86 data layout:
```
define void @test_vector_add_1d_2_3(<3 x float>* nocapture readnone %0,
<3 x float>* nocapture readonly %1, i64 %2, i64 %3, i64 %4, <3 x float>*
nocapture readnone %5, <3 x float>* nocapture readonly %6, i64 %7, i64
%8, i64 %9, <3 x float>* nocapture readnone %10, <3 x float>* nocapture
%11, i64 %12, i64 %13, i64 %14) local_unnamed_addr {
  %16 = getelementptr <3 x float>, <3 x float>* %6, i64 1
  %17 = load <3 x float>, <3 x float>* %16, align 16
  %18 = getelementptr <3 x float>, <3 x float>* %1, i64 1
  %19 = load <3 x float>, <3 x float>* %18, align 16
  %20 = fadd <3 x float> %17, %19
  %21 = getelementptr <3 x float>, <3 x float>* %11, i64 1
```

The pointer addressing a `vector<3xf32>` is assumed aligned `@16`.
Similarly, the pointer addressing a `vector<65xf32>` is assumed aligned
`@512`.

This revision allows using objects such as `vector<3xf32>` properly with
the standard x86 data layout used in the JitRunner. Integration testing
is done out of tree, at the moment such testing fails without this
change.

Reviewers: ftynse

Subscribers: mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, arpith-jacob, mgester, lucyrfox, liufengdb, Joonsoo, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D75459
parent 8a37b9e6
Loading
Loading
Loading
Loading
+38 −2
Original line number Diff line number Diff line
@@ -39,14 +39,50 @@ template <int N> void dropFront(int64_t arr[N], int64_t *res) {
//===----------------------------------------------------------------------===//
// Codegen-compatible structures for Vector type.
//===----------------------------------------------------------------------===//
namespace detail {
  template <unsigned N>
  constexpr unsigned nextPowerOf2();
  template <>
  constexpr unsigned nextPowerOf2<0>() {
    return 1;
  }
  template <>
  constexpr unsigned nextPowerOf2<1>() {
    return 1;
  }
  template <unsigned N>
  constexpr unsigned nextPowerOf2() {
    return (!(N & (N - 1))) ? N : 2 * nextPowerOf2<(N + 1) / 2>();
  }
} // end namespace detail

// N-D vectors recurse down to 1-D.
template <typename T, int Dim, int... Dims>
struct Vector {
  constexpr Vector<T, Dims...> &operator[](unsigned i) { return vector[i]; }
  constexpr const Vector<T, Dims...> &operator[](unsigned i) const {
    return vector[i];
  }

private:
  Vector<T, Dims...> vector[Dim];
};

template <typename T, int Dim>
struct Vector<T, Dim> {
// 1-D vectors in LLVM are automatically padded to the next power of 2.
// We insert explicit padding in to account for this.
template <typename T, int Dim> struct Vector<T, Dim> {
  Vector() {
    static_assert(detail::nextPowerOf2<sizeof(T[Dim])>() >= sizeof(T[Dim]),
                  "size error");
    static_assert(detail::nextPowerOf2<sizeof(T[Dim])>() < 2 * sizeof(T[Dim]),
                  "size error");
  }
  constexpr T &operator[](unsigned i) { return vector[i]; }
  constexpr const T &operator[](unsigned i) const { return vector[i]; }

private:
  T vector[Dim];
  char padding[detail::nextPowerOf2<sizeof(T[Dim])>() - sizeof(T[Dim])];
};

template <int D1, typename T>
+3 −3
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ void VectorDataPrinter<T, M, Dims...>::print(std::ostream &os,
  static_assert(sizeof(val) == M * StaticSizeMult<Dims...>::value * sizeof(T),
                "Incorrect vector size!");
  // First
  os << "(" << val.vector[0];
  os << "(" << val[0];
  if (M > 1)
    os << ", ";
  if (sizeof...(Dims) > 1)
@@ -100,14 +100,14 @@ void VectorDataPrinter<T, M, Dims...>::print(std::ostream &os,
  // Kernel
  for (unsigned i = 1; i + 1 < M; ++i) {
    printSpace(os, 2 * sizeof...(Dims));
    os << val.vector[i] << ", ";
    os << val[i] << ", ";
    if (sizeof...(Dims) > 1)
      os << "\n";
  }
  // Last
  if (M > 1) {
    printSpace(os, sizeof...(Dims));
    os << val.vector[M - 1];
    os << val[M - 1];
  }
  os << ")";
}