1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00
llvm-mirror/lib/IR/OptBisect.cpp
Fedor Sergeev f4f5aa42aa [NFC] OptPassGate extracted from OptBisect
Summary:
This is an NFC refactoring of the OptBisect class to split it into an optional pass gate interface used by LLVMContext and the Optional Pass Bisector (OptBisect) used for debugging of optional passes.

This refactoring is needed for D44464, which introduces setOptPassGate() method to allow implementations other than OptBisect.

Patch by Yevgeny Rouban.

Reviewers: andrew.w.kaylor, fedor.sergeev, vsk, dberlin, Eugene.Zelenko, reames, skatkov
Reviewed By: fedor.sergeev
Differential Revision: https://reviews.llvm.org/D44821

llvm-svn: 328637
2018-03-27 16:57:20 +00:00

128 lines
4.1 KiB
C++

//===- llvm/IR/OptBisect/Bisect.cpp - LLVM Bisect support -----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
/// \file
/// This file implements support for a bisecting optimizations based on a
/// command line option.
//
//===----------------------------------------------------------------------===//
#include "llvm/IR/OptBisect.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <limits>
#include <string>
using namespace llvm;
static cl::opt<int> OptBisectLimit("opt-bisect-limit", cl::Hidden,
cl::init(std::numeric_limits<int>::max()),
cl::Optional,
cl::desc("Maximum optimization to perform"));
OptBisect::OptBisect() : OptPassGate() {
BisectEnabled = OptBisectLimit != std::numeric_limits<int>::max();
}
static void printPassMessage(const StringRef &Name, int PassNum,
StringRef TargetDesc, bool Running) {
StringRef Status = Running ? "" : "NOT ";
errs() << "BISECT: " << Status << "running pass "
<< "(" << PassNum << ") " << Name << " on " << TargetDesc << "\n";
}
static std::string getDescription(const Module &M) {
return "module (" + M.getName().str() + ")";
}
static std::string getDescription(const Function &F) {
return "function (" + F.getName().str() + ")";
}
static std::string getDescription(const BasicBlock &BB) {
return "basic block (" + BB.getName().str() + ") in function (" +
BB.getParent()->getName().str() + ")";
}
static std::string getDescription(const Loop &L) {
// FIXME: Move into LoopInfo so we can get a better description
// (and avoid a circular dependency between IR and Analysis).
return "loop";
}
static std::string getDescription(const Region &R) {
// FIXME: Move into RegionInfo so we can get a better description
// (and avoid a circular dependency between IR and Analysis).
return "region";
}
static std::string getDescription(const CallGraphSCC &SCC) {
// FIXME: Move into CallGraphSCCPass to avoid circular dependency between
// IR and Analysis.
std::string Desc = "SCC (";
bool First = true;
for (CallGraphNode *CGN : SCC) {
if (First)
First = false;
else
Desc += ", ";
Function *F = CGN->getFunction();
if (F)
Desc += F->getName();
else
Desc += "<<null function>>";
}
Desc += ")";
return Desc;
}
bool OptBisect::shouldRunPass(const Pass *P, const Module &U) {
return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
}
bool OptBisect::shouldRunPass(const Pass *P, const Function &U) {
return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
}
bool OptBisect::shouldRunPass(const Pass *P, const BasicBlock &U) {
return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
}
bool OptBisect::shouldRunPass(const Pass *P, const Region &U) {
return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
}
bool OptBisect::shouldRunPass(const Pass *P, const Loop &U) {
return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
}
bool OptBisect::shouldRunPass(const Pass *P, const CallGraphSCC &U) {
return !BisectEnabled || checkPass(P->getPassName(), getDescription(U));
}
bool OptBisect::checkPass(const StringRef PassName,
const StringRef TargetDesc) {
assert(BisectEnabled);
int CurBisectNum = ++LastBisectNum;
bool ShouldRun = (OptBisectLimit == -1 || CurBisectNum <= OptBisectLimit);
printPassMessage(PassName, CurBisectNum, TargetDesc, ShouldRun);
return ShouldRun;
}