Commit abe01e17 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Revert "[llvm-exegesis] Improve error reporting" and follow-up.

It broke e.g. all tests under tools/llvm-exegesis/X86/ when libpfm is
not available, see comment on D74085.

This reverts commit b3576f60 and
14191596.
parent 4c330be6
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ std::unique_ptr<SnippetGenerator> ExegesisTarget::createSnippetGenerator(
  return nullptr;
}

Expected<std::unique_ptr<BenchmarkRunner>>
std::unique_ptr<BenchmarkRunner>
ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
                                      const LLVMState &State) const {
  PfmCountersInfo PfmCounters = State.getPfmCounters();
@@ -66,16 +66,14 @@ ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
      const char *ModeName = Mode == InstructionBenchmark::Latency
                                 ? "latency"
                                 : "inverse_throughput";
      return make_error<Failure>(
          Twine("can't run '")
              .concat(ModeName)
              .concat("' mode, sched model does not define a cycle counter."));
      report_fatal_error(Twine("can't run '").concat(ModeName).concat("' mode, "
                               "sched model does not define a cycle counter."));
    }
    return createLatencyBenchmarkRunner(State, Mode);
  case InstructionBenchmark::Uops:
    if (!PfmCounters.UopsCounter && !PfmCounters.IssueCounters)
      return make_error<Failure>("can't run 'uops' mode, sched model does not "
                                 "define uops or issue counters.");
      report_fatal_error("can't run 'uops' mode, sched model does not define "
                         "uops or issue counters.");
    return createUopsBenchmarkRunner(State);
  }
  return nullptr;
+1 −1
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ public:
                         const LLVMState &State,
                         const SnippetGenerator::Options &Opts) const;
  // Creates a benchmark runner for the given mode.
  Expected<std::unique_ptr<BenchmarkRunner>>
  std::unique_ptr<BenchmarkRunner>
  createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
                        const LLVMState &State) const;

+24 −49
Original line number Diff line number Diff line
@@ -160,27 +160,7 @@ static cl::opt<bool>
                              "and prints a message to access it"),
                     cl::cat(BenchmarkOptions), cl::init(true));

static ExitOnError ExitOnErr("llvm-exegesis error: ");

// Helper function that logs the error(s) and exits.
template <typename... ArgTs> static void ExitWithError(ArgTs &&... Args) {
  ExitOnErr(make_error<Failure>(std::forward<ArgTs>(Args)...));
}

// Check Err. If it's in a failure state log the file error(s) and exit.
static void ExitOnFileError(const Twine &FileName, Error Err) {
  if (Err) {
    ExitOnErr(createFileError(FileName, std::move(Err)));
  }
}

// Check E. If it's in a success state then return the contained value.
// If it's in a failure state log the file error(s) and exit.
template <typename T>
T ExitOnFileError(const Twine &FileName, Expected<T> &&E) {
  ExitOnFileError(FileName, E.takeError());
  return std::move(*E);
}
static ExitOnError ExitOnErr;

// Checks that only one of OpcodeNames, OpcodeIndex or SnippetsFile is provided,
// and returns the opcode indices or {} if snippets should be read from
@@ -189,11 +169,10 @@ static std::vector<unsigned> getOpcodesOrDie(const MCInstrInfo &MCInstrInfo) {
  const size_t NumSetFlags = (OpcodeNames.empty() ? 0 : 1) +
                             (OpcodeIndex == 0 ? 0 : 1) +
                             (SnippetsFile.empty() ? 0 : 1);
  if (NumSetFlags != 1) {
    ExitOnErr.setBanner("llvm-exegesis: ");
    ExitWithError("please provide one and only one of 'opcode-index', "
                  "'opcode-name' or 'snippets-file'");
  }
  if (NumSetFlags != 1)
    report_fatal_error(
        "please provide one and only one of 'opcode-index', 'opcode-name' or "
        "'snippets-file'");
  if (!SnippetsFile.empty())
    return {};
  if (OpcodeIndex > 0)
@@ -219,7 +198,7 @@ static std::vector<unsigned> getOpcodesOrDie(const MCInstrInfo &MCInstrInfo) {
    if (unsigned Opcode = ResolveName(OpcodeName))
      Result.push_back(Opcode);
    else
      ExitWithError(Twine("unknown opcode ").concat(OpcodeName));
      report_fatal_error(Twine("unknown opcode ").concat(OpcodeName));
  }
  return Result;
}
@@ -244,17 +223,18 @@ generateSnippets(const LLVMState &State, unsigned Opcode,
      State.getExegesisTarget().createSnippetGenerator(BenchmarkMode, State,
                                                       SnippetOptions);
  if (!Generator)
    ExitWithError("cannot create snippet generator");
    report_fatal_error("cannot create snippet generator");
  return Generator->generateConfigurations(Instr, ForbiddenRegs);
}

void benchmarkMain() {
#ifndef HAVE_LIBPFM
  ExitWithError("benchmarking unavailable, LLVM was built without libpfm.");
  report_fatal_error(
      "benchmarking unavailable, LLVM was built without libpfm.");
#endif

  if (exegesis::pfm::pfmInitialize())
    ExitWithError("cannot initialize libpfm");
    report_fatal_error("cannot initialize libpfm");

  InitializeNativeTarget();
  InitializeNativeTargetAsmPrinter();
@@ -263,10 +243,10 @@ void benchmarkMain() {

  const LLVMState State(CpuName);

  const std::unique_ptr<BenchmarkRunner> Runner = ExitOnErr(
      State.getExegesisTarget().createBenchmarkRunner(BenchmarkMode, State));
  const std::unique_ptr<BenchmarkRunner> Runner =
      State.getExegesisTarget().createBenchmarkRunner(BenchmarkMode, State);
  if (!Runner) {
    ExitWithError("cannot create benchmark runner");
    report_fatal_error("cannot create benchmark runner");
  }

  const auto Opcodes = getOpcodesOrDie(State.getInstrInfo());
@@ -299,10 +279,8 @@ void benchmarkMain() {
    Configurations = ExitOnErr(readSnippets(State, SnippetsFile));
  }

  if (NumRepetitions == 0) {
    ExitOnErr.setBanner("llvm-exegesis: ");
    ExitWithError("--num-repetitions must be greater than zero");
  }
  if (NumRepetitions == 0)
    report_fatal_error("--num-repetitions must be greater than zero");

  // Write to standard output if file is not set.
  if (BenchmarkFile.empty())
@@ -311,7 +289,7 @@ void benchmarkMain() {
  for (const BenchmarkCode &Conf : Configurations) {
    InstructionBenchmark Result = Runner->runConfiguration(
        Conf, NumRepetitions, *Repetitor, DumpObjectToDisk);
    ExitOnFileError(BenchmarkFile, Result.writeYaml(State, BenchmarkFile));
    ExitOnErr(Result.writeYaml(State, BenchmarkFile));
  }
  exegesis::pfm::pfmTerminate();
}
@@ -331,32 +309,29 @@ static void maybeRunAnalysis(const Analysis &Analyzer, const std::string &Name,
  raw_fd_ostream ClustersOS(OutputFilename, ErrorCode,
                            sys::fs::FA_Read | sys::fs::FA_Write);
  if (ErrorCode)
    ExitOnFileError(OutputFilename, errorCodeToError(ErrorCode));
    report_fatal_error("cannot open out file: " + OutputFilename);
  if (auto Err = Analyzer.run<Pass>(ClustersOS))
    ExitOnFileError(OutputFilename, std::move(Err));
    report_fatal_error(std::move(Err));
}

static void analysisMain() {
  ExitOnErr.setBanner("llvm-exegesis: ");
  if (BenchmarkFile.empty())
    ExitWithError("--benchmarks-file must be set");
    report_fatal_error("--benchmarks-file must be set.");

  if (AnalysisClustersOutputFile.empty() &&
      AnalysisInconsistenciesOutputFile.empty()) {
    ExitWithError(
        "for --mode=analysis: At least one of --analysis-clusters-output-file"
        "and --analysis-inconsistencies-output-file must be specified");
    report_fatal_error(
        "At least one of --analysis-clusters-output-file and "
        "--analysis-inconsistencies-output-file must be specified.");
  }

  InitializeNativeTarget();
  InitializeNativeTargetAsmPrinter();
  InitializeNativeTargetDisassembler();

  // Read benchmarks.
  const LLVMState State("");
  const std::vector<InstructionBenchmark> Points = ExitOnFileError(
      BenchmarkFile, InstructionBenchmark::readYamls(State, BenchmarkFile));

  const std::vector<InstructionBenchmark> Points =
      ExitOnErr(InstructionBenchmark::readYamls(State, BenchmarkFile));
  outs() << "Parsed " << Points.size() << " benchmark points\n";
  if (Points.empty()) {
    errs() << "no benchmarks to analyze\n";