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
25struct OffloadConfig {
26 bool TracingEnabled = false;
27 bool ValidationEnabled = true;
28};
29
30OffloadConfig &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)
34llvm::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.
40using ErrPtrT = std::unique_ptr<ol_error_struct_t>;
41struct 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};
59struct 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};
69using ErrSetT = std::unordered_set<ErrPtrT, ErrPtrHash, ErrPtrEqual>;
70ErrSetT &errors();
71
72namespace {
73ol_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
82inline 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.

source code of offload/liboffload/include/OffloadImpl.hpp