[libc] Switch to using the generic `<gpuintrin.h>` implementations (#121810)
[llvm-project.git] / compiler-rt / lib / orc / record_section_tracker.h
blob1ac729a9539196fefc1caf58b8aa788bcf712548
1 //===- record_section_tracker.h -- for fixed-sized record sects -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // RecordSectionsTracker: Responsible for managing sections of metadata records
10 // with fixed sizes.
12 //===----------------------------------------------------------------------===//
14 #ifndef ORC_RT_RECORD_SECTION_TRACKER_H
15 #define ORC_RT_RECORD_SECTION_TRACKER_H
17 #include "error.h"
18 #include "executor_address.h"
19 #include <algorithm>
20 #include <vector>
22 namespace orc_rt {
24 /// Used to manage sections of fixed-sized metadata records (e.g. pointer
25 /// sections, selector refs, etc.)
26 template <typename RecordElement> class RecordSectionsTracker {
27 public:
28 /// Add a section to the "new" list.
29 void add(span<RecordElement> Sec) { New.push_back(std::move(Sec)); }
31 /// Returns true if there are new sections to process.
32 bool hasNewSections() const { return !New.empty(); }
34 /// Returns the number of new sections to process.
35 size_t numNewSections() const { return New.size(); }
37 /// Process all new sections.
38 template <typename ProcessSectionFunc>
39 std::enable_if_t<std::is_void_v<
40 std::invoke_result_t<ProcessSectionFunc, span<RecordElement>>>>
41 processNewSections(ProcessSectionFunc &&ProcessSection) {
42 for (auto &Sec : New)
43 ProcessSection(Sec);
44 moveNewToProcessed();
47 /// Proces all new sections with a fallible handler.
48 ///
49 /// Successfully handled sections will be moved to the Processed
50 /// list.
51 template <typename ProcessSectionFunc>
52 std::enable_if_t<
53 std::is_same_v<
54 Error, std::invoke_result_t<ProcessSectionFunc, span<RecordElement>>>,
55 Error>
56 processNewSections(ProcessSectionFunc &&ProcessSection) {
57 for (size_t I = 0; I != New.size(); ++I) {
58 if (auto Err = ProcessSection(New[I])) {
59 for (size_t J = 0; J != I; ++J)
60 Processed.push_back(New[J]);
61 New.erase(New.begin(), New.begin() + I);
62 return Err;
65 moveNewToProcessed();
66 return Error::success();
69 /// Move all sections back to New for reprocessing.
70 void reset() {
71 moveNewToProcessed();
72 New = std::move(Processed);
75 /// Remove the section with the given range.
76 bool removeIfPresent(ExecutorAddrRange R) {
77 if (removeIfPresent(New, R))
78 return true;
79 return removeIfPresent(Processed, R);
82 private:
83 void moveNewToProcessed() {
84 if (Processed.empty())
85 Processed = std::move(New);
86 else {
87 Processed.reserve(Processed.size() + New.size());
88 std::copy(New.begin(), New.end(), std::back_inserter(Processed));
89 New.clear();
93 bool removeIfPresent(std::vector<span<RecordElement>> &V,
94 ExecutorAddrRange R) {
95 auto RI = std::find_if(
96 V.rbegin(), V.rend(),
97 [RS = R.toSpan<RecordElement>()](const span<RecordElement> &E) {
98 return E.data() == RS.data();
99 });
100 if (RI != V.rend()) {
101 V.erase(std::next(RI).base());
102 return true;
104 return false;
107 std::vector<span<RecordElement>> Processed;
108 std::vector<span<RecordElement>> New;
111 } // namespace orc_rt
113 #endif // ORC_RT_RECORD_SECTION_TRACKER_H