//===- BlockVerifier.cpp - FDR Block Verifier -----------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "llvm/XRay/BlockVerifier.h"
#include "llvm/Support/Error.h"

namespace llvm {
namespace xray {
namespace {

constexpr unsigned long long mask(BlockVerifier::State S) {
  return 1uLL << static_cast<std::size_t>(S);
}

constexpr std::size_t number(BlockVerifier::State S) {
  return static_cast<std::size_t>(S);
}

StringRef recordToString(BlockVerifier::State R) {
  switch (R) {
  case BlockVerifier::State::BufferExtents:
    return "BufferExtents";
  case BlockVerifier::State::NewBuffer:
    return "NewBuffer";
  case BlockVerifier::State::WallClockTime:
    return "WallClockTime";
  case BlockVerifier::State::PIDEntry:
    return "PIDEntry";
  case BlockVerifier::State::NewCPUId:
    return "NewCPUId";
  case BlockVerifier::State::TSCWrap:
    return "TSCWrap";
  case BlockVerifier::State::CustomEvent:
    return "CustomEvent";
  case BlockVerifier::State::Function:
    return "Function";
  case BlockVerifier::State::CallArg:
    return "CallArg";
  case BlockVerifier::State::EndOfBuffer:
    return "EndOfBuffer";
  case BlockVerifier::State::TypedEvent:
    return "TypedEvent";
  case BlockVerifier::State::StateMax:
  case BlockVerifier::State::Unknown:
    return "Unknown";
  }
  llvm_unreachable("Unkown state!");
}

struct Transition {
  BlockVerifier::State From;
  std::bitset<number(BlockVerifier::State::StateMax)> ToStates;
};

} // namespace

Error BlockVerifier::transition(State To) {
  using ToSet = std::bitset<number(State::StateMax)>;
  static constexpr std::array<const Transition, number(State::StateMax)>
      TransitionTable{{{State::Unknown,
                        {mask(State::BufferExtents) | mask(State::NewBuffer)}},

                       {State::BufferExtents, {mask(State::NewBuffer)}},

                       {State::NewBuffer, {mask(State::WallClockTime)}},

                       {State::WallClockTime,
                        {mask(State::PIDEntry) | mask(State::NewCPUId)}},

                       {State::PIDEntry, {mask(State::NewCPUId)}},

                       {State::NewCPUId,
                        {mask(State::NewCPUId) | mask(State::TSCWrap) |
                         mask(State::CustomEvent) | mask(State::Function) |
                         mask(State::EndOfBuffer) | mask(State::TypedEvent)}},

                       {State::TSCWrap,
                        {mask(State::TSCWrap) | mask(State::NewCPUId) |
                         mask(State::CustomEvent) | mask(State::Function) |
                         mask(State::EndOfBuffer) | mask(State::TypedEvent)}},

                       {State::CustomEvent,
                        {mask(State::CustomEvent) | mask(State::TSCWrap) |
                         mask(State::NewCPUId) | mask(State::Function) |
                         mask(State::EndOfBuffer) | mask(State::TypedEvent)}},

                       {State::TypedEvent,
                        {mask(State::TypedEvent) | mask(State::TSCWrap) |
                         mask(State::NewCPUId) | mask(State::Function) |
                         mask(State::EndOfBuffer) | mask(State::CustomEvent)}},

                       {State::Function,
                        {mask(State::Function) | mask(State::TSCWrap) |
                         mask(State::NewCPUId) | mask(State::CustomEvent) |
                         mask(State::CallArg) | mask(State::EndOfBuffer) |
                         mask(State::TypedEvent)}},

                       {State::CallArg,
                        {mask(State::CallArg) | mask(State::Function) |
                         mask(State::TSCWrap) | mask(State::NewCPUId) |
                         mask(State::CustomEvent) | mask(State::EndOfBuffer) |
                         mask(State::TypedEvent)}},

                       {State::EndOfBuffer, {}}}};

  if (CurrentRecord >= State::StateMax)
    return createStringError(
        std::make_error_code(std::errc::executable_format_error),
        "BUG (BlockVerifier): Cannot find transition table entry for %s, "
        "transitioning to %s.",
        recordToString(CurrentRecord).data(), recordToString(To).data());

  // If we're at an EndOfBuffer record, we ignore anything that follows that
  // isn't a NewBuffer record.
  if (CurrentRecord == State::EndOfBuffer && To != State::NewBuffer)
    return Error::success();

  auto &Mapping = TransitionTable[number(CurrentRecord)];
  auto &Destinations = Mapping.ToStates;
  assert(Mapping.From == CurrentRecord &&
         "BUG: Wrong index for record mapping.");
  if ((Destinations & ToSet(mask(To))) == 0)
    return createStringError(
        std::make_error_code(std::errc::executable_format_error),
        "BlockVerifier: Invalid transition from %s to %s.",
        recordToString(CurrentRecord).data(), recordToString(To).data());

  CurrentRecord = To;
  return Error::success();
} // namespace xray

Error BlockVerifier::visit(BufferExtents &) {
  return transition(State::BufferExtents);
}

Error BlockVerifier::visit(WallclockRecord &) {
  return transition(State::WallClockTime);
}

Error BlockVerifier::visit(NewCPUIDRecord &) {
  return transition(State::NewCPUId);
}

Error BlockVerifier::visit(TSCWrapRecord &) {
  return transition(State::TSCWrap);
}

Error BlockVerifier::visit(CustomEventRecord &) {
  return transition(State::CustomEvent);
}

Error BlockVerifier::visit(CustomEventRecordV5 &) {
  return transition(State::CustomEvent);
}

Error BlockVerifier::visit(TypedEventRecord &) {
  return transition(State::TypedEvent);
}

Error BlockVerifier::visit(CallArgRecord &) {
  return transition(State::CallArg);
}

Error BlockVerifier::visit(PIDRecord &) { return transition(State::PIDEntry); }

Error BlockVerifier::visit(NewBufferRecord &) {
  return transition(State::NewBuffer);
}

Error BlockVerifier::visit(EndBufferRecord &) {
  return transition(State::EndOfBuffer);
}

Error BlockVerifier::visit(FunctionRecord &) {
  return transition(State::Function);
}

Error BlockVerifier::verify() {
  // The known terminal conditions are the following:
  switch (CurrentRecord) {
  case State::EndOfBuffer:
  case State::NewCPUId:
  case State::CustomEvent:
  case State::TypedEvent:
  case State::Function:
  case State::CallArg:
  case State::TSCWrap:
    return Error::success();
  default:
    return createStringError(
        std::make_error_code(std::errc::executable_format_error),
        "BlockVerifier: Invalid terminal condition %s, malformed block.",
        recordToString(CurrentRecord).data());
  }
}

void BlockVerifier::reset() { CurrentRecord = State::Unknown; }

} // namespace xray
} // namespace llvm
