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/Analysis/CallGraphSCCPass.h" 17 #include "llvm/Analysis/LazyCallGraph.h" 18 #include "llvm/Analysis/LoopInfo.h" 19 #include "llvm/Analysis/RegionInfo.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/IR/OptBisect.h" 22 #include "llvm/Pass.h" 23 #include "llvm/Support/CommandLine.h" 24 #include "llvm/Support/raw_ostream.h" 25 26 using namespace llvm; 27 28 static cl::opt<int> OptBisectLimit("opt-bisect-limit", cl::Hidden, 29 cl::init(INT_MAX), cl::Optional, 30 cl::desc("Maximum optimization to perform")); 31 32 OptBisect::OptBisect() { 33 BisectEnabled = OptBisectLimit != INT_MAX; 34 } 35 36 static void printPassMessage(const StringRef &Name, int PassNum, 37 StringRef TargetDesc, bool Running) { 38 StringRef Status = Running ? "" : "NOT "; 39 errs() << "BISECT: " << Status << "running pass " 40 << "(" << PassNum << ") " << Name << " on " << TargetDesc << "\n"; 41 } 42 43 static std::string getDescription(const Module &M) { 44 return "module (" + M.getName().str() + ")"; 45 } 46 47 static std::string getDescription(const Function &F) { 48 return "function (" + F.getName().str() + ")"; 49 } 50 51 static std::string getDescription(const BasicBlock &BB) { 52 return "basic block (" + BB.getName().str() + ") in function (" + 53 BB.getParent()->getName().str() + ")"; 54 } 55 56 static std::string getDescription(const Loop &L) { 57 // FIXME: Move into LoopInfo so we can get a better description 58 // (and avoid a circular dependency between IR and Analysis). 59 return "loop"; 60 } 61 62 static std::string getDescription(const Region &R) { 63 // FIXME: Move into RegionInfo so we can get a better description 64 // (and avoid a circular dependency between IR and Analysis). 65 return "region"; 66 } 67 68 static std::string getDescription(const CallGraphSCC &SCC) { 69 // FIXME: Move into CallGraphSCCPass to avoid circular dependency between 70 // IR and Analysis. 71 std::string Desc = "SCC ("; 72 bool First = true; 73 for (CallGraphNode *CGN : SCC) { 74 if (First) 75 First = false; 76 else 77 Desc += ", "; 78 Function *F = CGN->getFunction(); 79 if (F) 80 Desc += F->getName(); 81 else 82 Desc += "<<null function>>"; 83 } 84 Desc += ")"; 85 return Desc; 86 } 87 88 // Force instantiations. 89 template bool OptBisect::shouldRunPass(const Pass *, const Module &); 90 template bool OptBisect::shouldRunPass(const Pass *, const Function &); 91 template bool OptBisect::shouldRunPass(const Pass *, const BasicBlock &); 92 template bool OptBisect::shouldRunPass(const Pass *, const Loop &); 93 template bool OptBisect::shouldRunPass(const Pass *, const CallGraphSCC &); 94 template bool OptBisect::shouldRunPass(const Pass *, const Region &); 95 96 template <class UnitT> 97 bool OptBisect::shouldRunPass(const Pass *P, const UnitT &U) { 98 if (!BisectEnabled) 99 return true; 100 return checkPass(P->getPassName(), getDescription(U)); 101 } 102 103 bool OptBisect::checkPass(const StringRef PassName, 104 const StringRef TargetDesc) { 105 assert(BisectEnabled); 106 107 int CurBisectNum = ++LastBisectNum; 108 bool ShouldRun = (OptBisectLimit == -1 || CurBisectNum <= OptBisectLimit); 109 printPassMessage(PassName, CurBisectNum, TargetDesc, ShouldRun); 110 return ShouldRun; 111 } 112