Files
revng-revng/lib/CliftPipes/Clifter.cpp
Lauri Vasama 90e5dfd4c9 Pass MLIRContext by address
Passing by address is more conventional. This is what MLIR does most of
the time, and it avoids dereferences and addressofs everywhere.
2026-04-30 15:09:16 +03:00

89 lines
3.0 KiB
C++

//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include "revng/CliftPipes/CliftContainer.h"
#include "revng/CliftPipes/Clifter.h"
#include "revng/Clifter/Clifter.h"
#include "revng/Model/IRHelpers.h"
#include "revng/Model/NameBuilder.h"
#include "revng/Pipeline/RegisterPipe.h"
#include "revng/Pipes/IRHelpers.h"
namespace {
class ClifterPipe {
public:
static constexpr auto Name = "clifter";
std::array<pipeline::ContractGroup, 1> getContract() const {
using namespace pipeline;
using namespace revng::kinds;
return { ContractGroup({ Contract(StackAccessesSegregated,
0,
CliftFunction,
1,
InputPreservation::Preserve) }) };
}
void run(pipeline::ExecutionContext &EC,
const pipeline::LLVMContainer &LLVMContainer,
revng::pipes::CliftFunctionContainer &CliftContainer) {
CliftContainer.getContext()->loadDialect<clift::CliftDialect>();
auto const &Model = *revng::getModelFromContext(EC);
model::CNameBuilder NameBuilder(Model);
const llvm::Module &M = LLVMContainer.getModule();
auto TargetToFunction = getTargetToFunctionMapping(M);
// The importer construction itself only relies on minimal number of model
// properties (e.g. architecture) to avoid creating dependencies for all
// imported functions. The importer does some caching, but care is taken to
// make sure that the pertinent model properties are queried within each
// function import process regardless of caching.
auto Importer = clift::Clifter::make(CliftContainer.getModule(), Model);
for (const model::Function &Function :
revng::getFunctionsAndCommit(EC, CliftContainer.name())) {
auto It = TargetToFunction.find(Function.Entry());
revng_assert(It != TargetToFunction.end());
Importer->import(It->second);
}
}
};
static pipeline::RegisterPipe<ClifterPipe> X;
} // namespace
namespace revng::pypeline::piperuns {
Clifter::Clifter(const class Model &Model,
llvm::StringRef Config,
llvm::StringRef DynamicConfig,
const LLVMFunctionContainer &Input,
CliftFunctionContainer &Output) :
Binary(*Model.get().get()), Input(Input), Output(Output) {
Output.getContext()->loadDialect<clift::CliftDialect>();
}
void Clifter::runOnFunction(const model::Function &Function) {
ObjectID Object(Function.Entry());
const llvm::Module &Module = Input.getModule(Object);
const llvm::Function
&LLVMFunction = getUniqueIsolatedFunction(Module, Function.Entry());
mlir::MLIRContext *Context = Output.getContext();
auto ModuleOpObject = mlir::ModuleOp::create(mlir::UnknownLoc::get(Context));
clift::setModuleAttr(ModuleOpObject);
auto Importer = clift::Clifter::make(ModuleOpObject, Binary);
Importer->import(&LLVMFunction);
Output.assign(Object, ModuleOpObject);
}
} // namespace revng::pypeline::piperuns