mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
7db2c64f61
Remove the logic for detecting Instructions with duplicated uses introduced by control-flow restructuring (the use is duplicated, but the instruction is not). By dropping this detection, we'll end up not marking for serialization some Instructions. Hence, when emitting C code, such Instructions will just be emitted as inline expressions, without declaring a dedicated local variable to hold their value. This is somehow suboptimal w.r.t the fact that the expression will be emitted many times, one for each duplicated use. However, this is not semantically incorrect, just verbose. On the other hand, the logic for detecting Instructions with duplicated uses has always been subtly broken, because it only looked at the number of duplicates for a given basic block introduced by control-flow restructuring. This information is not enough to detect Instructions with duplicated uses. Proper detection should actually be based on GHAST.
58 lines
1.8 KiB
C++
58 lines
1.8 KiB
C++
//
|
|
// Copyright rev.ng Srls. See LICENSE.md for details.
|
|
//
|
|
|
|
/// \brief Dataflow analysis to identify which Instructions must be serialized
|
|
|
|
#include "llvm/IR/BasicBlock.h"
|
|
#include "llvm/IR/Instruction.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
#include "llvm/Support/Casting.h"
|
|
|
|
#include "revng/Model/LoadModelPass.h"
|
|
#include "revng/Support/Debug.h"
|
|
#include "revng/Support/FunctionTags.h"
|
|
#include "revng/Support/IRHelpers.h"
|
|
|
|
#include "revng-c/MarkForSerialization/MarkAnalysis.h"
|
|
#include "revng-c/MarkForSerialization/MarkForSerializationPass.h"
|
|
#include "revng-c/RestructureCFGPass/RestructureCFG.h"
|
|
#include "revng-c/TargetFunctionOption/TargetFunctionOption.h"
|
|
|
|
Logger<> MarkLog("mark-serialization");
|
|
|
|
void MarkForSerializationPass::getAnalysisUsage(llvm::AnalysisUsage &AU) const {
|
|
AU.addRequired<RestructureCFG>();
|
|
AU.setPreservesAll();
|
|
}
|
|
|
|
bool MarkForSerializationPass::runOnFunction(llvm::Function &F) {
|
|
|
|
// Skip non-isolated functions
|
|
auto FTags = FunctionTags::TagsSet::from(&F);
|
|
if (not FTags.contains(FunctionTags::Lifted))
|
|
return false;
|
|
|
|
// If the `-single-decompilation` option was passed from command line, skip
|
|
// decompilation for all the functions that are not the selected one.
|
|
if (not TargetFunction.empty())
|
|
if (not F.getName().equals(TargetFunction.c_str()))
|
|
return false;
|
|
|
|
// Mark instructions for serialization, and write the results in ToSerialize
|
|
ToSerialize = {};
|
|
MarkAnalysis::Analysis Mark(F, ToSerialize);
|
|
Mark.initialize();
|
|
Mark.run();
|
|
|
|
return false;
|
|
}
|
|
|
|
char MarkForSerializationPass::ID = 0;
|
|
|
|
using Register = llvm::RegisterPass<MarkForSerializationPass>;
|
|
static Register X("mark-for-serialization",
|
|
"Pass that marks Instructions for serialization in C",
|
|
false,
|
|
false);
|