Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | //===- offload_impl.hpp- Implementation helpers for the Offload library ---===// |
---|---|
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 | #pragma once |
9 | |
10 | #include "PluginInterface.h" |
11 | #include <OffloadAPI.h> |
12 | #include <iostream> |
13 | #include <memory> |
14 | #include <optional> |
15 | #include <set> |
16 | #include <string> |
17 | #include <unordered_set> |
18 | #include <vector> |
19 | |
20 | #include "llvm/ADT/DenseSet.h" |
21 | #include "llvm/ADT/StringRef.h" |
22 | #include "llvm/ADT/StringSet.h" |
23 | #include "llvm/Support/Error.h" |
24 | |
25 | struct OffloadConfig { |
26 | bool TracingEnabled = false; |
27 | bool ValidationEnabled = true; |
28 | }; |
29 | |
30 | OffloadConfig &offloadConfig(); |
31 | |
32 | // Use the StringSet container to efficiently deduplicate repeated error |
33 | // strings (e.g. if the same error is hit constantly in a long running program) |
34 | llvm::StringSet<> &errorStrs(); |
35 | |
36 | // Use an unordered_set to avoid duplicates of error structs themselves. |
37 | // We cannot store the structs directly as returned pointers to them must always |
38 | // be valid, and a rehash of the set may invalidate them. This requires |
39 | // custom hash and equal_to function objects. |
40 | using ErrPtrT = std::unique_ptr<ol_error_struct_t>; |
41 | struct ErrPtrEqual { |
42 | bool operator()(const ErrPtrT &lhs, const ErrPtrT &rhs) const { |
43 | if (!lhs && !rhs) { |
44 | return true; |
45 | } |
46 | if (!lhs || !rhs) { |
47 | return false; |
48 | } |
49 | |
50 | bool StrsEqual = false; |
51 | if (lhs->Details == NULL && rhs->Details == NULL) { |
52 | StrsEqual = true; |
53 | } else if (lhs->Details != NULL && rhs->Details != NULL) { |
54 | StrsEqual = (std::strcmp(s1: lhs->Details, s2: rhs->Details) == 0); |
55 | } |
56 | return (lhs->Code == rhs->Code) && StrsEqual; |
57 | } |
58 | }; |
59 | struct ErrPtrHash { |
60 | size_t operator()(const ErrPtrT &e) const { |
61 | if (!e) { |
62 | // We shouldn't store empty errors (i.e. success), but just in case |
63 | return 0lu; |
64 | } else { |
65 | return std::hash<int>{}(e->Code); |
66 | } |
67 | } |
68 | }; |
69 | using ErrSetT = std::unordered_set<ErrPtrT, ErrPtrHash, ErrPtrEqual>; |
70 | ErrSetT &errors(); |
71 | |
72 | namespace { |
73 | ol_errc_t GetErrorCode(std::error_code Code) { |
74 | if (Code.category() == |
75 | error::make_error_code(error::ErrorCode::SUCCESS).category()) |
76 | return static_cast<ol_errc_t>(Code.value()); |
77 | |
78 | return OL_ERRC_UNKNOWN; |
79 | } |
80 | } // namespace |
81 | |
82 | inline ol_result_t llvmErrorToOffloadError(llvm::Error &&Err) { |
83 | if (!Err) { |
84 | // No error |
85 | return nullptr; |
86 | } |
87 | |
88 | ol_errc_t ErrCode; |
89 | llvm::StringRef Details; |
90 | |
91 | llvm::handleAllErrors(E: std::move(Err), Handlers: [&](llvm::StringError &Err) { |
92 | ErrCode = GetErrorCode(Err.convertToErrorCode()); |
93 | Details = errorStrs().insert(key: Err.getMessage()).first->getKeyData(); |
94 | }); |
95 | |
96 | auto NewErr = std::unique_ptr<ol_error_struct_t>( |
97 | new ol_error_struct_t{ErrCode, Details.data()}); |
98 | return errors().emplace(std::move(NewErr)).first->get(); |
99 | } |
100 |
Warning: That file was not part of the compilation database. It may have many parsing errors.