mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
Add recompile-isolated to pypeline
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user