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