GCBI: rework members and constructor

Move member declaration to the top of the class definition of
`GeneratedCodeBasicInfo` and initialize primitive members.
Merge the `run` method into the constructor since all uses have them
happening close to each other.
This commit is contained in:
Giacomo Vercesi
2026-01-08 15:13:12 +01:00
parent 2d8e7f78bb
commit 723ae8d801
13 changed files with 46 additions and 82 deletions
@@ -45,22 +45,28 @@ class MDNode;
/// between basic blocks generated due to translation and dispatcher-related
/// basic blocks.
class GeneratedCodeBasicInfo {
public:
GeneratedCodeBasicInfo(const model::Binary &Binary) :
Binary(&Binary),
PC(nullptr),
SP(nullptr),
RA(nullptr),
Dispatcher(nullptr),
DispatcherFail(nullptr),
AnyPC(nullptr),
UnexpectedPC(nullptr),
PCRegSize(0),
RootFunction(nullptr),
PCH(),
RootParsed(false) {}
private:
const model::Binary &Binary;
llvm::GlobalVariable *PC = nullptr;
llvm::GlobalVariable *SP = nullptr;
llvm::GlobalVariable *RA = nullptr;
llvm::BasicBlock *Dispatcher = nullptr;
llvm::BasicBlock *DispatcherFail = nullptr;
llvm::BasicBlock *AnyPC = nullptr;
llvm::BasicBlock *UnexpectedPC = nullptr;
std::map<MetaAddress, llvm::BasicBlock *> JumpTargets;
unsigned PCRegSize = 0;
llvm::Function *RootFunction = nullptr;
std::vector<llvm::GlobalVariable *> CSVs;
std::vector<llvm::GlobalVariable *> ABIRegisters;
std::set<llvm::GlobalVariable *> ABIRegistersSet;
llvm::Function *NewPC = nullptr;
std::unique_ptr<ProgramCounterHandler> PCH;
using PCToBlockMap = std::multimap<MetaAddress, llvm::BasicBlock *>;
bool RootParsed = false;
void run(llvm::Module &M);
public:
GeneratedCodeBasicInfo(const model::Binary &Binary, llvm::Module &M);
/// Handle the invalidation of this information, so that it does not get
/// invalidated by other passes.
@@ -163,7 +169,7 @@ public:
const ProgramCounterHandler *programCounterHandler() {
if (not PCH) {
llvm::Module *M = RootFunction->getParent();
PCH = ProgramCounterHandler::fromModule(Binary->Architecture(), M);
PCH = ProgramCounterHandler::fromModule(Binary.Architecture(), M);
}
return PCH.get();
@@ -298,7 +304,7 @@ public:
}
MetaAddress fromPC(uint64_t PC) const {
return MetaAddress::fromPC(Binary->Architecture(), PC);
return MetaAddress::fromPC(Binary.Architecture(), PC);
}
llvm::Function *root() {
@@ -310,31 +316,11 @@ public:
blocksByPCRange(MetaAddress Start, MetaAddress End);
bool hasDelaySlot() const {
return model::Architecture::hasDelaySlot(Binary->Architecture());
return model::Architecture::hasDelaySlot(Binary.Architecture());
}
private:
void parseRoot();
private:
const model::Binary *Binary;
llvm::GlobalVariable *PC;
llvm::GlobalVariable *SP;
llvm::GlobalVariable *RA;
llvm::BasicBlock *Dispatcher;
llvm::BasicBlock *DispatcherFail;
llvm::BasicBlock *AnyPC;
llvm::BasicBlock *UnexpectedPC;
std::map<MetaAddress, llvm::BasicBlock *> JumpTargets;
unsigned PCRegSize;
llvm::Function *RootFunction;
std::vector<llvm::GlobalVariable *> CSVs;
std::vector<llvm::GlobalVariable *> ABIRegisters;
std::set<llvm::GlobalVariable *> ABIRegistersSet;
llvm::Function *NewPC;
std::unique_ptr<ProgramCounterHandler> PCH;
using PCToBlockMap = std::multimap<MetaAddress, llvm::BasicBlock *>;
bool RootParsed = false;
};
template<>
@@ -18,23 +18,12 @@ using CFGMap = TupleTreeContainer<efa::ControlFlowGraph,
namespace piperuns {
namespace detail {
struct GCBIRun {
GCBIRun(GeneratedCodeBasicInfo &GCBI, llvm::Module &Module) {
GCBI.run(Module);
}
};
} // namespace detail
class CollectCFG {
private:
const class Model &Model;
CFGMap &Output;
GeneratedCodeBasicInfo GCBI;
detail::GCBIRun GCBIRun;
efa::FunctionSummaryOracle Oracle;
efa::CFGAnalyzer Analyzer;
@@ -31,7 +31,7 @@ class Isolate {
private:
std::unique_ptr<llvm::Module> ClonedModule;
LLVMFunctionContainer &Output;
GeneratedCodeBasicInfo GCBI;
std::optional<GeneratedCodeBasicInfo> GCBI;
// unique_ptr to the implementation. This is a temporary measure until the
// old pipeline is dropped and the body of the `Impl` class can be inlined in
// this one.
+8 -8
View File
@@ -27,14 +27,17 @@ char GeneratedCodeBasicInfoWrapperPass::ID = 0;
using RegisterGCBI = RegisterPass<GeneratedCodeBasicInfoWrapperPass>;
static RegisterGCBI X("gcbi", "Generated Code Basic Info", true, true);
void GeneratedCodeBasicInfo::run(Module &M) {
GeneratedCodeBasicInfo::GeneratedCodeBasicInfo(const model::Binary &Binary,
llvm::Module &M) :
Binary(Binary) {
RootFunction = M.getFunction("root");
NewPC = getIRHelper("newpc", M);
revng_log(PassesLog, "Starting GeneratedCodeBasicInfo");
using namespace model::Architecture;
auto Architecture = Binary->Architecture();
auto Architecture = Binary.Architecture();
PC = M.getGlobalVariable(getPCCSVName(Architecture), true);
SP = M.getGlobalVariable(getCSVName(getStackPointer(Architecture)), true);
auto ReturnAddressRegister = getReturnAddressRegister(Architecture);
@@ -158,23 +161,20 @@ GeneratedCodeBasicInfo::blocksByPCRange(MetaAddress Start, MetaAddress End) {
GeneratedCodeBasicInfo
GeneratedCodeBasicInfoAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {
auto &LMA = MAM.getResult<LoadModelAnalysis>(M);
GeneratedCodeBasicInfo GCBI(*LMA.getReadOnlyModel());
GCBI.run(M);
GeneratedCodeBasicInfo GCBI(*LMA.getReadOnlyModel(), M);
return GCBI;
}
GeneratedCodeBasicInfo
GeneratedCodeBasicInfoAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
auto &LMA = FAM.getResult<LoadModelAnalysis>(F);
GeneratedCodeBasicInfo GCBI(*LMA.getReadOnlyModel());
GCBI.run(*F.getParent());
GeneratedCodeBasicInfo GCBI(*LMA.getReadOnlyModel(), *F.getParent());
return GCBI;
}
bool GeneratedCodeBasicInfoWrapperPass::runOnModule(Module &M) {
auto &LMA = getAnalysis<LoadModelWrapperPass>().get();
GCBI.reset(new GeneratedCodeBasicInfo(*LMA.getReadOnlyModel()));
GCBI->run(M);
GCBI.reset(new GeneratedCodeBasicInfo(*LMA.getReadOnlyModel(), M));
return false;
}
@@ -353,8 +353,7 @@ void AttachDebugInfo::runOnLLVMFunction(const model::Function &Function,
llvm::Function &LLVMFunction) {
const MetaAddress &Address = Function.Entry();
llvm::Module &Module = *LLVMFunction.getParent();
GeneratedCodeBasicInfo GCBI(Binary);
GCBI.run(Module);
GeneratedCodeBasicInfo GCBI(Binary, Module);
auto CFGGetter =
[*this](const MetaAddress &Address) -> const efa::ControlFlowGraph & {
+2 -4
View File
@@ -46,8 +46,7 @@ public:
using FSOracle = efa::FunctionSummaryOracle;
// Collect GCBI
GeneratedCodeBasicInfo GCBI(*Binary);
GCBI.run(M);
GeneratedCodeBasicInfo GCBI(*Binary, M);
FSOracle Oracle = FSOracle::importBasicPrototypeData(M, GCBI, *Binary);
efa::CFGAnalyzer Analyzer(M, GCBI, Binary, Oracle);
@@ -100,8 +99,7 @@ CollectCFG::CollectCFG(const class Model &Model,
CFGMap &Output) :
Model(Model),
Output(Output),
GCBI(*Model.get().get()),
GCBIRun(GCBI, Input.getModule()),
GCBI(*Model.get().get(), Input.getModule()),
Oracle(FSO::importBasicPrototypeData(Input.getModule(),
GCBI,
*Model.get().get())),
+1 -2
View File
@@ -1110,8 +1110,7 @@ llvm::Error DetectABI::run(Model &Model,
TupleTree<model::Binary> &TupleModel = Model.get();
model::Binary &Binary = *TupleModel;
GeneratedCodeBasicInfo GCBI(Binary);
GCBI.run(Module);
GeneratedCodeBasicInfo GCBI(Binary, Module);
revng::pipes::CFGMap CFGs("");
ControlFlowGraphCache FMC(CFGs);
+1 -2
View File
@@ -564,8 +564,7 @@ namespace revng::pypeline::piperuns {
void EnforceABI::runOnLLVMFunction(const model::Function &Function,
llvm::Function &LLVMFunction) {
llvm::Module &Module = *LLVMFunction.getParent();
GeneratedCodeBasicInfo GCBI(Binary);
GCBI.run(Module);
GeneratedCodeBasicInfo GCBI(Binary, Module);
auto CFGGetter =
[this](const MetaAddress &Address) -> const efa::ControlFlowGraph & {
@@ -48,9 +48,7 @@ public:
RootModule(RootModule),
FunctionModule(FunctionModule),
Context(RootModule.getContext()),
GCBI(Binary) {
GCBI.run(RootModule);
GCBI(Binary, RootModule) {
for (const model::Function &Function : Binary.Functions()) {
auto *F = FunctionModule->getFunction(llvmName(Function));
@@ -201,8 +199,7 @@ public:
static void populateFunctionDispatcher(const model::Binary &Binary,
llvm::Module &Module) {
GeneratedCodeBasicInfo GCBI(Binary);
GCBI.run(Module);
GeneratedCodeBasicInfo GCBI(Binary, Module);
llvm::LLVMContext &Context = Module.getContext();
llvm::Function *FunctionDispatcher = getIRHelper("function_dispatcher",
+3 -3
View File
@@ -706,7 +706,7 @@ Isolate::Isolate(const class Model &Model,
const CFGMap &CFG,
LLVMRootContainer &Root,
LLVMFunctionContainer &Output) :
Output(Output), GCBI(*Model.get().get()) {
Output(Output) {
// Manually perform `cloneIntoContext` to prune the root container as early as
// possible
llvm::SmallVector<char, 0> Buffer;
@@ -714,7 +714,7 @@ Isolate::Isolate(const class Model &Model,
Root.disposeIfPossible();
ClonedModule = readBitcode(Buffer, Output.getContext());
GCBI.run(*ClonedModule);
GCBI.emplace(*Model.get().get(), *ClonedModule);
auto CFGGetter =
[&CFG](const MetaAddress &Address) -> const efa::ControlFlowGraph & {
@@ -723,7 +723,7 @@ Isolate::Isolate(const class Model &Model,
// TODO: inline Impl
Impl = std::make_unique<IFI>(ClonedModule->getFunction("root"),
GCBI,
*GCBI,
*Model.get().get(),
CFGGetter);
Impl->prologue();
+1 -2
View File
@@ -637,8 +637,7 @@ namespace revng::pypeline::piperuns {
void PromoteCSVs::runOnLLVMFunction(const model::Function &Function,
llvm::Function &LLVMFunction) {
llvm::Module &Module = *LLVMFunction.getParent();
GeneratedCodeBasicInfo GCBI(Binary);
GCBI.run(Module);
GeneratedCodeBasicInfo GCBI(Binary, Module);
::PromoteCSVs Impl(Binary, Module, GCBI);
Impl.prologue();
@@ -79,8 +79,7 @@ namespace revng::pypeline::piperuns {
void InjectStackSizeProbesAtCallSites::runOnFunction(const model::Function
&Function) {
llvm::Module &Module = ModuleContainer.getModule(ObjectID(Function.Entry()));
GeneratedCodeBasicInfo GCBI(Binary);
GCBI.run(Module);
GeneratedCodeBasicInfo GCBI(Binary, Module);
injectStackSizeProbesAtCallSites(Module, GCBI);
}
@@ -227,8 +227,7 @@ namespace revng::pypeline::piperuns {
// TODO: inline promoteStackPointer once we dismiss the old pipeline
void PromoteStackPointer::runOnLLVMFunction(const model::Function &Function,
llvm::Function &LLVMFunction) {
GeneratedCodeBasicInfo GCBI(Binary);
GCBI.run(*LLVMFunction.getParent());
GeneratedCodeBasicInfo GCBI(Binary, *LLVMFunction.getParent());
promoteStackPointer(Binary, Function, LLVMFunction, GCBI);
}