1*679d9ea1SVitaly Buka //===-- sanitizer_range.cpp -----------------------------------------------===//
2*679d9ea1SVitaly Buka //
3*679d9ea1SVitaly Buka // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*679d9ea1SVitaly Buka // See https://llvm.org/LICENSE.txt for license information.
5*679d9ea1SVitaly Buka // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*679d9ea1SVitaly Buka //
7*679d9ea1SVitaly Buka //===----------------------------------------------------------------------===//
8*679d9ea1SVitaly Buka
9*679d9ea1SVitaly Buka #include "sanitizer_range.h"
10*679d9ea1SVitaly Buka
11*679d9ea1SVitaly Buka #include "sanitizer_common/sanitizer_array_ref.h"
12*679d9ea1SVitaly Buka
13*679d9ea1SVitaly Buka namespace __sanitizer {
14*679d9ea1SVitaly Buka
Intersect(ArrayRef<Range> a,ArrayRef<Range> b,InternalMmapVectorNoCtor<Range> & output)15*679d9ea1SVitaly Buka void Intersect(ArrayRef<Range> a, ArrayRef<Range> b,
16*679d9ea1SVitaly Buka InternalMmapVectorNoCtor<Range> &output) {
17*679d9ea1SVitaly Buka output.clear();
18*679d9ea1SVitaly Buka
19*679d9ea1SVitaly Buka struct Event {
20*679d9ea1SVitaly Buka uptr val;
21*679d9ea1SVitaly Buka s8 diff1;
22*679d9ea1SVitaly Buka s8 diff2;
23*679d9ea1SVitaly Buka };
24*679d9ea1SVitaly Buka
25*679d9ea1SVitaly Buka InternalMmapVector<Event> events;
26*679d9ea1SVitaly Buka for (const Range &r : a) {
27*679d9ea1SVitaly Buka CHECK_LE(r.begin, r.end);
28*679d9ea1SVitaly Buka events.push_back({r.begin, 1, 0});
29*679d9ea1SVitaly Buka events.push_back({r.end, -1, 0});
30*679d9ea1SVitaly Buka }
31*679d9ea1SVitaly Buka
32*679d9ea1SVitaly Buka for (const Range &r : b) {
33*679d9ea1SVitaly Buka CHECK_LE(r.begin, r.end);
34*679d9ea1SVitaly Buka events.push_back({r.begin, 0, 1});
35*679d9ea1SVitaly Buka events.push_back({r.end, 0, -1});
36*679d9ea1SVitaly Buka }
37*679d9ea1SVitaly Buka
38*679d9ea1SVitaly Buka Sort(events.data(), events.size(),
39*679d9ea1SVitaly Buka [](const Event &lh, const Event &rh) { return lh.val < rh.val; });
40*679d9ea1SVitaly Buka
41*679d9ea1SVitaly Buka uptr start = 0;
42*679d9ea1SVitaly Buka sptr state1 = 0;
43*679d9ea1SVitaly Buka sptr state2 = 0;
44*679d9ea1SVitaly Buka for (const auto &e : events) {
45*679d9ea1SVitaly Buka if (e.val != start) {
46*679d9ea1SVitaly Buka DCHECK_GE(state1, 0);
47*679d9ea1SVitaly Buka DCHECK_GE(state2, 0);
48*679d9ea1SVitaly Buka if (state1 && state2) {
49*679d9ea1SVitaly Buka if (!output.empty() && start == output.back().end)
50*679d9ea1SVitaly Buka output.back().end = e.val;
51*679d9ea1SVitaly Buka else
52*679d9ea1SVitaly Buka output.push_back({start, e.val});
53*679d9ea1SVitaly Buka }
54*679d9ea1SVitaly Buka start = e.val;
55*679d9ea1SVitaly Buka }
56*679d9ea1SVitaly Buka
57*679d9ea1SVitaly Buka state1 += e.diff1;
58*679d9ea1SVitaly Buka state2 += e.diff2;
59*679d9ea1SVitaly Buka }
60*679d9ea1SVitaly Buka }
61*679d9ea1SVitaly Buka
62*679d9ea1SVitaly Buka } // namespace __sanitizer
63