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 OptBisect::OptBisect() : OptPassGate() { 40 BisectEnabled = OptBisectLimit != std::numeric_limits<int>::max(); 41 } 42 43 static void printPassMessage(const StringRef &Name, int PassNum, 44 StringRef TargetDesc, bool Running) { 45 StringRef Status = Running ? "" : "NOT "; 46 errs() << "BISECT: " << Status << "running pass " 47 << "(" << PassNum << ") " << Name << " on " << TargetDesc << "\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: Move into LoopInfo so we can get a better description 65 // (and avoid a circular dependency between IR and Analysis). 66 return "loop"; 67 } 68 69 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 return "region"; 73 } 74 75 static std::string getDescription(const CallGraphSCC &SCC) { 76 // FIXME: Move into CallGraphSCCPass to avoid circular dependency between 77 // IR and Analysis. 78 std::string Desc = "SCC ("; 79 bool First = true; 80 for (CallGraphNode *CGN : SCC) { 81 if (First) 82 First = false; 83 else 84 Desc += ", "; 85 Function *F = CGN->getFunction(); 86 if (F) 87 Desc += F->getName(); 88 else 89 Desc += "<<null function>>"; 90 } 91 Desc += ")"; 92 return Desc; 93 } 94 95 bool OptBisect::shouldRunPass(const Pass *P, const Module &U) { 96 return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); 97 } 98 99 bool OptBisect::shouldRunPass(const Pass *P, const Function &U) { 100 return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); 101 } 102 103 bool OptBisect::shouldRunPass(const Pass *P, const BasicBlock &U) { 104 return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); 105 } 106 107 bool OptBisect::shouldRunPass(const Pass *P, const Region &U) { 108 return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); 109 } 110 111 bool OptBisect::shouldRunPass(const Pass *P, const Loop &U) { 112 return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); 113 } 114 115 bool OptBisect::shouldRunPass(const Pass *P, const CallGraphSCC &U) { 116 return !BisectEnabled || checkPass(P->getPassName(), getDescription(U)); 117 } 118 119 bool OptBisect::checkPass(const StringRef PassName, 120 const StringRef TargetDesc) { 121 assert(BisectEnabled); 122 123 int CurBisectNum = ++LastBisectNum; 124 bool ShouldRun = (OptBisectLimit == -1 || CurBisectNum <= OptBisectLimit); 125 printPassMessage(PassName, CurBisectNum, TargetDesc, ShouldRun); 126 return ShouldRun; 127 } 128