Commit 742fa941 authored by Pavel Kosov's avatar Pavel Kosov
Browse files

[llvm-exegesis] Skip codegen of known-invalid snippets

On some targets, not all types of instruction operands are currently
handled. Instead of stopping the whole llvm-exegesis run because of any
instruction opcode that is not fully supported, write a per-opcode error
message and proceed to other opcodes. This improves the reliability of
--opcode-index=-1 sweep on partially supported targets.

Depends on: D146302, D146303

~~

Huawei RRI, OS Lab

Reviewed By: courbet

Differential Revision: https://reviews.llvm.org/D146304
parent ce0d16f5
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
# Test that we can just use --opcode-index=-1 to generate snippets for
# all supported opcodes and gracefully handle unsupported ones.

# RUN: llvm-exegesis --mtriple=aarch64-linux-gnu --mcpu=cortex-a55 --benchmark-phase=prepare-and-assemble-snippet \
# RUN:               --mode=latency --opcode-index=-1 | FileCheck %s
# RUN: llvm-exegesis --mtriple=aarch64-linux-gnu --mcpu=cortex-a55 --benchmark-phase=prepare-and-assemble-snippet \
# RUN:               --mode=uops --opcode-index=-1 | FileCheck %s

# 100 means "quite a lot"
# CHECK-COUNT-100: assembled_snippet: {{.*}}
+23 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Program.h"
@@ -77,9 +78,12 @@ Error SnippetGenerator::generateConfigurations(
        BC.Info = CT.Info;
        BC.Key.Instructions.reserve(CT.Instructions.size());
        for (InstructionTemplate &IT : CT.Instructions) {
          if (auto error = randomizeUnsetVariables(State, ForbiddenRegs, IT))
            return error;
          BC.Key.Instructions.push_back(IT.build());
          if (auto Error = randomizeUnsetVariables(State, ForbiddenRegs, IT))
            return Error;
          MCInst Inst = IT.build();
          if (auto Error = validateGeneratedInstruction(State, Inst))
            return Error;
          BC.Key.Instructions.push_back(Inst);
        }
        if (CT.ScratchSpacePointerInReg)
          BC.LiveIns.push_back(CT.ScratchSpacePointerInReg);
@@ -282,5 +286,21 @@ Error randomizeUnsetVariables(const LLVMState &State,
  return Error::success();
}

Error validateGeneratedInstruction(const LLVMState &State, const MCInst &Inst) {
  for (const auto &Operand : Inst) {
    if (!Operand.isValid()) {
      // Mention the particular opcode - it is not necessarily the "main"
      // opcode being benchmarked by this snippet. For example, serial snippet
      // generator uses one more opcode when in SERIAL_VIA_NON_MEMORY_INSTR
      // execution mode.
      const auto OpcodeName = State.getInstrInfo().getName(Inst.getOpcode());
      return make_error<Failure>("Not all operands were initialized by the "
                                 "snippet generator for " +
                                 OpcodeName + " opcode.");
    }
  }
  return Error::success();
}

} // namespace exegesis
} // namespace llvm
+3 −0
Original line number Diff line number Diff line
@@ -107,6 +107,9 @@ Error randomizeUnsetVariables(const LLVMState &State,
                              const BitVector &ForbiddenRegs,
                              InstructionTemplate &IT);

// Sanity check generated instruction.
Error validateGeneratedInstruction(const LLVMState &State, const MCInst &Inst);

} // namespace exegesis
} // namespace llvm