Add recompile-isolated to pypeline

This commit is contained in:
Giacomo Vercesi
2025-11-04 10:19:11 +01:00
parent 8f5e7feb4f
commit ca3c5113d9
5 changed files with 109 additions and 7 deletions
@@ -0,0 +1,30 @@
#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include "revng/PipeboxCommon/LLVMContainer.h"
namespace revng::pypeline::piperuns {
class InvokeIsolatedFunctions {
public:
static constexpr llvm::StringRef Name = "InvokeIsolatedFunctions";
using Arguments = TypeList<
PipeArgument<"RootModule", "Root module containing the root function">,
PipeArgument<"FunctionModules",
"LLVM Modules containing isolated functions">,
PipeArgument<"Output",
"Output LLVM Module with root, functions and dispatcher",
Access::Write>>;
static void run(const class Model &Model,
llvm::StringRef Config,
llvm::StringRef DynamicConfig,
const LLVMRootContainer &Root,
const LLVMFunctionContainer &Functions,
LLVMRootContainer &Output);
};
} // namespace revng::pypeline::piperuns
@@ -71,6 +71,13 @@ public:
public:
const llvm::Module &getModule() const { return *Module; }
llvm::Module &getModule() { return *Module; }
void assign(std::unique_ptr<llvm::Module> &&NewModule) {
if (&Context == &NewModule->getContext())
Module = std::move(NewModule);
else
Module = cloneIntoContext(*NewModule, Context);
}
};
class LLVMFunctionContainer {
@@ -116,6 +123,9 @@ public:
}
public:
llvm::LLVMContext &getContext() { return Context; }
const llvm::LLVMContext &getContext() const { return Context; }
const llvm::Module &getModule(const ObjectID &ID) const {
return *Modules.at(ID);
}
@@ -14,6 +14,7 @@
#include "revng/ABI/FunctionType/Layout.h"
#include "revng/BasicAnalyses/GeneratedCodeBasicInfo.h"
#include "revng/EarlyFunctionAnalysis/ControlFlowGraphCache.h"
#include "revng/FunctionIsolation/InvokeIsolatedFunctions.h"
#include "revng/Model/IRHelpers.h"
#include "revng/Model/NameBuilder.h"
#include "revng/Pipeline/AllRegistries.h"
@@ -28,15 +29,14 @@ using namespace llvm;
class InvokeIsolatedFunctionsImpl {
private:
using FunctionInfo = tuple<const model::Function *,
BasicBlock *,
const Function *>;
using FunctionInfo = tuple<const model::Function *, BasicBlock *, Function *>;
using FunctionMap = std::map<model::Function::Key, FunctionInfo>;
private:
const model::Binary &Binary;
Function &RootFunction;
Module &RootModule;
const Module *FunctionModule;
LLVMContext &Context;
GeneratedCodeBasicInfo GCBI;
FunctionMap Map;
@@ -44,10 +44,11 @@ private:
public:
InvokeIsolatedFunctionsImpl(const model::Binary &Binary,
llvm::Module &RootModule,
const llvm::Module &FunctionModule) :
const llvm::Module *FunctionModule) :
Binary(Binary),
RootFunction(*RootModule.getFunction("root")),
RootModule(RootModule),
FunctionModule(FunctionModule),
Context(RootModule.getContext()),
GCBI(Binary) {
@@ -55,7 +56,7 @@ public:
model::CNameBuilder NameBuilder = Binary;
for (const model::Function &Function : Binary.Functions()) {
auto *F = FunctionModule.getFunction(NameBuilder.llvmName(Function));
auto *F = FunctionModule->getFunction(NameBuilder.llvmName(Function));
revng_assert(F != nullptr);
Map[Function.key()] = { &Function, nullptr, F };
}
@@ -172,11 +173,15 @@ public:
}
}
llvm::Function *
llvm::Function *NewDeclaration = nullptr;
if (&RootModule != FunctionModule) {
NewDeclaration = llvm::Function::Create(F->getFunctionType(),
llvm::Function::ExternalLinkage,
F->getName(),
RootModule);
} else {
NewDeclaration = F;
}
// Emit the invoke instruction, propagating debug info
auto *NewInvoke = Builder.CreateInvoke(NewDeclaration,
@@ -274,7 +279,7 @@ public:
FunctionContainer.getModule());
InvokeIsolatedFunctionsImpl Impl(*revng::getModelFromContext(EC),
OutputRootContainer.getModule(),
FunctionContainer.getModule());
&FunctionContainer.getModule());
Impl.run();
const llvm::Module &FunctionModule = FunctionContainer.getModule();
@@ -287,3 +292,35 @@ public:
};
static pipeline::RegisterPipe<InvokeIsolatedPipe> Y;
namespace revng::pypeline::piperuns {
void InvokeIsolatedFunctions::run(const class Model &Model,
llvm::StringRef Config,
llvm::StringRef DynamicConfig,
const LLVMRootContainer &Root,
const LLVMFunctionContainer &Functions,
LLVMRootContainer &Output) {
const model::Binary &Binary = *Model.get().get();
// Clone the container
llvm::LLVMContext &OutputContext = Output.getModule().getContext();
std::unique_ptr<llvm::Module>
OutputModule = cloneIntoContext(Root.getModule(), OutputContext);
// Merge all the functions into a single Module
llvm::Linker Linker(*OutputModule);
for (auto &Object : Functions.objects()) {
const llvm::Module &Module = Functions.getModule(Object);
Linker.linkInModule(cloneIntoContext(Module, OutputContext),
llvm::Linker::OverrideFromSrc);
}
populateFunctionDispatcher(Binary, *OutputModule);
InvokeIsolatedFunctionsImpl Impl(Binary, *OutputModule, OutputModule.get());
Impl.run();
Output.assign(std::move(OutputModule));
}
} // namespace revng::pypeline::piperuns
+2
View File
@@ -5,6 +5,7 @@
#include "revng/EarlyFunctionAnalysis/AttachDebugInfo.h"
#include "revng/EarlyFunctionAnalysis/CollectCFG.h"
#include "revng/FunctionIsolation/EnforceABI.h"
#include "revng/FunctionIsolation/InvokeIsolatedFunctions.h"
#include "revng/FunctionIsolation/IsolateFunctions.h"
#include "revng/FunctionIsolation/PromoteCSVs.h"
#include "revng/HeadersGeneration/ModelToHeaderPipe.h"
@@ -63,3 +64,4 @@ static RegisterFunctionPipe<YieldAssembly> P13;
static RegisterSingleOutputPipe<LinkSupport> P14;
static RegisterSingleOutputPipe<CompileRootModule> P15;
static RegisterSingleOutputPipe<LinkForTranslation> P16;
static RegisterSingleOutputPipe<InvokeIsolatedFunctions> P17;
+23
View File
@@ -25,6 +25,8 @@ containers:
type: ObjectFileContainer
- name: translated
type: TranslatedContainer
- name: llvm-root-with-functions
type: LLVMRootContainer
branches:
files-imported:
@@ -178,3 +180,24 @@ branches:
artifacts:
- name: recompile
container: translated
recompile-isolated:
from: isolate
tasks:
- pipe: InvokeIsolatedFunctions
arguments: [llvm-root, llvm-functions, llvm-root-with-functions]
- pipe: LinkSupport
arguments: [llvm-root-with-functions]
- pipe: PureLLVMPassesRootPipe
arguments: [llvm-root-with-functions]
configuration:
Passes: [drop-opaque-return-address]
- pipe: CompileRootModule
arguments: [llvm-root-with-functions, object-file]
- pipe: LinkForTranslation
arguments: [binaries-container, object-file, translated]
- savepoint: recompile-isolated
containers: [translated]
artifacts:
- name: recompile-isolated
container: translated