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