Line data Source code
1 : //===- llvm/IR/OptBisect/Bisect.cpp - LLVM Bisect support -----------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : /// \file
11 : /// This file implements support for a bisecting optimizations based on a
12 : /// command line option.
13 : //
14 : //===----------------------------------------------------------------------===//
15 :
16 : #include "llvm/IR/OptBisect.h"
17 : #include "llvm/ADT/StringRef.h"
18 : #include "llvm/Analysis/CallGraph.h"
19 : #include "llvm/Analysis/CallGraphSCCPass.h"
20 : #include "llvm/Analysis/LoopInfo.h"
21 : #include "llvm/Analysis/RegionInfo.h"
22 : #include "llvm/IR/BasicBlock.h"
23 : #include "llvm/IR/Function.h"
24 : #include "llvm/IR/Module.h"
25 : #include "llvm/Pass.h"
26 : #include "llvm/Support/CommandLine.h"
27 : #include "llvm/Support/raw_ostream.h"
28 : #include <cassert>
29 : #include <limits>
30 : #include <string>
31 :
32 : using namespace llvm;
33 :
34 : static cl::opt<int> OptBisectLimit("opt-bisect-limit", cl::Hidden,
35 : cl::init(std::numeric_limits<int>::max()),
36 : cl::Optional,
37 : cl::desc("Maximum optimization to perform"));
38 :
39 33449 : OptBisect::OptBisect() : OptPassGate() {
40 33449 : BisectEnabled = OptBisectLimit != std::numeric_limits<int>::max();
41 33449 : }
42 :
43 989 : static void printPassMessage(const StringRef &Name, int PassNum,
44 : StringRef TargetDesc, bool Running) {
45 989 : StringRef Status = Running ? "" : "NOT ";
46 989 : errs() << "BISECT: " << Status << "running pass "
47 1962 : << "(" << PassNum << ") " << Name << " on " << TargetDesc << "\n";
48 981 : }
49 :
50 26 : static std::string getDescription(const Module &M) {
51 52 : return "module (" + M.getName().str() + ")";
52 : }
53 :
54 719 : static std::string getDescription(const Function &F) {
55 2157 : return "function (" + F.getName().str() + ")";
56 : }
57 :
58 0 : static std::string getDescription(const BasicBlock &BB) {
59 0 : return "basic block (" + BB.getName().str() + ") in function (" +
60 0 : BB.getParent()->getName().str() + ")";
61 : }
62 :
63 0 : static std::string getDescription(const Loop &L) {
64 : // FIXME: Move into LoopInfo so we can get a better description
65 : // (and avoid a circular dependency between IR and Analysis).
66 164 : return "loop";
67 : }
68 :
69 0 : static std::string getDescription(const Region &R) {
70 : // FIXME: Move into RegionInfo so we can get a better description
71 : // (and avoid a circular dependency between IR and Analysis).
72 0 : return "region";
73 : }
74 :
75 80 : static std::string getDescription(const CallGraphSCC &SCC) {
76 : // FIXME: Move into CallGraphSCCPass to avoid circular dependency between
77 : // IR and Analysis.
78 80 : std::string Desc = "SCC (";
79 : bool First = true;
80 160 : for (CallGraphNode *CGN : SCC) {
81 80 : if (First)
82 : First = false;
83 : else
84 : Desc += ", ";
85 80 : Function *F = CGN->getFunction();
86 80 : if (F)
87 60 : Desc += F->getName();
88 : else
89 : Desc += "<<null function>>";
90 : }
91 : Desc += ")";
92 80 : return Desc;
93 : }
94 :
95 23442 : bool OptBisect::shouldRunPass(const Pass *P, const Module &U) {
96 23468 : return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
97 : }
98 :
99 9311498 : bool OptBisect::shouldRunPass(const Pass *P, const Function &U) {
100 9311498 : return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
101 : }
102 :
103 1331 : bool OptBisect::shouldRunPass(const Pass *P, const BasicBlock &U) {
104 1331 : return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
105 : }
106 :
107 13134 : bool OptBisect::shouldRunPass(const Pass *P, const Region &U) {
108 13134 : return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
109 : }
110 :
111 65266 : bool OptBisect::shouldRunPass(const Pass *P, const Loop &U) {
112 65430 : return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
113 : }
114 :
115 165106 : bool OptBisect::shouldRunPass(const Pass *P, const CallGraphSCC &U) {
116 165106 : return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
117 : }
118 :
119 989 : bool OptBisect::checkPass(const StringRef PassName,
120 : const StringRef TargetDesc) {
121 : assert(BisectEnabled);
122 :
123 989 : int CurBisectNum = ++LastBisectNum;
124 989 : bool ShouldRun = (OptBisectLimit == -1 || CurBisectNum <= OptBisectLimit);
125 989 : printPassMessage(PassName, CurBisectNum, TargetDesc, ShouldRun);
126 981 : return ShouldRun;
127 : }
|