Add LLMRename analysis to pypeline

This commit is contained in:
Giacomo Vercesi
2026-03-02 10:35:07 +01:00
committed by Alessandro Di Federico
parent 63a11d0c63
commit b40fec2270
6 changed files with 88 additions and 29 deletions
@@ -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
+1 -1
View File
@@ -38,7 +38,7 @@ public:
struct RunOptions {
/// If provided, will pipe the provided string to stdin
std::optional<std::string> Stdin;
std::optional<llvm::StringRef> Stdin;
/// Capture output options
CaptureOption Capture = CaptureOption::None;
};
+57 -28
View File
@@ -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<TupleTreeDiff<ModelT>>(Result.Stdout);
if (not MaybeChanges)
return MaybeChanges.takeError();
for (const Change<ModelT> &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<ModelT> &Model = revng::getWritableModelFromContext(EC);
TupleTree<model::Binary> &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<TupleTreeDiff<ModelT>>(Result.Stdout);
if (not MaybeChanges)
return MaybeChanges.takeError();
for (const Change<ModelT> &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<LLMRename> 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
+1
View File
@@ -17,6 +17,7 @@ target_link_libraries(
revngDataLayoutAnalysis
revngFunctionIsolation
revngImportFromCAnalysis
revngLLMRenameAnalysis
revngLift
revngModelImporter
revngModelToHeader
+2
View File
@@ -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<AnalyzeDataLayout> A9;
static RegisterAnalysis<ConvertFunctionsToCABI> A10;
static RegisterAnalysis<ConvertFunctionsToRaw> A11;
static RegisterAnalysis<ImportFromC> A12;
static RegisterAnalysis<LLMRename> A13;
+3
View File
@@ -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]