1//===- bolt/Passes/CallGraphWalker.cpp ------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the CallGraphWalker class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "bolt/Passes/CallGraphWalker.h"
14#include "bolt/Passes/BinaryFunctionCallGraph.h"
15#include "llvm/Support/CommandLine.h"
16#include "llvm/Support/Timer.h"
17#include <queue>
18#include <set>
19
20namespace opts {
21extern llvm::cl::opt<bool> TimeOpts;
22}
23
24namespace llvm {
25namespace bolt {
26
27void CallGraphWalker::traverseCG() {
28 NamedRegionTimer T1("CG Traversal", "CG Traversal", "CG breakdown",
29 "CG breakdown", opts::TimeOpts);
30 std::queue<BinaryFunction *> Queue;
31 std::set<BinaryFunction *> InQueue;
32
33 for (BinaryFunction *Func : TopologicalCGOrder) {
34 Queue.push(x: Func);
35 InQueue.insert(x: Func);
36 }
37
38 while (!Queue.empty()) {
39 BinaryFunction *Func = Queue.front();
40 Queue.pop();
41 InQueue.erase(x: Func);
42
43 bool Changed = false;
44 for (CallbackTy Visitor : Visitors) {
45 bool CurVisit = Visitor(Func);
46 Changed = Changed || CurVisit;
47 }
48
49 if (Changed) {
50 for (CallGraph::NodeId CallerID : CG.predecessors(Id: CG.getNodeId(BF: Func))) {
51 BinaryFunction *CallerFunc = CG.nodeIdToFunc(Id: CallerID);
52 if (InQueue.count(x: CallerFunc))
53 continue;
54 Queue.push(x: CallerFunc);
55 InQueue.insert(x: CallerFunc);
56 }
57 }
58 }
59}
60
61void CallGraphWalker::walk() {
62 TopologicalCGOrder = CG.buildTraversalOrder();
63 traverseCG();
64}
65
66} // namespace bolt
67} // namespace llvm
68

source code of bolt/lib/Passes/CallGraphWalker.cpp