[llvm] 34fd007 - Revert "[ADT] Implement the Waymarking as an independent utility"

Ehud Katz via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 21 13:53:22 PDT 2020


OK, sorry about that.
This revert is due to a strange failure in the new tests, only on this bot:
http://lab.llvm.org:8011/builders/clang-cmake-aarch64-lld/builds/8411.

On Sat, Mar 21, 2020 at 10:50 PM Roman Lebedev <lebedev.ri at gmail.com> wrote:

> On Sat, Mar 21, 2020 at 11:48 PM Ehud Katz via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
> >
> >
> > Author: Ehud Katz
> > Date: 2020-03-21T22:47:17+02:00
> > New Revision: 34fd007aaf80bb26d4ebbfd3272b9f85ce77416e
> >
> > URL:
> https://github.com/llvm/llvm-project/commit/34fd007aaf80bb26d4ebbfd3272b9f85ce77416e
> > DIFF:
> https://github.com/llvm/llvm-project/commit/34fd007aaf80bb26d4ebbfd3272b9f85ce77416e.diff
> >
> > LOG: Revert "[ADT] Implement the Waymarking as an independent utility"
> >
> > This reverts commit 73cf8abbe695aede9aac804f960513bb7355004a.
> When reverting commits, *please* specify the revert reason.
>
> > Added:
> >
> >
> > Modified:
> >     llvm/unittests/ADT/CMakeLists.txt
> >
> > Removed:
> >     llvm/include/llvm/ADT/Waymarking.h
> >     llvm/unittests/ADT/WaymarkingTest.cpp
> >
> >
> >
> ################################################################################
> > diff  --git a/llvm/include/llvm/ADT/Waymarking.h
> b/llvm/include/llvm/ADT/Waymarking.h
> > deleted file mode 100644
> > index 547538c75f14..000000000000
> > --- a/llvm/include/llvm/ADT/Waymarking.h
> > +++ /dev/null
> > @@ -1,325 +0,0 @@
> > -//===- Waymarking.h - Array waymarking algorithm ----------------*- C++
> -*-===//
> > -//
> > -// Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
> > -// See https://llvm.org/LICENSE.txt for license information.
> > -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -//
> > -// Utility to backtrace an array's head, from a pointer into it. For the
> > -// backtrace to work, we use "Waymarks", which are special tags
> embedded into
> > -// the array's elements.
> > -//
> > -// A Tag of n-bits (in size) is composed as follows:
> > -//
> > -// bits: |   n-1   |             n-2 ... 0              |
> > -//       .---------.------------------------------------.
> > -//       |Stop Mask|(2^(n-1))-ary numeric system - digit|
> > -//       '---------'------------------------------------'
> > -//
> > -// Backtracing is done as follows:
> > -// Walk back (starting from a given pointer to an element into the
> array), until
> > -// a tag with a "Stop Mask" is reached. Then start calculating the
> "Offset" from
> > -// the array's head, by picking up digits along the way, until another
> stop is
> > -// reached. The "Offset" is then subtracted from the current pointer,
> and the
> > -// result is the array's head.
> > -// A special case - if we first encounter a Tag with a Stop and a zero
> digit,
> > -// then this is already the head.
> > -//
> > -// For example:
> > -// In case of 2 bits:
> > -//
> > -// Tags:
> > -// x0 - binary digit 0
> > -// x1 - binary digit 1
> > -// 1x - stop and calculate (s)
> > -//
> > -// Array:
> > -//
>  .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.
> > -// head -> |s0 |s1 | 0 |s1 | 0 | 0 |s1 | 1 | 1 |s1 | 0 | 1 | 0 |s1 | 0
> | 1 |
> > -//
>  '---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'
> > -//             |-1 |-2     |-4         |-7         |-10            |-14
> > -//          <_ |   |       |           |           |               |
> > -//          <_____ |       |           |           |               |
> > -//          <_____________ |           |           |               |
> > -//          <_________________________ |           |               |
> > -//          <_____________________________________ |               |
> > -//          <_____________________________________________________ |
> > -//
> > -//
> > -// In case of 3 bits:
> > -//
> > -// Tags:
> > -// x00 - quaternary digit 0
> > -// x01 - quaternary digit 1
> > -// x10 - quaternary digit 2
> > -// x11 - quaternary digit 3
> > -// 1xy - stop and calculate (s)
> > -//
> > -// Array:
> > -//
>  .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.
> > -// head -> |s0 |s1 |s2 |s3 | 0 |s1 | 2 |s1 | 0 |s2 | 2 |s2 | 0 |s3 | 2
> |s3 |
> > -//
>  '---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'
> > -//             |-1 |-2 |-3 |-4     |-6     |-8     |-10    |-12
> |-14    |-16
> > -//          <_ |   |   |   |       |       |       |       |       |
>    |
> > -//          <_____ |   |   |       |       |       |       |       |
>    |
> > -//          <_________ |   |       |       |       |       |       |
>    |
> > -//          <_____________ |       |       |       |       |       |
>    |
> > -//          <_____________________ |       |       |       |       |
>    |
> > -//          <_____________________________ |       |       |       |
>    |
> > -//          <_____________________________________ |       |       |
>    |
> > -//          <_____________________________________________ |       |
>    |
> > -//          <_____________________________________________________ |
>    |
> > -//
> <_____________________________________________________________ |
> > -//
> > -//
> > -// The API introduce 2 functions:
> > -// 1. fillWaymarks
> > -// 2. followWaymarks
> > -//
> > -// Example:
> > -//   int N = 10;
> > -//   int M = 5;
> > -//   int **A = new int *[N + M];   // Define the array.
> > -//   for (int I = 0; I < N + M; ++I)
> > -//     A[I] = new int(I);
> > -//
> > -//   fillWaymarks(A, A + N);       // Set the waymarks for the first N
> elements
> > -//                                 // of the array.
> > -//                                 // Note that it must be done AFTER
> we fill
> > -//                                 // the array's elements.
> > -//
> > -//   ...                           // Elements which are not in the
> range
> > -//                                 // [A, A+N) will not be marked, and
> we won't
> > -//                                 // be able to call followWaymarks on
> them.
> > -//
> > -//   ...                           // Elements which will be changed
> after the
> > -//                                 // call to fillWaymarks, will have
> to be
> > -//                                 // retagged.
> > -//
> > -//   fillWaymarks(A + N, A + N + M, N); // Set the waymarks of the
> remaining M
> > -//                                      // elements.
> > -//   ...
> > -//   int **It = A + N + 1;
> > -//   int **B = followWaymarks(It); // Find the head of the array
> containing It.
> > -//   assert(B == A);
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -
> > -#ifndef LLVM_ADT_WAYMARKING_H
> > -#define LLVM_ADT_WAYMARKING_H
> > -
> > -#include "llvm/ADT/STLExtras.h"
> > -#include "llvm/Support/PointerLikeTypeTraits.h"
> > -
> > -namespace llvm {
> > -
> > -namespace detail {
> > -
> > -template <unsigned NumBits> struct WaymarkingTraits {
> > -  enum : unsigned {
> > -    // The number of bits of a Waymarking Tag.
> > -    NUM_BITS = NumBits,
> > -
> > -    // A Tag is composed from a Mark and a Stop mask.
> > -    MARK_SIZE = NUM_BITS - 1,
> > -    STOP_MASK = (1 << MARK_SIZE),
> > -    MARK_MASK = (STOP_MASK - 1),
> > -    TAG_MASK = (MARK_MASK | STOP_MASK),
> > -
> > -    // The number of pre-calculated tags (for fast fill).
> > -    NUM_STATIC_TAGS = 32
> > -  };
> > -
> > -private:
> > -  // Add a new tag, calculated from Count and Stop, to the Vals pack,
> while
> > -  // continuing recursively to decrease Len down to 0.
> > -  template <unsigned Len, bool Stop, unsigned Count, uint8_t... Vals>
> > -  struct AddTag;
> > -
> > -  // Delegate to the specialized AddTag according to the need of a Stop
> mask.
> > -  template <unsigned Len, unsigned Count, uint8_t... Vals> struct
> GenTag {
> > -    typedef
> > -        typename AddTag<Len, (Count <= MARK_MASK), Count,
> Vals...>::Xdata Xdata;
> > -  };
> > -
> > -  // Start adding tags while calculating the next Count, which is
> actually the
> > -  // number of already calculated tags (equivalent to the position in
> the
> > -  // array).
> > -  template <unsigned Len, uint8_t... Vals> struct GenOffset {
> > -    typedef typename GenTag<Len, sizeof...(Vals), Vals...>::Xdata Xdata;
> > -  };
> > -
> > -  // Add the tag and remove it from Count.
> > -  template <unsigned Len, unsigned Count, uint8_t... Vals>
> > -  struct AddTag<Len, false, Count, Vals...> {
> > -    typedef typename GenTag<Len - 1, (Count >> MARK_SIZE), Vals...,
> > -                            Count & MARK_MASK>::Xdata Xdata;
> > -  };
> > -
> > -  // We have reached the end of this Count, so start with a new Count.
> > -  template <unsigned Len, unsigned Count, uint8_t... Vals>
> > -  struct AddTag<Len, true, Count, Vals...> {
> > -    typedef typename GenOffset<Len - 1, Vals...,
> > -                               (Count & MARK_MASK) | STOP_MASK>::Xdata
> Xdata;
> > -  };
> > -
> > -  template <unsigned Count, uint8_t... Vals> struct TagsData {
> > -    // The remaining number for calculating the next tag, following the
> last one
> > -    // in Values.
> > -    static const unsigned Remain = Count;
> > -
> > -    // The array of ordered pre-calculated Tags.
> > -    static const uint8_t Values[sizeof...(Vals)];
> > -  };
> > -
> > -  // Specialize the case when Len equals 0, as the recursion stop
> condition.
> > -  template <unsigned Count, uint8_t... Vals>
> > -  struct AddTag<0, false, Count, Vals...> {
> > -    typedef TagsData<Count, Vals...> Xdata;
> > -  };
> > -
> > -  template <unsigned Count, uint8_t... Vals>
> > -  struct AddTag<0, true, Count, Vals...> {
> > -    typedef TagsData<Count, Vals...> Xdata;
> > -  };
> > -
> > -public:
> > -  typedef typename GenOffset<NUM_STATIC_TAGS>::Xdata Tags;
> > -};
> > -
> > -template <unsigned NumBits>
> > -template <unsigned Count, uint8_t... Vals>
> > -const uint8_t WaymarkingTraits<NumBits>::TagsData<
> > -    Count, Vals...>::Values[sizeof...(Vals)] = {Vals...};
> > -
> > -} // end namespace detail
> > -
> > -/// This class is responsible for tagging (and retrieving the tag of) a
> given
> > -/// element of type T.
> > -template <class T, class WTraits = detail::WaymarkingTraits<
> > -                       PointerLikeTypeTraits<T>::NumLowBitsAvailable>>
> > -struct Waymarker {
> > -  using Traits = WTraits;
> > -  static void setWaymark(T &N, unsigned Tag) { N.setWaymark(Tag); }
> > -  static unsigned getWaymark(const T &N) { return N.getWaymark(); }
> > -};
> > -
> > -template <class T, class WTraits> struct Waymarker<T *, WTraits> {
> > -  using Traits = WTraits;
> > -  static void setWaymark(T *&N, unsigned Tag) {
> > -    reinterpret_cast<uintptr_t &>(N) |= static_cast<uintptr_t>(Tag);
> > -  }
> > -  static unsigned getWaymark(const T *N) {
> > -    return static_cast<unsigned>(reinterpret_cast<uintptr_t>(N)) &
> > -           Traits::TAG_MASK;
> > -  }
> > -};
> > -
> > -/// Sets up the waymarking algorithm's tags for a given range [Begin,
> End).
> > -///
> > -/// \param Begin The beginning of the range to mark with tags
> (inclusive).
> > -/// \param End The ending of the range to mark with tags (exclusive).
> > -/// \param Offset The position in the supposed tags array from which to
> start
> > -/// marking the given range.
> > -template <class TIter, class Marker = Waymarker<
> > -                           typename
> std::iterator_traits<TIter>::value_type>>
> > -void fillWaymarks(TIter Begin, TIter End, size_t Offset = 0) {
> > -  if (Begin == End)
> > -    return;
> > -
> > -  size_t Count = Marker::Traits::Tags::Remain;
> > -  if (Offset <= Marker::Traits::NUM_STATIC_TAGS) {
> > -    // Start by filling the pre-calculated tags, starting from the
> given offset.
> > -    while (Offset != Marker::Traits::NUM_STATIC_TAGS) {
> > -      Marker::setWaymark(*Begin, Marker::Traits::Tags::Values[Offset]);
> > -
> > -      ++Offset;
> > -      ++Begin;
> > -
> > -      if (Begin == End)
> > -        return;
> > -    }
> > -  } else {
> > -    // The given offset is larger than the number of pre-calculated
> tags, so we
> > -    // must do it the hard way.
> > -    // Calculate the next remaining Count, as if we have filled the
> tags up to
> > -    // the given offset.
> > -    size_t Off = Marker::Traits::NUM_STATIC_TAGS;
> > -    do {
> > -      ++Off;
> > -
> > -      unsigned Tag = Count & Marker::Traits::MARK_MASK;
> > -
> > -      // If the count can fit into the tag, then the counting must stop.
> > -      if (Count <= Marker::Traits::MARK_MASK) {
> > -        Tag |= Marker::Traits::STOP_MASK;
> > -        Count = Off;
> > -      } else
> > -        Count >>= Marker::Traits::MARK_SIZE;
> > -    } while (Off != Offset);
> > -  }
> > -
> > -  // By now, we have the matching remaining Count for the current
> offset.
> > -  do {
> > -    ++Offset;
> > -
> > -    unsigned Tag = Count & Marker::Traits::MARK_MASK;
> > -
> > -    // If the count can fit into the tag, then the counting must stop.
> > -    if (Count <= Marker::Traits::MARK_MASK) {
> > -      Tag |= Marker::Traits::STOP_MASK;
> > -      Count = Offset;
> > -    } else
> > -      Count >>= Marker::Traits::MARK_SIZE;
> > -
> > -    Marker::setWaymark(*Begin, Tag);
> > -    ++Begin;
> > -  } while (Begin != End);
> > -}
> > -
> > -/// Sets up the waymarking algorithm's tags for a given range.
> > -///
> > -/// \param Range The range to mark with tags.
> > -/// \param Offset The position in the supposed tags array from which to
> start
> > -/// marking the given range.
> > -template <typename R, class Marker = Waymarker<typename
> std::remove_reference<
> > -                          decltype(*std::begin(std::declval<R
> &>()))>::type>>
> > -void fillWaymarks(R &&Range, size_t Offset = 0) {
> > -  return fillWaymarks<decltype(std::begin(std::declval<R &>())),
> Marker>(
> > -      adl_begin(Range), adl_end(Range), Offset);
> > -}
> > -
> > -/// Retrieves the element marked with tag of only STOP_MASK, by
> following the
> > -/// waymarks. This is the first element in a range passed to a previous
> call to
> > -/// \c fillWaymarks with \c Offset 0.
> > -///
> > -/// For the trivial usage of calling \c fillWaymarks(Array), and \I is
> an
> > -/// iterator inside \c Array, this function retrieves the head of \c
> Array, by
> > -/// following the waymarks.
> > -///
> > -/// \param I The iterator into an array which was marked by the
> waymarking tags
> > -/// (by a previous call to \c fillWaymarks).
> > -template <class TIter, class Marker = Waymarker<
> > -                           typename
> std::iterator_traits<TIter>::value_type>>
> > -TIter followWaymarks(TIter I) {
> > -  unsigned Tag;
> > -  do
> > -    Tag = Marker::getWaymark(*I--);
> > -  while (!(Tag & Marker::Traits::STOP_MASK));
> > -
> > -  // Special case for the first Use.
> > -  if (Tag != Marker::Traits::STOP_MASK) {
> > -    ptr
> > diff _t Offset = Tag & Marker::Traits::MARK_MASK;
> > -    while (!((Tag = Marker::getWaymark(*I)) &
> Marker::Traits::STOP_MASK)) {
> > -      Offset = (Offset << Marker::Traits::MARK_SIZE) + Tag;
> > -      --I;
> > -    }
> > -    I -= Offset;
> > -  }
> > -  return ++I;
> > -}
> > -
> > -} // end namespace llvm
> > -
> > -#endif // LLVM_ADT_WAYMARKING_H
> >
> > diff  --git a/llvm/unittests/ADT/CMakeLists.txt
> b/llvm/unittests/ADT/CMakeLists.txt
> > index 771d1600ca6d..53d18b373271 100644
> > --- a/llvm/unittests/ADT/CMakeLists.txt
> > +++ b/llvm/unittests/ADT/CMakeLists.txt
> > @@ -73,7 +73,6 @@ add_llvm_unittest(ADTTests
> >    TinyPtrVectorTest.cpp
> >    TripleTest.cpp
> >    TwineTest.cpp
> > -  WaymarkingTest.cpp
> >    )
> >
> >  target_link_libraries(ADTTests PRIVATE LLVMTestingSupport)
> >
> > diff  --git a/llvm/unittests/ADT/WaymarkingTest.cpp
> b/llvm/unittests/ADT/WaymarkingTest.cpp
> > deleted file mode 100644
> > index 9ec980323e75..000000000000
> > --- a/llvm/unittests/ADT/WaymarkingTest.cpp
> > +++ /dev/null
> > @@ -1,150 +0,0 @@
> > -//===- llvm/unittest/IR/WaymarkTest.cpp - Waymarking unit tests
> -----------===//
> > -//
> > -// Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
> > -// See https://llvm.org/LICENSE.txt for license information.
> > -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> > -//
> >
> -//===----------------------------------------------------------------------===//
> > -
> > -#include "llvm/ADT/Waymarking.h"
> > -#include "gtest/gtest.h"
> > -
> > -using namespace llvm;
> > -
> > -static const int N = 100;
> > -
> > -static int tag(int *P) {
> > -  return static_cast<int>(reinterpret_cast<uintptr_t>(P) &
> > -                          uintptr_t(alignof(int *) - 1));
> > -}
> > -
> > -static int *ref(int *P) {
> > -  return reinterpret_cast<int *>(reinterpret_cast<uintptr_t>(P) &
> > -                                 ~uintptr_t(alignof(int *) - 1));
> > -}
> > -
> > -static int **createArray(int Len) {
> > -  int **A = new int *[Len];
> > -  for (int I = 0; I < Len; ++I)
> > -    A[I] = new int(I);
> > -  return A;
> > -}
> > -
> > -static void freeArray(int **A, int Len) {
> > -  for (int I = 0; I < Len; ++I)
> > -    delete ref(A[I]);
> > -  delete[] A;
> > -}
> > -
> > -namespace {
> > -
> > -TEST(WaymarkingTest, SingleHead) {
> > -  const int N2 = 2 * N;
> > -  int **A = createArray(N2);
> > -
> > -  // Fill the first half of the array with waymarkings.
> > -  fillWaymarks(A, A + N, 0);
> > -
> > -  // Verify the values stored in the array are as expected, while we
> can deduce
> > -  // the array's head from them.
> > -  for (int I = 0; I < N; ++I) {
> > -    int **P = followWaymarks(A + I);
> > -    EXPECT_EQ(A, P);
> > -    EXPECT_EQ(I, *ref(A[I]));
> > -  }
> > -
> > -  // Fill the rest of the waymarkings (continuing from where we
> stopped).
> > -  fillWaymarks(A + N, A + N2, N);
> > -
> > -  // Verify the values stored in the array are as expected, while we
> can deduce
> > -  // the array's head from them.
> > -  for (int I = 0; I < N2; ++I) {
> > -    int **P = followWaymarks(A + I);
> > -    EXPECT_EQ(A, P);
> > -    EXPECT_EQ(I, *ref(A[I]));
> > -  }
> > -
> > -  freeArray(A, N2);
> > -}
> > -
> > -TEST(WaymarkingTest, MultiHead) {
> > -  const int N2 = 2 * N;
> > -  const int N3 = 3 * N;
> > -  int **A = createArray(N3);
> > -
> > -  // Seperate the array into 3 sections, of waymarkings.
> > -  fillWaymarks(A, A + N, 0);
> > -  fillWaymarks(A + N, A + N2, 0);
> > -  fillWaymarks(A + N2, A + N3, 0);
> > -
> > -  // Verify the values stored in the array are as expected, while we
> can deduce
> > -  // the array section's head from them.
> > -  for (int I = 0; I < N; ++I) {
> > -    int **P = followWaymarks(A + I);
> > -    EXPECT_EQ(A, P);
> > -    EXPECT_EQ(I, *ref(A[I]));
> > -  }
> > -  for (int I = N; I < N2; ++I) {
> > -    int **P = followWaymarks(A + I);
> > -    EXPECT_EQ(A + N, P);
> > -    EXPECT_EQ(I, *ref(A[I]));
> > -  }
> > -  for (int I = N2; I < N3; ++I) {
> > -    int **P = followWaymarks(A + I);
> > -    EXPECT_EQ(A + N2, P);
> > -    EXPECT_EQ(I, *ref(A[I]));
> > -  }
> > -
> > -  freeArray(A, N3);
> > -}
> > -
> > -TEST(WaymarkingTest, Reset) {
> > -  int **A = createArray(N);
> > -
> > -  fillWaymarks(A, A + N, 0);
> > -
> > -  const int N2 = N / 2;
> > -  const int N3 = N / 3;
> > -  const int N4 = N / 4;
> > -
> > -  // Reset specific elements and check that the tag remains the same.
> > -  int T2 = tag(A[N2]);
> > -  delete ref(A[N2]);
> > -  A[N2] = new int(-1);
> > -  fillWaymarks(A + N2, A + N2 + 1, N2);
> > -  EXPECT_EQ(T2, tag(A[N2]));
> > -
> > -  int T3 = tag(A[N3]);
> > -  delete ref(A[N3]);
> > -  A[N3] = new int(-1);
> > -  fillWaymarks(A + N3, A + N3 + 1, N3);
> > -  EXPECT_EQ(T3, tag(A[N3]));
> > -
> > -  int T4 = tag(A[N4]);
> > -  delete ref(A[N4]);
> > -  A[N4] = new int(-1);
> > -  fillWaymarks(A + N4, A + N4 + 1, N4);
> > -  EXPECT_EQ(T4, tag(A[N4]));
> > -
> > -  // Verify the values stored in the array are as expected, while we
> can deduce
> > -  // the array's head from them.
> > -  for (int I = 0; I < N; ++I) {
> > -    int **P = followWaymarks(A + I);
> > -    EXPECT_EQ(A, P);
> > -    switch (I) {
> > -    case N2:
> > -    case N3:
> > -    case N4:
> > -      EXPECT_EQ(-1, *ref(A[I]));
> > -      break;
> > -
> > -    default:
> > -      EXPECT_EQ(I, *ref(A[I]));
> > -      break;
> > -    }
> > -  }
> > -
> > -  freeArray(A, N);
> > -}
> > -
> > -} // end anonymous namespace
> >
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200321/612bf81e/attachment.html>


More information about the llvm-commits mailing list