[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