From 723ae8d8014cf22f216b60dc747ef92a8bb6e5b8 Mon Sep 17 00:00:00 2001 From: Giacomo Vercesi Date: Thu, 8 Jan 2026 15:13:12 +0100 Subject: [PATCH] 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. --- .../BasicAnalyses/GeneratedCodeBasicInfo.h | 62 +++++++------------ .../revng/EarlyFunctionAnalysis/CollectCFG.h | 11 ---- .../FunctionIsolation/IsolateFunctions.h | 2 +- lib/BasicAnalyses/GeneratedCodeBasicInfo.cpp | 16 ++--- lib/EarlyFunctionAnalysis/AttachDebugInfo.cpp | 3 +- lib/EarlyFunctionAnalysis/CollectCFG.cpp | 6 +- lib/EarlyFunctionAnalysis/DetectABI.cpp | 3 +- lib/FunctionIsolation/EnforceABI.cpp | 3 +- .../InvokeIsolatedFunctions.cpp | 7 +-- lib/FunctionIsolation/IsolateFunctions.cpp | 6 +- lib/FunctionIsolation/PromoteCSVs.cpp | 3 +- .../InjectStackSizeProbesAtCallSitesPass.cpp | 3 +- .../PromoteStackPointerPass.cpp | 3 +- 13 files changed, 46 insertions(+), 82 deletions(-) diff --git a/include/revng/BasicAnalyses/GeneratedCodeBasicInfo.h b/include/revng/BasicAnalyses/GeneratedCodeBasicInfo.h index 33bf98a0e..35870e0c6 100644 --- a/include/revng/BasicAnalyses/GeneratedCodeBasicInfo.h +++ b/include/revng/BasicAnalyses/GeneratedCodeBasicInfo.h @@ -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 JumpTargets; + unsigned PCRegSize = 0; + llvm::Function *RootFunction = nullptr; + std::vector CSVs; + std::vector ABIRegisters; + std::set ABIRegistersSet; + llvm::Function *NewPC = nullptr; + std::unique_ptr PCH; + using PCToBlockMap = std::multimap; + 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 JumpTargets; - unsigned PCRegSize; - llvm::Function *RootFunction; - std::vector CSVs; - std::vector ABIRegisters; - std::set ABIRegistersSet; - llvm::Function *NewPC; - std::unique_ptr PCH; - using PCToBlockMap = std::multimap; - bool RootParsed = false; }; template<> diff --git a/include/revng/EarlyFunctionAnalysis/CollectCFG.h b/include/revng/EarlyFunctionAnalysis/CollectCFG.h index b91404784..1f9b47cef 100644 --- a/include/revng/EarlyFunctionAnalysis/CollectCFG.h +++ b/include/revng/EarlyFunctionAnalysis/CollectCFG.h @@ -18,23 +18,12 @@ using CFGMap = TupleTreeContainer ClonedModule; LLVMFunctionContainer &Output; - GeneratedCodeBasicInfo GCBI; + std::optional 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. diff --git a/lib/BasicAnalyses/GeneratedCodeBasicInfo.cpp b/lib/BasicAnalyses/GeneratedCodeBasicInfo.cpp index bbb74c809..bebcae0f6 100644 --- a/lib/BasicAnalyses/GeneratedCodeBasicInfo.cpp +++ b/lib/BasicAnalyses/GeneratedCodeBasicInfo.cpp @@ -27,14 +27,17 @@ char GeneratedCodeBasicInfoWrapperPass::ID = 0; using RegisterGCBI = RegisterPass; 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(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(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().get(); - GCBI.reset(new GeneratedCodeBasicInfo(*LMA.getReadOnlyModel())); - GCBI->run(M); + GCBI.reset(new GeneratedCodeBasicInfo(*LMA.getReadOnlyModel(), M)); return false; } diff --git a/lib/EarlyFunctionAnalysis/AttachDebugInfo.cpp b/lib/EarlyFunctionAnalysis/AttachDebugInfo.cpp index be5524af5..8bd1ec9c5 100644 --- a/lib/EarlyFunctionAnalysis/AttachDebugInfo.cpp +++ b/lib/EarlyFunctionAnalysis/AttachDebugInfo.cpp @@ -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 & { diff --git a/lib/EarlyFunctionAnalysis/CollectCFG.cpp b/lib/EarlyFunctionAnalysis/CollectCFG.cpp index 32d3f0dc0..9861f0619 100644 --- a/lib/EarlyFunctionAnalysis/CollectCFG.cpp +++ b/lib/EarlyFunctionAnalysis/CollectCFG.cpp @@ -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())), diff --git a/lib/EarlyFunctionAnalysis/DetectABI.cpp b/lib/EarlyFunctionAnalysis/DetectABI.cpp index a877562e3..59862a5d1 100644 --- a/lib/EarlyFunctionAnalysis/DetectABI.cpp +++ b/lib/EarlyFunctionAnalysis/DetectABI.cpp @@ -1110,8 +1110,7 @@ llvm::Error DetectABI::run(Model &Model, TupleTree &TupleModel = Model.get(); model::Binary &Binary = *TupleModel; - GeneratedCodeBasicInfo GCBI(Binary); - GCBI.run(Module); + GeneratedCodeBasicInfo GCBI(Binary, Module); revng::pipes::CFGMap CFGs(""); ControlFlowGraphCache FMC(CFGs); diff --git a/lib/FunctionIsolation/EnforceABI.cpp b/lib/FunctionIsolation/EnforceABI.cpp index 975987645..4601b0cb7 100644 --- a/lib/FunctionIsolation/EnforceABI.cpp +++ b/lib/FunctionIsolation/EnforceABI.cpp @@ -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 & { diff --git a/lib/FunctionIsolation/InvokeIsolatedFunctions.cpp b/lib/FunctionIsolation/InvokeIsolatedFunctions.cpp index dcfb7f4a9..50bcb36e2 100644 --- a/lib/FunctionIsolation/InvokeIsolatedFunctions.cpp +++ b/lib/FunctionIsolation/InvokeIsolatedFunctions.cpp @@ -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", diff --git a/lib/FunctionIsolation/IsolateFunctions.cpp b/lib/FunctionIsolation/IsolateFunctions.cpp index c9235b980..d56a0efef 100644 --- a/lib/FunctionIsolation/IsolateFunctions.cpp +++ b/lib/FunctionIsolation/IsolateFunctions.cpp @@ -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 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(ClonedModule->getFunction("root"), - GCBI, + *GCBI, *Model.get().get(), CFGGetter); Impl->prologue(); diff --git a/lib/FunctionIsolation/PromoteCSVs.cpp b/lib/FunctionIsolation/PromoteCSVs.cpp index 6cec0f505..3251491ac 100644 --- a/lib/FunctionIsolation/PromoteCSVs.cpp +++ b/lib/FunctionIsolation/PromoteCSVs.cpp @@ -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(); diff --git a/lib/PromoteStackPointer/InjectStackSizeProbesAtCallSitesPass.cpp b/lib/PromoteStackPointer/InjectStackSizeProbesAtCallSitesPass.cpp index d7a8d923c..b9ca368ee 100644 --- a/lib/PromoteStackPointer/InjectStackSizeProbesAtCallSitesPass.cpp +++ b/lib/PromoteStackPointer/InjectStackSizeProbesAtCallSitesPass.cpp @@ -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); } diff --git a/lib/PromoteStackPointer/PromoteStackPointerPass.cpp b/lib/PromoteStackPointer/PromoteStackPointerPass.cpp index f8156f9db..dc3d674de 100644 --- a/lib/PromoteStackPointer/PromoteStackPointerPass.cpp +++ b/lib/PromoteStackPointer/PromoteStackPointerPass.cpp @@ -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); }