[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