[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:48:00 PDT 2020


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.

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


        


More information about the llvm-commits mailing list