[compiler-rt] 6b3ae49 - [sanitizer] Calculate Range sets intersection

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 2 13:51:15 PDT 2023


Author: Vitaly Buka
Date: 2023-06-02T13:51:00-07:00
New Revision: 6b3ae49d3243b1387abafe686ae8ef99c01227ac

URL: https://github.com/llvm/llvm-project/commit/6b3ae49d3243b1387abafe686ae8ef99c01227ac
DIFF: https://github.com/llvm/llvm-project/commit/6b3ae49d3243b1387abafe686ae8ef99c01227ac.diff

LOG: [sanitizer] Calculate Range sets intersection

Will be used to handle Root Regions in LSAN D151781.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D151779

Added: 
    compiler-rt/lib/sanitizer_common/sanitizer_common_range.cpp
    compiler-rt/lib/sanitizer_common/sanitizer_common_range.h
    compiler-rt/lib/sanitizer_common/tests/sanitizer_common_range_test.cpp

Modified: 
    compiler-rt/lib/sanitizer_common/CMakeLists.txt
    compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
index c4fdc7aeb4e40..d4187a925d39a 100644
--- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt
+++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
@@ -3,6 +3,7 @@
 
 set(SANITIZER_SOURCES_NOTERMINATION
   sanitizer_allocator.cpp
+  sanitizer_common_range.cpp
   sanitizer_common.cpp
   sanitizer_deadlock_detector1.cpp
   sanitizer_deadlock_detector2.cpp

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_range.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common_range.cpp
new file mode 100644
index 0000000000000..fcdb928a33b4c
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_range.cpp
@@ -0,0 +1,60 @@
+//===-- sanitizer_common_range.cpp ----------------------------------------===//
+//
+// 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 "sanitizer_common_range.h"
+
+namespace __sanitizer {
+
+void Intersect(ArrayRef<Range> a, ArrayRef<Range> b,
+               InternalMmapVectorNoCtor<Range> &output) {
+  output.clear();
+
+  struct Event {
+    uptr val;
+    s8 
diff 1;
+    s8 
diff 2;
+  };
+
+  InternalMmapVector<Event> events;
+  for (const Range &r : a) {
+    CHECK_LE(r.begin, r.end);
+    events.push_back({r.begin, 1, 0});
+    events.push_back({r.end, -1, 0});
+  }
+
+  for (const Range &r : b) {
+    CHECK_LE(r.begin, r.end);
+    events.push_back({r.begin, 0, 1});
+    events.push_back({r.end, 0, -1});
+  }
+
+  Sort(events.data(), events.size(),
+       [](const Event &lh, const Event &rh) { return lh.val < rh.val; });
+
+  uptr start = 0;
+  sptr state1 = 0;
+  sptr state2 = 0;
+  for (const auto &e : events) {
+    if (e.val != start) {
+      DCHECK_GE(state1, 0);
+      DCHECK_GE(state2, 0);
+      if (state1 && state2) {
+        if (!output.empty() && start == output.back().end)
+          output.back().end = e.val;
+        else
+          output.push_back({start, e.val});
+      }
+      start = e.val;
+    }
+
+    state1 += e.
diff 1;
+    state2 += e.
diff 2;
+  }
+}
+
+}  // namespace __sanitizer

diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_range.h b/compiler-rt/lib/sanitizer_common/sanitizer_common_range.h
new file mode 100644
index 0000000000000..76e3d04b2cebb
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_range.h
@@ -0,0 +1,39 @@
+//===-- sanitizer_common_range.h --------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Contais Range and related utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_COMMON_REGION_H
+#define SANITIZER_COMMON_REGION_H
+
+#include "sanitizer_common.h"
+
+namespace __sanitizer {
+
+struct Range {
+  uptr begin;
+  uptr end;
+};
+
+inline bool operator==(const Range &lhs, const Range &rhs) {
+  return lhs.begin == rhs.begin && lhs.end == rhs.end;
+}
+
+inline bool operator!=(const Range &lhs, const Range &rhs) {
+  return !(lhs == rhs);
+}
+
+// Calculates intersection of two sets of regions in O(N log N) time.
+void Intersect(ArrayRef<Range> a, ArrayRef<Range> b,
+               InternalMmapVectorNoCtor<Range> &output);
+
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_COMMON_REGION_H

diff  --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt
index 40aa8e703b6c7..4924a9e32d774 100644
--- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt
+++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt
@@ -16,6 +16,7 @@ set(SANITIZER_UNITTESTS
   sanitizer_bitvector_test.cpp
   sanitizer_bvgraph_test.cpp
   sanitizer_chained_origin_depot_test.cpp
+  sanitizer_common_range_test.cpp
   sanitizer_common_test.cpp
   sanitizer_deadlock_detector_test.cpp
   sanitizer_dense_map_test.cpp

diff  --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_range_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_range_test.cpp
new file mode 100644
index 0000000000000..2a2e1de2a6dd5
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_range_test.cpp
@@ -0,0 +1,66 @@
+//===-- sanitizer_common_region_test.cpp ----------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_common/sanitizer_common_range.h"
+
+#include <algorithm>
+
+#include "gtest/gtest.h"
+#include "sanitizer_common/sanitizer_common.h"
+
+namespace __sanitizer {
+
+class SanitizerCommon
+    : public testing::TestWithParam<std::tuple<
+          std::vector<Range>, std::vector<Range>, std::vector<Range>>> {};
+
+TEST_P(SanitizerCommon, Intersect) {
+  {
+    InternalMmapVector<Range> output;
+    Intersect(std::get<0>(GetParam()), std::get<1>(GetParam()), output);
+    EXPECT_EQ(std::get<2>(GetParam()),
+              std::vector<Range>(output.begin(), output.end()));
+  }
+  {
+    InternalMmapVector<Range> output;
+    Intersect(std::get<1>(GetParam()), std::get<0>(GetParam()), output);
+    EXPECT_EQ(std::get<2>(GetParam()),
+              std::vector<Range>(output.begin(), output.end()));
+  }
+}
+
+static void PrintTo(const Range &r, std::ostream *os) {
+  *os << "[" << r.begin << ", " << r.end << ")";
+}
+
+static const std::tuple<std::vector<Range>, std::vector<Range>,
+                        std::vector<Range>>
+    kTests[] = {
+        {{}, {}, {}},
+        {{{100, 1000}}, {{5000, 10000}}, {}},
+        {{{100, 1000}, {200, 2000}}, {{5000, 10000}, {6000, 11000}}, {}},
+        {{{100, 1000}}, {{100, 1000}}, {{100, 1000}}},
+        {{{100, 1000}}, {{50, 150}}, {{100, 150}}},
+        {{{100, 1000}}, {{150, 250}}, {{150, 250}}},
+        {{{100, 1000}, {100, 1000}}, {{100, 1000}}, {{100, 1000}}},
+        {{{100, 1000}}, {{500, 1500}}, {{500, 1000}}},
+        {{{100, 200}}, {{200, 300}, {1, 1000}}, {{100, 200}}},
+        {{{100, 200}, {200, 300}}, {{100, 300}}, {{100, 300}}},
+        {{{100, 200}, {200, 300}, {300, 400}}, {{150, 350}}, {{150, 350}}},
+        {{{100, 200}, {300, 400}, {500, 600}},
+         {{0, 1000}},
+         {{100, 200}, {300, 400}, {500, 600}}},
+};
+
+INSTANTIATE_TEST_SUITE_P(SanitizerCommonEmpty, SanitizerCommon,
+                         testing::ValuesIn(kTests));
+
+}  // namespace __sanitizer


        


More information about the llvm-commits mailing list