diff --git a/llvm/test/tools/llvm-snippy/dumps/dump-registers/dump-initial-registers-no-model.yaml b/llvm/test/tools/llvm-snippy/dumps/dump-registers/dump-initial-registers-no-model.yaml new file mode 100644 index 000000000000..9055d1e6bd82 --- /dev/null +++ b/llvm/test/tools/llvm-snippy/dumps/dump-registers/dump-initial-registers-no-model.yaml @@ -0,0 +1,25 @@ +# REQUIRES: skip-snippy-model-mixin +# RUN: llvm-snippy %s -mtriple=riscv64 --model-plugin=None -num-instrs=10 \ +# RUN: --init-regs-in-elf \ +# RUN: --dump-initial-registers-yaml=%t.initial-regs.yaml +# RUN: FileCheck %s --input-file=%t.initial-regs.yaml + +# RUN: llvm-snippy %s -mtriple=riscv64 --model-plugin=None -num-instrs=10 \ +# RUN: --initial-regs-yaml=%t.initial-regs.yaml \ +# RUN: --dump-initial-registers-yaml=%t.reloaded-regs.yaml +# RUN: diff %t.initial-regs.yaml %t.reloaded-regs.yaml + +# RUN: not llvm-snippy %s -mtriple=riscv64 --model-plugin=None -num-instrs=10 \ +# RUN: --dump-initial-registers-yaml=%t.initial-regs.yaml/invalid 2>&1 \ +# RUN: | FileCheck %s --check-prefix=ERROR + +# CHECK: registers: +# CHECK-NEXT: - [ X0, 0x0000000000000000 ] +# CHECK: - [ X31, 0x{{([[:xdigit:]]{16})}} ] +# ERROR: error: Register dump error: + +include: + - "../../Inputs/sections.yaml" + +histogram: + - [ADD, 1] diff --git a/llvm/tools/llvm-snippy/include/snippy/Simulator/Simulator.h b/llvm/tools/llvm-snippy/include/snippy/Simulator/Simulator.h index e2e5d873e1b7..2746c6f42dee 100644 --- a/llvm/tools/llvm-snippy/include/snippy/Simulator/Simulator.h +++ b/llvm/tools/llvm-snippy/include/snippy/Simulator/Simulator.h @@ -38,6 +38,7 @@ struct IRegisterState { virtual void loadFromYamlFile(StringRef, WarningsT &, const SnippyTarget *Tgt = nullptr) = 0; virtual void saveAsYAMLFile(raw_ostream &) const = 0; + void saveAsYAMLFile(StringRef YamlPath) const; virtual bool operator==(const IRegisterState &) const = 0; bool operator!=(const IRegisterState &Another) const { diff --git a/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp b/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp index eea39dfb89a5..c38152e3f1a1 100644 --- a/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp +++ b/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp @@ -525,6 +525,16 @@ GeneratorResult FlowGenerator::generate(LLVMState &State, } else { + if (auto &YamlPath = PassCfg.RegistersConfig.InitialStateOutputYaml; + !YamlPath.empty()) { + auto *EntryFunc = + MainModule.getModule().getFunction(ProgramCfg.EntryPointName); + assert(EntryFunc); + auto &ST = State.getSubtargetImpl(*EntryFunc); + auto &RegState = ProgContext.getInitialRegisterState(ST); + RegState.saveAsYAMLFile(YamlPath); + } + snippy::warn(WarningName::NoModelExec, State.getCtx(), "Skipping snippet execution on the model", "model was set to 'None'."); diff --git a/llvm/tools/llvm-snippy/lib/Generator/Interpreter.cpp b/llvm/tools/llvm-snippy/lib/Generator/Interpreter.cpp index a48a3c820243..2c39d8c82d8c 100644 --- a/llvm/tools/llvm-snippy/lib/Generator/Interpreter.cpp +++ b/llvm/tools/llvm-snippy/lib/Generator/Interpreter.cpp @@ -331,15 +331,7 @@ void Interpreter::dumpRegsAsYAML(const IRegisterState &Regs, raw_ostream &OS) { } void Interpreter::dumpRegs(const IRegisterState &Regs, StringRef YamlPath) { - if (YamlPath.empty()) - return; - - std::error_code EC; - raw_fd_ostream File(YamlPath, EC); - if (EC) - snippy::fatal(formatv("Register dump error: {0}", EC.message())); - - dumpRegsAsYAML(Regs, File); + Regs.saveAsYAMLFile(YamlPath); } void Interpreter::dumpOneRange(NamedMemoryRange Range, diff --git a/llvm/tools/llvm-snippy/lib/Simulator/Simulator.cpp b/llvm/tools/llvm-snippy/lib/Simulator/Simulator.cpp index 1436d5f8920e..a001e0a0b262 100644 --- a/llvm/tools/llvm-snippy/lib/Simulator/Simulator.cpp +++ b/llvm/tools/llvm-snippy/lib/Simulator/Simulator.cpp @@ -8,10 +8,25 @@ #include "snippy/Simulator/Simulator.h" +#include "snippy/Support/Error.h" + +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/YAMLTraits.h" namespace llvm { +void snippy::IRegisterState::saveAsYAMLFile(StringRef YamlPath) const { + if (YamlPath.empty()) + return; + + std::error_code EC; + raw_fd_ostream File(YamlPath, EC); + if (EC) + snippy::fatal(formatv("Register dump error: {0}", EC.message())); + + saveAsYAMLFile(File); +} + namespace { struct RegionKey {