//===----------------------- CodeRegionGenerator.cpp ------------*- 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
//
//===----------------------------------------------------------------------===//
/// \file
///
/// This file defines classes responsible for generating llvm-mca
/// CodeRegions from various types of input. llvm-mca only analyzes CodeRegions,
/// so the classes here provide the input-to-CodeRegions translation.
//
//===----------------------------------------------------------------------===//

#include "CodeRegionGenerator.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/SMLoc.h"
#include <memory>

namespace llvm {
namespace mca {

// This virtual dtor serves as the anchor for the CodeRegionGenerator class.
CodeRegionGenerator::~CodeRegionGenerator() {}

Expected<const CodeRegions &> AsmCodeRegionGenerator::parseCodeRegions(
    const std::unique_ptr<MCInstPrinter> &IP, bool SkipFailures) {
  MCTargetOptions Opts;
  Opts.PreserveAsmComments = false;
  CodeRegions &Regions = getRegions();
  MCStreamerWrapper *Str = getMCStreamer();

  // Need to initialize an MCTargetStreamer otherwise
  // certain asm directives will cause a segfault.
  // Using nulls() so that anything emitted by the MCTargetStreamer
  // doesn't show up in the llvm-mca output.
  raw_ostream &OSRef = nulls();
  formatted_raw_ostream FOSRef(OSRef);
  TheTarget.createAsmTargetStreamer(*Str, FOSRef, IP.get());

  // Create a MCAsmParser and setup the lexer to recognize llvm-mca ASM
  // comments.
  std::unique_ptr<MCAsmParser> Parser(
      createMCAsmParser(Regions.getSourceMgr(), Ctx, *Str, MAI));
  AsmLexer &Lexer = Parser->getLexer();
  MCACommentConsumer *CCP = getCommentConsumer();
  Lexer.setCommentConsumer(CCP);
  // Enable support for MASM literal numbers (example: 05h, 101b).
  Lexer.setLexMasmIntegers(true);

  std::unique_ptr<MCTargetAsmParser> TAP(
      TheTarget.createMCAsmParser(STI, *Parser, MCII, Opts));
  if (!TAP)
    return make_error<StringError>(
        "This target does not support assembly parsing.",
        inconvertibleErrorCode());
  Parser->setTargetParser(*TAP);
  // Parser->Run() confusingly returns true on errors, in which case the errors
  // were already shown to the user. SkipFailures implies continuing in the
  // presence of any kind of failure within the parser, in which case failing
  // input lines are not represented, but the rest of the input remains.
  if (Parser->Run(false) && !SkipFailures) {
    const char *Message = "Assembly input parsing had errors, use "
                          "-skip-unsupported-instructions=parse-failure "
                          "to drop failing lines from the input.";
    return make_error<StringError>(Message, inconvertibleErrorCode());
  }

  if (CCP->hadErr())
    return make_error<StringError>("There was an error parsing comments.",
                                   inconvertibleErrorCode());

  // Set the assembler dialect from the input. llvm-mca will use this as the
  // default dialect when printing reports.
  AssemblerDialect = Parser->getAssemblerDialect();
  return Regions;
}

void AnalysisRegionCommentConsumer::HandleComment(SMLoc Loc,
                                                  StringRef CommentText) {
  // Skip empty comments.
  StringRef Comment(CommentText);
  if (Comment.empty())
    return;

  // Skip spaces and tabs.
  unsigned Position = Comment.find_first_not_of(" \t");
  if (Position >= Comment.size())
    // We reached the end of the comment. Bail out.
    return;

  Comment = Comment.drop_front(Position);
  if (Comment.consume_front("LLVM-MCA-END")) {
    // Skip spaces and tabs.
    Position = Comment.find_first_not_of(" \t");
    if (Position < Comment.size())
      Comment = Comment.drop_front(Position);
    Regions.endRegion(Comment, Loc);
    return;
  }

  // Try to parse the LLVM-MCA-BEGIN comment.
  if (!Comment.consume_front("LLVM-MCA-BEGIN"))
    return;

  // Skip spaces and tabs.
  Position = Comment.find_first_not_of(" \t");
  if (Position < Comment.size())
    Comment = Comment.drop_front(Position);
  // Use the rest of the string as a descriptor for this code snippet.
  Regions.beginRegion(Comment, Loc);
}

void InstrumentRegionCommentConsumer::HandleComment(SMLoc Loc,
                                                    StringRef CommentText) {
  // Skip empty comments.
  StringRef Comment(CommentText);
  if (Comment.empty())
    return;

  // Skip spaces and tabs.
  unsigned Position = Comment.find_first_not_of(" \t");
  if (Position >= Comment.size())
    // We reached the end of the comment. Bail out.
    return;
  Comment = Comment.drop_front(Position);

  // Bail out if not an MCA style comment
  if (!Comment.consume_front("LLVM-MCA-"))
    return;

  // Skip AnalysisRegion comments
  if (Comment.consume_front("BEGIN") || Comment.consume_front("END"))
    return;

  if (IM.shouldIgnoreInstruments())
    return;

  auto [InstrumentKind, Data] = Comment.split(" ");

  // An error if not of the form LLVM-MCA-TARGET-KIND
  if (!IM.supportsInstrumentType(InstrumentKind)) {
    if (InstrumentKind.empty())
      SM.PrintMessage(
          Loc, llvm::SourceMgr::DK_Error,
          "No instrumentation kind was provided in LLVM-MCA comment");
    else
      SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
                      "Unknown instrumentation type in LLVM-MCA comment: " +
                          InstrumentKind);
    FoundError = true;
    return;
  }

  UniqueInstrument I = IM.createInstrument(InstrumentKind, Data);
  if (!I) {
    if (Data.empty())
      SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
                      "Failed to create " + InstrumentKind +
                          " instrument with no data");
    else
      SM.PrintMessage(Loc, llvm::SourceMgr::DK_Error,
                      "Failed to create " + InstrumentKind +
                          " instrument with data: " + Data);
    FoundError = true;
    return;
  }

  // End InstrumentType region if one is open
  if (Regions.isRegionActive(InstrumentKind))
    Regions.endRegion(InstrumentKind, Loc);
  // Start new instrumentation region
  Regions.beginRegion(InstrumentKind, Loc, std::move(I));
}

} // namespace mca
} // namespace llvm
