From b40fec227033b9dc35604347bec52a524d62d00e Mon Sep 17 00:00:00 2001 From: Giacomo Vercesi Date: Mon, 2 Mar 2026 10:35:07 +0100 Subject: [PATCH] Add `LLMRename` analysis to pypeline --- include/revng/LLMRename/LLMRenameAnalysis.h | 24 ++++++ include/revng/Support/ProgramRunner.h | 2 +- lib/LLMRename/LLMRenameAnalysis.cpp | 85 ++++++++++++++------- lib/Pipebox/CMakeLists.txt | 1 + lib/Pipebox/Pipebox.cpp | 2 + python/revng/internal/pipeline.yml | 3 + 6 files changed, 88 insertions(+), 29 deletions(-) create mode 100644 include/revng/LLMRename/LLMRenameAnalysis.h diff --git a/include/revng/LLMRename/LLMRenameAnalysis.h b/include/revng/LLMRename/LLMRenameAnalysis.h new file mode 100644 index 000000000..db2c3674d --- /dev/null +++ b/include/revng/LLMRename/LLMRenameAnalysis.h @@ -0,0 +1,24 @@ +#pragma once + +// +// This file is distributed under the MIT License. See LICENSE.md for details. +// + +#include "revng/Pipebox/Containers.h" +#include "revng/PipeboxCommon/Model.h" + +namespace revng::pypeline::analyses { + +class LLMRename { +public: + static constexpr llvm::StringRef Name = "llm-rename"; + + llvm::Error run(Model &Model, + const Request &Incoming, + llvm::StringRef Configuration, + const PTMLCFunctionBytesContainer &Input); + + bool isAvailable() const; +}; + +} // namespace revng::pypeline::analyses diff --git a/include/revng/Support/ProgramRunner.h b/include/revng/Support/ProgramRunner.h index 31018bc91..33c06544c 100644 --- a/include/revng/Support/ProgramRunner.h +++ b/include/revng/Support/ProgramRunner.h @@ -38,7 +38,7 @@ public: struct RunOptions { /// If provided, will pipe the provided string to stdin - std::optional Stdin; + std::optional Stdin; /// Capture output options CaptureOption Capture = CaptureOption::None; }; diff --git a/lib/LLMRename/LLMRenameAnalysis.cpp b/lib/LLMRename/LLMRenameAnalysis.cpp index 054c0f32e..598a34204 100644 --- a/lib/LLMRename/LLMRenameAnalysis.cpp +++ b/lib/LLMRename/LLMRenameAnalysis.cpp @@ -5,6 +5,7 @@ #include "llvm/Support/Process.h" #include "revng/Backend/DecompilePipe.h" +#include "revng/LLMRename/LLMRenameAnalysis.h" #include "revng/Pipeline/RegisterAnalysis.h" #include "revng/Pipes/Kinds.h" #include "revng/Pipes/ModelGlobal.h" @@ -13,6 +14,38 @@ using revng::pipes::DecompileStringMap; +static llvm::Error doRename(model::Binary &Model, llvm::StringRef Contents) { + using ModelT = model::Binary; + ProgramRunner::RunOptions Options{ + .Stdin = Contents, + .Capture = ProgramRunner::CaptureOption::StdoutAndStderrSeparately + }; + ProgramRunner::Result Result = ::Runner.run("revng", + { "llm-rename" }, + Options); + if (Result.ExitCode == 2) { + // Exit code 2 is treated specially to propagate stderr as the error + // message + return revng::createError(Result.Stderr); + } else if (Result.ExitCode != 0) { + return revng::createError("Failed to run llm-rename, process " + "returned with exit code: " + + std::to_string(Result.ExitCode)); + } + + auto MaybeChanges = fromString>(Result.Stdout); + if (not MaybeChanges) + return MaybeChanges.takeError(); + + for (const Change &Change : MaybeChanges->Changes) { + bool SetResult = setByPath(Change.Path, Model, *Change.New); + if (not SetResult) + return revng::createError("Could not apply change"); + } + + return llvm::Error::success(); +} + struct LLMRename { static constexpr auto Name = "llm-rename"; constexpr static std::tuple Options = {}; @@ -28,35 +61,10 @@ struct LLMRename { llvm::Error run(pipeline::ExecutionContext &EC, const DecompileStringMap &Container) { - using ModelT = model::Binary; - TupleTree &Model = revng::getWritableModelFromContext(EC); + TupleTree &Model = revng::getWritableModelFromContext(EC); for (auto &&[_, Contents] : Container) { - ProgramRunner::RunOptions Options{ - .Stdin = Contents, - .Capture = ProgramRunner::CaptureOption::StdoutAndStderrSeparately - }; - ProgramRunner::Result Result = ::Runner.run("revng", - { "llm-rename" }, - Options); - if (Result.ExitCode == 2) { - // Exit code 2 is treated specially to propagate stderr as the error - // message - return revng::createError(Result.Stderr); - } else if (Result.ExitCode != 0) { - return revng::createError("Failed to run llm-rename, process " - "returned with exit code: " - + std::to_string(Result.ExitCode)); - } - - auto MaybeChanges = fromString>(Result.Stdout); - if (not MaybeChanges) - return MaybeChanges.takeError(); - - for (const Change &Change : MaybeChanges->Changes) { - bool SetResult = setByPath(Change.Path, *Model, *Change.New); - if (not SetResult) - return revng::createError("Could not apply change"); - } + if (auto Error = doRename(*Model, Contents)) + return Error; } return llvm::Error::success(); @@ -64,3 +72,24 @@ struct LLMRename { }; pipeline::RegisterAnalysis LLMRenameAnalysis; + +namespace revng::pypeline::analyses { + +llvm::Error LLMRename::run(Model &Model, + const Request &Incoming, + llvm::StringRef Configuration, + const PTMLCFunctionBytesContainer &Input) { + model::Binary &Binary = *Model.get().get(); + for (const ObjectID *Object : Incoming[0]) { + auto Buffer = Input.getMemoryBuffer(*Object); + if (auto Error = doRename(Binary, Buffer->getBuffer())) + return Error; + } + return llvm::Error::success(); +} + +bool LLMRename::isAvailable() const { + return ::LLMRename::isAvailable(); +} + +} // namespace revng::pypeline::analyses diff --git a/lib/Pipebox/CMakeLists.txt b/lib/Pipebox/CMakeLists.txt index dac7b4794..67cd2ebc8 100644 --- a/lib/Pipebox/CMakeLists.txt +++ b/lib/Pipebox/CMakeLists.txt @@ -17,6 +17,7 @@ target_link_libraries( revngDataLayoutAnalysis revngFunctionIsolation revngImportFromCAnalysis + revngLLMRenameAnalysis revngLift revngModelImporter revngModelToHeader diff --git a/lib/Pipebox/Pipebox.cpp b/lib/Pipebox/Pipebox.cpp index 4f68883d7..88c999c17 100644 --- a/lib/Pipebox/Pipebox.cpp +++ b/lib/Pipebox/Pipebox.cpp @@ -22,6 +22,7 @@ #include "revng/HeadersGeneration/ModelToHeaderPipe.h" #include "revng/HeadersGeneration/ModelTypeDefinitionPipe.h" #include "revng/ImportFromC/ImportFromCAnalysis.h" +#include "revng/LLMRename/LLMRenameAnalysis.h" #include "revng/Lift/Lift.h" #include "revng/Lift/LinkSupportPipe.h" #include "revng/Model/Importer/Binary/ImportBinaryAnalysis.h" @@ -143,3 +144,4 @@ static RegisterAnalysis A9; static RegisterAnalysis A10; static RegisterAnalysis A11; static RegisterAnalysis A12; +static RegisterAnalysis A13; diff --git a/python/revng/internal/pipeline.yml b/python/revng/internal/pipeline.yml index 15c7f097f..74687abf0 100644 --- a/python/revng/internal/pipeline.yml +++ b/python/revng/internal/pipeline.yml @@ -401,6 +401,9 @@ branches: container: decompile-c category: user filename: decompiled.c + analyses: + - analysis: llm-rename + containers: [decompile-c] - pipe: decompile-to-single-file arguments: [decompile-c, decompiled-single-file]