From e9ab8432f8bc7ae3472ac0a8598b62744648aac2 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 3 Apr 2026 02:01:06 +0300 Subject: [PATCH 1/2] [snippy] Support dump-initial-registers-yaml without model plugin --- .../dump-initial-registers-no-model.yaml | 20 ++++++++++++++++ .../include/snippy/Generator/SnippyModule.h | 4 ++++ llvm/tools/llvm-snippy/lib/FlowGenerator.cpp | 23 +++++++++++++++++++ .../lib/Generator/SnippyModule.cpp | 8 +++++++ 4 files changed, 55 insertions(+) create mode 100644 llvm/test/tools/llvm-snippy/dump-initial-registers-no-model.yaml diff --git a/llvm/test/tools/llvm-snippy/dump-initial-registers-no-model.yaml b/llvm/test/tools/llvm-snippy/dump-initial-registers-no-model.yaml new file mode 100644 index 000000000000..97db6d240c6b --- /dev/null +++ b/llvm/test/tools/llvm-snippy/dump-initial-registers-no-model.yaml @@ -0,0 +1,20 @@ +# RUN: rm -f %t.initial-regs.yaml +# RUN: llvm-snippy %s -mtriple=riscv64-unknown-elf -num-instrs=10 \ +# RUN: --init-regs-in-elf \ +# RUN: --dump-initial-registers-yaml=%t.initial-regs.yaml +# RUN: test -s %t.initial-regs.yaml + +sections: + - name: text + VMA: 0x1000 + LMA: 0x1000 + SIZE: 0x1000 + ACCESS: rx + - name: data + VMA: 0x3000 + LMA: 0x3000 + SIZE: 0x1000 + ACCESS: rw + +histogram: + - [ADD, 1] \ No newline at end of file diff --git a/llvm/tools/llvm-snippy/include/snippy/Generator/SnippyModule.h b/llvm/tools/llvm-snippy/include/snippy/Generator/SnippyModule.h index f5d5f5cac7e3..b4d77473c62d 100644 --- a/llvm/tools/llvm-snippy/include/snippy/Generator/SnippyModule.h +++ b/llvm/tools/llvm-snippy/include/snippy/Generator/SnippyModule.h @@ -318,6 +318,8 @@ class SnippyProgramContext final { const IRegisterState & getInitialRegisterState(const TargetSubtargetInfo &ST) const; + const IRegisterState &getInitialRegisterState() const; + bool hasProgramStateSaveSpace() const { return PGSK.get(); } const auto &getProgramStateSaveSpace() const { return *PGSK; } auto &getProgramStateSaveSpace() { return *PGSK; } @@ -364,6 +366,8 @@ class SnippyProgramContext final { std::unique_ptr MemManager; std::unique_ptr SMCManager; + const TargetSubtargetInfo *InitialStateSubtarget = nullptr; + constexpr static auto SmallStringDefaultSize = 16; std::optional ROMSection; diff --git a/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp b/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp index 1eb0be2fd0d7..0cea8adb8a60 100644 --- a/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp +++ b/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp @@ -185,6 +185,27 @@ static auto createSMCInitRoutine(GeneratorContext &Ctx) { return ExtModule; } +void dumpInitialRegistersIfRequested(SnippyProgramContext &ProgContext, + LLVMContext &Ctx, + const PassConfig &PassCfg) { + auto &YamlPath = PassCfg.RegistersConfig.InitialStateOutputYaml; + if (YamlPath.empty()) + return; + + if (PassCfg.ModelPluginConfig.runOnModel()) + return; + + auto &Regs = ProgContext.getInitialRegisterState(); + + std::error_code EC; + raw_fd_ostream File(YamlPath, EC); + if (EC) + snippy::fatal(Ctx, "Failed to dump initial registers", + "cannot open file \"" + YamlPath + "\": " + EC.message()); + + Regs.saveAsYAMLFile(File); +} + } // namespace [[maybe_unused]] static void dumpSelfcheck(const std::vector &Data, @@ -425,6 +446,8 @@ GeneratorResult FlowGenerator::generate(LLVMState &State, if (ProgramCfg.MemoryCfg.SkipRuntimeMemInit) Modules = {&MainModule}; + dumpInitialRegistersIfRequested(ProgContext, State.getCtx(), PassCfg); + dumpVerificationIntervalsIfNeeeded(MainModule, GenCtx, BaseFileName); if (PassCfg.ModelPluginConfig.runOnModel()) { diff --git a/llvm/tools/llvm-snippy/lib/Generator/SnippyModule.cpp b/llvm/tools/llvm-snippy/lib/Generator/SnippyModule.cpp index 06ee8d9e337d..25a9178562d6 100644 --- a/llvm/tools/llvm-snippy/lib/Generator/SnippyModule.cpp +++ b/llvm/tools/llvm-snippy/lib/Generator/SnippyModule.cpp @@ -285,6 +285,13 @@ const IRegisterState &SnippyProgramContext::getInitialRegisterState( return *InitialMachineState; } +const IRegisterState &SnippyProgramContext::getInitialRegisterState() const { + assert(InitialStateSubtarget && + "Initial register state requested before target context " + "initialization"); + return getInitialRegisterState(*InitialStateSubtarget); +} + SnippyProgramContext::SnippyProgramContext(LLVMState &State, RegisterGenerator &RegGen, std::vector Pools, @@ -318,6 +325,7 @@ void SnippyProgramContext::createTargetContext(const Config &Cfg, const TargetSubtargetInfo &STI, const RegPoolWrapper &RP) { assert(!TargetContext && "Double context insertion"); + InitialStateSubtarget = &STI; TargetContext = State->getSnippyTarget().createTargetContext(*State, Cfg, &STI, RP); } From 20fc6cf7900a1ce0eab830835b69f91f82315f8d Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 20 Jun 2026 21:04:57 +0300 Subject: [PATCH 2/2] [snippy] Dump initial registers without model plugin --- .../dump-initial-registers-no-model.yaml | 18 +++---------- .../include/snippy/Generator/SnippyModule.h | 4 +++ llvm/tools/llvm-snippy/lib/FlowGenerator.cpp | 26 +++---------------- .../Generator/SimulatorContextWrapperPass.cpp | 2 +- .../lib/Generator/SnippyModule.cpp | 25 ++++++++++++++++++ 5 files changed, 37 insertions(+), 38 deletions(-) diff --git a/llvm/test/tools/llvm-snippy/dump-initial-registers-no-model.yaml b/llvm/test/tools/llvm-snippy/dump-initial-registers-no-model.yaml index 97db6d240c6b..5e33e31ceabc 100644 --- a/llvm/test/tools/llvm-snippy/dump-initial-registers-no-model.yaml +++ b/llvm/test/tools/llvm-snippy/dump-initial-registers-no-model.yaml @@ -1,20 +1,10 @@ -# RUN: rm -f %t.initial-regs.yaml -# RUN: llvm-snippy %s -mtriple=riscv64-unknown-elf -num-instrs=10 \ +# 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: test -s %t.initial-regs.yaml -sections: - - name: text - VMA: 0x1000 - LMA: 0x1000 - SIZE: 0x1000 - ACCESS: rx - - name: data - VMA: 0x3000 - LMA: 0x3000 - SIZE: 0x1000 - ACCESS: rw +include: + - "Inputs/sections.yaml" histogram: - - [ADD, 1] \ No newline at end of file + - [ADD, 1] diff --git a/llvm/tools/llvm-snippy/include/snippy/Generator/SnippyModule.h b/llvm/tools/llvm-snippy/include/snippy/Generator/SnippyModule.h index b4d77473c62d..860c787170af 100644 --- a/llvm/tools/llvm-snippy/include/snippy/Generator/SnippyModule.h +++ b/llvm/tools/llvm-snippy/include/snippy/Generator/SnippyModule.h @@ -318,6 +318,10 @@ class SnippyProgramContext final { const IRegisterState & getInitialRegisterState(const TargetSubtargetInfo &ST) const; + void dumpInitialRegisterState(StringRef YamlPath) const; + void dumpInitialRegisterState(StringRef YamlPath, + const TargetSubtargetInfo &ST) const; + const IRegisterState &getInitialRegisterState() const; bool hasProgramStateSaveSpace() const { return PGSK.get(); } diff --git a/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp b/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp index 0cea8adb8a60..f2821e13c62b 100644 --- a/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp +++ b/llvm/tools/llvm-snippy/lib/FlowGenerator.cpp @@ -185,27 +185,6 @@ static auto createSMCInitRoutine(GeneratorContext &Ctx) { return ExtModule; } -void dumpInitialRegistersIfRequested(SnippyProgramContext &ProgContext, - LLVMContext &Ctx, - const PassConfig &PassCfg) { - auto &YamlPath = PassCfg.RegistersConfig.InitialStateOutputYaml; - if (YamlPath.empty()) - return; - - if (PassCfg.ModelPluginConfig.runOnModel()) - return; - - auto &Regs = ProgContext.getInitialRegisterState(); - - std::error_code EC; - raw_fd_ostream File(YamlPath, EC); - if (EC) - snippy::fatal(Ctx, "Failed to dump initial registers", - "cannot open file \"" + YamlPath + "\": " + EC.message()); - - Regs.saveAsYAMLFile(File); -} - } // namespace [[maybe_unused]] static void dumpSelfcheck(const std::vector &Data, @@ -446,8 +425,6 @@ GeneratorResult FlowGenerator::generate(LLVMState &State, if (ProgramCfg.MemoryCfg.SkipRuntimeMemInit) Modules = {&MainModule}; - dumpInitialRegistersIfRequested(ProgContext, State.getCtx(), PassCfg); - dumpVerificationIntervalsIfNeeeded(MainModule, GenCtx, BaseFileName); if (PassCfg.ModelPluginConfig.runOnModel()) { @@ -527,6 +504,9 @@ GeneratorResult FlowGenerator::generate(LLVMState &State, } else { + ProgContext.dumpInitialRegisterState( + PassCfg.RegistersConfig.InitialStateOutputYaml); + 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/SimulatorContextWrapperPass.cpp b/llvm/tools/llvm-snippy/lib/Generator/SimulatorContextWrapperPass.cpp index 83f34a54f000..0108c11272d7 100644 --- a/llvm/tools/llvm-snippy/lib/Generator/SimulatorContextWrapperPass.cpp +++ b/llvm/tools/llvm-snippy/lib/Generator/SimulatorContextWrapperPass.cpp @@ -227,7 +227,7 @@ Error SimulatorContext::runSimulator(const RunInfo &RI) { // StartPC location may be updated since last time it was configured. I.setPC(ElfData->ProgStart); - I.dumpCurrentRegState(InitialStateOutputYaml); + ProgCtx.dumpInitialRegisterState(InitialStateOutputYaml, I.getSubTarget()); if (ElfData->ProgEnd == std::nullopt) return createStringError( diff --git a/llvm/tools/llvm-snippy/lib/Generator/SnippyModule.cpp b/llvm/tools/llvm-snippy/lib/Generator/SnippyModule.cpp index 25a9178562d6..5e201651f180 100644 --- a/llvm/tools/llvm-snippy/lib/Generator/SnippyModule.cpp +++ b/llvm/tools/llvm-snippy/lib/Generator/SnippyModule.cpp @@ -285,6 +285,31 @@ const IRegisterState &SnippyProgramContext::getInitialRegisterState( return *InitialMachineState; } +void SnippyProgramContext::dumpInitialRegisterState( + StringRef YamlPath, const TargetSubtargetInfo &ST) const { + if (YamlPath.empty()) + return; + + std::error_code EC; + raw_fd_ostream File(YamlPath, EC); + if (EC) + snippy::fatal(State->getCtx(), "Failed to dump initial registers", + "cannot open file \"" + Twine(YamlPath) + + "\": " + EC.message()); + + getInitialRegisterState(ST).saveAsYAMLFile(File); +} + +void SnippyProgramContext::dumpInitialRegisterState(StringRef YamlPath) const { + if (YamlPath.empty()) + return; + + assert( + InitialStateSubtarget && + "Initial register state requested before target context initialization"); + dumpInitialRegisterState(YamlPath, *InitialStateSubtarget); +} + const IRegisterState &SnippyProgramContext::getInitialRegisterState() const { assert(InitialStateSubtarget && "Initial register state requested before target context "