Home | History | Annotate | Download | only in IR
      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 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 
     50 static std::string getDescription(const Module &M) {
     51   return "module (" + M.getName().str() + ")";
     52 }
     53 
     54 static std::string getDescription(const Function &F) {
     55   return "function (" + F.getName().str() + ")";
     56 }
     57 
     58 static std::string getDescription(const BasicBlock &BB) {
     59   return "basic block (" + BB.getName().str() + ") in function (" +
     60          BB.getParent()->getName().str() + ")";
     61 }
     62 
     63 static 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 
     70 static 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.
     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 
     95 template <class UnitT>
     96 bool OptBisect::shouldRunPass(const Pass *P, const UnitT &U) {
     97   if (!BisectEnabled)
     98     return true;
     99   return checkPass(P->getPassName(), getDescription(U));
    100 }
    101 
    102 bool 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 
    112 bool 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