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 25using namespace llvm; 26 27static cl::opt<int> OptBisectLimit("opt-bisect-limit", cl::Hidden, 28 cl::init(INT_MAX), cl::Optional, 29 cl::desc("Maximum optimization to perform")); 30 31OptBisect::OptBisect() { 32 BisectEnabled = OptBisectLimit != INT_MAX; 33} 34 35static 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 42static void printCaseMessage(int CaseNum, StringRef Msg, bool Running) { 43 if (Running) 44 errs() << "BISECT: running case ("; 45 else 46 errs() << "BISECT: NOT running case ("; 47 errs() << CaseNum << "): " << Msg << "\n"; 48} 49 50static std::string getDescription(const Module &M) { 51 return "module (" + M.getName().str() + ")"; 52} 53 54static std::string getDescription(const Function &F) { 55 return "function (" + F.getName().str() + ")"; 56} 57 58static std::string getDescription(const BasicBlock &BB) { 59 return "basic block (" + BB.getName().str() + ") in function (" + 60 BB.getParent()->getName().str() + ")"; 61} 62 63static std::string getDescription(const Loop &L) { 64 // FIXME: I'd like to be able to provide a better description here, but 65 // calling L->getHeader() would introduce a new dependency on the 66 // LLVMCore library. 67 return "loop"; 68} 69 70static std::string getDescription(const CallGraphSCC &SCC) { 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. 89template bool OptBisect::shouldRunPass(const Pass *, const Module &); 90template bool OptBisect::shouldRunPass(const Pass *, const Function &); 91template bool OptBisect::shouldRunPass(const Pass *, const BasicBlock &); 92template bool OptBisect::shouldRunPass(const Pass *, const Loop &); 93template bool OptBisect::shouldRunPass(const Pass *, const CallGraphSCC &); 94 95template <class UnitT> 96bool OptBisect::shouldRunPass(const Pass *P, const UnitT &U) { 97 if (!BisectEnabled) 98 return true; 99 return checkPass(P->getPassName(), getDescription(U)); 100} 101 102bool OptBisect::checkPass(const StringRef PassName, 103 const StringRef TargetDesc) { 104 assert(BisectEnabled); 105 106 int CurBisectNum = ++LastBisectNum; 107 bool ShouldRun = (OptBisectLimit == -1 || CurBisectNum <= OptBisectLimit); 108 printPassMessage(PassName, CurBisectNum, TargetDesc, ShouldRun); 109 return ShouldRun; 110} 111 112bool OptBisect::shouldRunCase(const Twine &Msg) { 113 if (!BisectEnabled) 114 return true; 115 int CurFuelNum = ++LastBisectNum; 116 bool ShouldRun = (OptBisectLimit == -1 || CurFuelNum <= OptBisectLimit); 117 printCaseMessage(CurFuelNum, Msg.str(), ShouldRun); 118 return ShouldRun; 119} 120 121