//===- bolt/Core/CallGraphWalker.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the CallGraphWalker class. // //===----------------------------------------------------------------------===// #include "bolt/Core/CallGraphWalker.h" #include "bolt/Core/BinaryFunctionCallGraph.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Timer.h" #include #include namespace opts { extern llvm::cl::opt TimeOpts; } namespace llvm { namespace bolt { void CallGraphWalker::traverseCG() { NamedRegionTimer T1("CG Traversal", "CG Traversal", "CG breakdown", "CG breakdown", opts::TimeOpts); std::queue Queue; std::set InQueue; for (BinaryFunction *Func : TopologicalCGOrder) { Queue.push(Func); InQueue.insert(Func); } while (!Queue.empty()) { BinaryFunction *Func = Queue.front(); Queue.pop(); InQueue.erase(Func); bool Changed = false; for (CallbackTy Visitor : Visitors) { bool CurVisit = Visitor(Func); Changed = Changed || CurVisit; } if (Changed) { for (CallGraph::NodeId CallerID : CG.predecessors(CG.getNodeId(Func))) { BinaryFunction *CallerFunc = CG.nodeIdToFunc(CallerID); if (InQueue.count(CallerFunc)) continue; Queue.push(CallerFunc); InQueue.insert(CallerFunc); } } } } void CallGraphWalker::walk() { TopologicalCGOrder = CG.buildTraversalOrder(); traverseCG(); } } // namespace bolt } // namespace llvm