diff --git a/compiler-rt/lib/orc/CMakeLists.txt b/compiler-rt/lib/orc/CMakeLists.txt --- a/compiler-rt/lib/orc/CMakeLists.txt +++ b/compiler-rt/lib/orc/CMakeLists.txt @@ -2,6 +2,7 @@ # ORC runtime library implementation files. set(ORC_SOURCES + debug.cpp extensible_rtti.cpp log_error_to_stderr.cpp macho_ehframe_registration.cpp diff --git a/compiler-rt/lib/orc/debug.h b/compiler-rt/lib/orc/debug.h new file mode 100644 --- /dev/null +++ b/compiler-rt/lib/orc/debug.h @@ -0,0 +1,56 @@ +//===- debug.h - Debugging output utilities ---------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of the ORC runtime support library. +// +//===----------------------------------------------------------------------===// + +#ifndef ORC_RT_DEBUG_H +#define ORC_RT_DEBUG_H + +#include + +#ifndef NDEBUG + +namespace __orc_rt { + +extern std::atomic DebugTypes; +extern char DebugTypesAll; +extern char DebugTypesNone; + +const char *initializeDebug(); +bool debugTypeEnabled(const char *Type, const char *Types); +void printdbg(const char *format, ...); + +} // namespace __orc_rt + +#define ORC_RT_DEBUG_WITH_TYPE(TYPE, X) \ + do { \ + const char *Types = \ + ::__orc_rt::DebugTypes.load(std::memory_order_relaxed); \ + if (!Types) \ + Types = initializeDebug(); \ + if (Types == &DebugTypesNone) \ + break; \ + if (Types == &DebugTypesAll || \ + ::__orc_rt::debugTypeEnabled(TYPE, Types)) { \ + X; \ + } \ + } while (false) + +#else + +#define ORC_RT_DEBUG_WITH_TYPE(TYPE, X) \ + do { \ + } while (false) + +#endif // !NDEBUG + +#define ORC_RT_DEBUG(X) ORC_RT_DEBUG_WITH_TYPE(DEBUG_TYPE, X) + +#endif // ORC_RT_COMMON_H diff --git a/compiler-rt/lib/orc/debug.cpp b/compiler-rt/lib/orc/debug.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/lib/orc/debug.cpp @@ -0,0 +1,74 @@ +//===- debug.cpp ----------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of the ORC runtime support library. +// +//===----------------------------------------------------------------------===// + +#include "debug.h" + +#include +#include +#include + +namespace __orc_rt { + +#ifndef NDEBUG + +std::atomic DebugTypes; +char DebugTypesAll; +char DebugTypesNone; + +/// Sets the DebugState and DebugTypes values -- this function may be called +/// concurrently on multiple threads, but will always assign the same values so +/// this should be safe. +const char *initializeDebug() { + if (const char *DT = getenv("ORC_RT_DEBUG")) { + if (strcmp(DT, "") == 0 || strcmp(DT, "1") == 0) { + DebugTypes.store(&DebugTypesAll, std::memory_order_relaxed); + return &DebugTypesAll; + } else { + DebugTypes.store(DT, std::memory_order_relaxed); + return DT; + } + } else { + DebugTypes.store(&DebugTypesNone, std::memory_order_relaxed); + return &DebugTypesAll; + } +} + +bool debugTypeEnabled(const char *Type, const char *Types) { + assert(Types && Types != &DebugTypesAll && Types != &DebugTypesNone && + "Invalid Types value"); + size_t TypeLen = strlen(Type); + const char *Start = Types; + const char *End = Start; + + do { + if (*End == '\0' || *End == ',') { + size_t ItemLen = End - Start; + if (ItemLen == TypeLen && memcmp(Type, Start, TypeLen) == 0) + return true; + if (*End == '\0') + return false; + Start = End + 1; + } + ++End; + } while (true); +} + +void printdbg(const char *format, ...) { + va_list Args; + va_start(Args, format); + vfprintf(stderr, format, Args); + va_end(Args); +} + +#endif // !NDEBUG + +} // end namespace __orc_rt