blob: 8f37e1be211dffe417786e5996aa7a8f3d42ddfd [file] [log] [blame]
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_MLIR_EDGE_IREE_BASE_INTERNAL_LOGGING_H_
#define THIRD_PARTY_MLIR_EDGE_IREE_BASE_INTERNAL_LOGGING_H_
#include <cstdint>
#include <sstream>
#include "third_party/absl/base/attributes.h"
#include "third_party/absl/base/optimization.h"
namespace iree {
// ------------------------------------------------------------------------- //
// | LOG | //
// ------------------------------------------------------------------------- //
// Severity levels for LOG().
const int INFO = 0; // absl::LogSeverity::kInfo
const int WARNING = 1; // absl::LogSeverity::kWarning
const int ERROR = 2; // absl::LogSeverity::kError
const int FATAL = 3; // absl::LogSeverity::kFatal
namespace internal {
class LogMessage : public std::basic_ostringstream<char> {
public:
LogMessage(const char* file_name, int line, int severity);
~LogMessage();
const char* file_name() const { return file_name_; }
int line() const { return line_; }
int severity() const { return severity_; }
// Returns the minimum log level for VLOG statements.
// E.g., if MinVLogLevel() is 2, then VLOG(2) statements will produce output,
// but VLOG(3) will not. Defaults to 0.
static int64_t MinVLogLevel();
protected:
void EmitLogMessage();
private:
const char* file_name_;
int line_;
int severity_;
};
// LogMessageFatal ensures the process exits in failure after logging a message.
class LogMessageFatal : public LogMessage {
public:
LogMessageFatal(const char* file, int line) ABSL_ATTRIBUTE_COLD;
ABSL_ATTRIBUTE_NORETURN ~LogMessageFatal();
};
// NullStream implements operator<< but does nothing.
class NullStream {
public:
NullStream& stream() { return *this; }
};
template <typename T>
inline NullStream& operator<<(NullStream& str, const T&) {
return str;
}
inline NullStream& operator<<(NullStream& str,
std::ostream& (*)(std::ostream& os)) {
return str;
}
inline NullStream& operator<<(NullStream& str,
std::ios_base& (*)(std::ios_base& os)) {
return str;
}
#define _IREE_LOG_INFO \
::iree::internal::LogMessage(__FILE__, __LINE__, ::iree::INFO)
#define _IREE_LOG_WARNING \
::iree::internal::LogMessage(__FILE__, __LINE__, ::iree::WARNING)
#define _IREE_LOG_ERROR \
::iree::internal::LogMessage(__FILE__, __LINE__, ::iree::ERROR)
#define _IREE_LOG_FATAL ::iree::internal::LogMessageFatal(__FILE__, __LINE__)
#define LOG(severity) _IREE_LOG_##severity
#define VLOG_IS_ON(lvl) ((lvl) <= ::iree::internal::LogMessage::MinVLogLevel())
#define VLOG(lvl) \
if (ABSL_PREDICT_FALSE(VLOG_IS_ON(lvl))) \
::iree::internal::LogMessage(__FILE__, __LINE__, ::iree::INFO)
// `DVLOG` behaves like `VLOG` in debug mode (i.e. `#ifndef NDEBUG`).
// Otherwise, it compiles away and does nothing.
#ifndef NDEBUG
#define DVLOG VLOG
#else
#define DVLOG(verbose_level) \
while (false && (verbose_level) > 0) ::iree::internal::NullStream().stream()
#endif // !NDEBUG
// ------------------------------------------------------------------------- //
// | CHECK | //
// ------------------------------------------------------------------------- //
// CHECK dies with a fatal error if condition is not true. It is *not*
// controlled by NDEBUG, so the check will be executed regardless of
// compilation mode. Therefore, it is safe to do things like:
// CHECK(fp->Write(x) == 4)
#define CHECK(condition) \
if (ABSL_PREDICT_FALSE(!(condition))) \
LOG(FATAL) << "Check failed: " #condition " "
// TODO(scotttodd): Log information about the check failure
#define CHECK_OP_LOG(name, op, val1, val2) LOG(FATAL) << "Check failed"
#define CHECK_OP(name, op, val1, val2) CHECK_OP_LOG(name, op, val1, val2)
// CHECK_EQ/NE/...
#define CHECK_EQ(val1, val2) CHECK_OP(Check_EQ, ==, val1, val2)
#define CHECK_NE(val1, val2) CHECK_OP(Check_NE, !=, val1, val2)
#define CHECK_LE(val1, val2) CHECK_OP(Check_LE, <=, val1, val2)
#define CHECK_LT(val1, val2) CHECK_OP(Check_LT, <, val1, val2)
#define CHECK_GE(val1, val2) CHECK_OP(Check_GE, >=, val1, val2)
#define CHECK_GT(val1, val2) CHECK_OP(Check_GT, >, val1, val2)
#ifndef NDEBUG
#define DCHECK(condition) CHECK(condition)
#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2)
#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2)
#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2)
#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2)
#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2)
#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2)
#else
#define DCHECK(condition) \
while (false && (condition)) LOG(FATAL)
// NDEBUG is defined, so DCHECK_EQ(x, y) and so on do nothing.
// However, we still want the compiler to parse x and y, because
// we don't want to lose potentially useful errors and warnings.
// _DCHECK_NOP is a helper, and should not be used outside of this file.
#define _IREE_DCHECK_NOP(x, y) \
while (false && ((void)(x), (void)(y), 0)) LOG(FATAL)
#define DCHECK_EQ(x, y) _IREE_DCHECK_NOP(x, y)
#define DCHECK_NE(x, y) _IREE_DCHECK_NOP(x, y)
#define DCHECK_LE(x, y) _IREE_DCHECK_NOP(x, y)
#define DCHECK_LT(x, y) _IREE_DCHECK_NOP(x, y)
#define DCHECK_GE(x, y) _IREE_DCHECK_NOP(x, y)
#define DCHECK_GT(x, y) _IREE_DCHECK_NOP(x, y)
#endif // !NDEBUG
// These are for when you don't want a CHECK failure to print a verbose
// stack trace. The implementation of CHECK* in this file already doesn't.
#define QCHECK(condition) CHECK(condition)
#define QCHECK_EQ(x, y) CHECK_EQ(x, y)
#define QCHECK_NE(x, y) CHECK_NE(x, y)
#define QCHECK_LE(x, y) CHECK_LE(x, y)
#define QCHECK_LT(x, y) CHECK_LT(x, y)
#define QCHECK_GE(x, y) CHECK_GE(x, y)
#define QCHECK_GT(x, y) CHECK_GT(x, y)
} // namespace internal
} // namespace iree
#endif // THIRD_PARTY_MLIR_EDGE_IREE_BASE_INTERNAL_LOGGING_H_