brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · f98164d Raw
101 lines · plain
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-exception6//7//===----------------------------------------------------------------------===//8#pragma once9 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 25namespace llvm {26namespace offload {27bool isTracingEnabled();28bool isValidationEnabled();29bool isOffloadInitialized();30} // namespace offload31} // namespace llvm32 33// Use the StringSet container to efficiently deduplicate repeated error34// strings (e.g. if the same error is hit constantly in a long running program)35llvm::StringSet<> &errorStrs();36 37// Use an unordered_set to avoid duplicates of error structs themselves.38// We cannot store the structs directly as returned pointers to them must always39// be valid, and a rehash of the set may invalidate them. This requires40// custom hash and equal_to function objects.41using ErrPtrT = std::unique_ptr<ol_error_struct_t>;42struct ErrPtrEqual {43  bool operator()(const ErrPtrT &lhs, const ErrPtrT &rhs) const {44    if (!lhs && !rhs) {45      return true;46    }47    if (!lhs || !rhs) {48      return false;49    }50 51    bool StrsEqual = false;52    if (lhs->Details == NULL && rhs->Details == NULL) {53      StrsEqual = true;54    } else if (lhs->Details != NULL && rhs->Details != NULL) {55      StrsEqual = (std::strcmp(lhs->Details, rhs->Details) == 0);56    }57    return (lhs->Code == rhs->Code) && StrsEqual;58  }59};60struct ErrPtrHash {61  size_t operator()(const ErrPtrT &e) const {62    if (!e) {63      // We shouldn't store empty errors (i.e. success), but just in case64      return 0lu;65    } else {66      return std::hash<int>{}(e->Code);67    }68  }69};70using ErrSetT = std::unordered_set<ErrPtrT, ErrPtrHash, ErrPtrEqual>;71ErrSetT &errors();72 73namespace {74ol_errc_t GetErrorCode(std::error_code Code) {75  if (Code.category() ==76      error::make_error_code(error::ErrorCode::SUCCESS).category())77    return static_cast<ol_errc_t>(Code.value());78 79  return OL_ERRC_UNKNOWN;80}81} // namespace82 83inline ol_result_t llvmErrorToOffloadError(llvm::Error &&Err) {84  if (!Err) {85    // No error86    return nullptr;87  }88 89  ol_errc_t ErrCode;90  llvm::StringRef Details;91 92  llvm::handleAllErrors(std::move(Err), [&](llvm::StringError &Err) {93    ErrCode = GetErrorCode(Err.convertToErrorCode());94    Details = errorStrs().insert(Err.getMessage()).first->getKeyData();95  });96 97  auto NewErr = std::unique_ptr<ol_error_struct_t>(98      new ol_error_struct_t{ErrCode, Details.data()});99  return errors().emplace(std::move(NewErr)).first->get();100}101