1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

Revert "Re-land: Add new hidden option -print-changed which only reports changes to IR"

The test added in this commit is failing on Windows bots:

http://lab.llvm.org:8011/builders/llvm-clang-win-x-armv7l/builds/1269

This reverts commit f9e6d1edc0dad9afb26e773aa125ed62c58f7080 and follow-up commit 6859d95ea2d0f3fe0de2923a3f642170e66a1a14.
This commit is contained in:
Douglas Yung 2020-09-17 01:28:32 -07:00
parent 36de144674
commit b4c47725ed
4 changed files with 7 additions and 426 deletions

View File

@ -124,97 +124,6 @@ public:
void registerCallbacks(PassInstrumentationCallbacks &PIC);
};
// Base class for classes that report changes to the IR.
// It presents an interface for such classes and provides calls
// on various events as the new pass manager transforms the IR.
// It also provides filtering of information based on hidden options
// specifying which functions are interesting.
// Calls are made for the following events/queries:
// 1. The initial IR processed.
// 2. To get the representation of the IR (of type \p T).
// 3. When a pass does not change the IR.
// 4. When a pass changes the IR (given both before and after representations
// of type \p T).
// 5. When an IR is invalidated.
// 6. When a pass is run on an IR that is not interesting (based on options).
// 7. When a pass is ignored (pass manager or adapter pass).
// 8. To compare two IR representations (of type \p T).
template <typename IRUnitT> class ChangePrinter {
protected:
ChangePrinter() : InitialIR(true) {}
public:
virtual ~ChangePrinter();
// Determine if this pass/IR is interesting and if so, save the IR
// otherwise it is left on the stack without data
void saveIRBeforePass(Any IR, StringRef PassID);
// Compare the IR from before the pass after the pass.
void handleIRAfterPass(Any IR, StringRef PassID);
// Handle the situation where a pass is invalidated.
void handleInvalidatedPass(StringRef PassID);
protected:
// called on the first IR processed
virtual void handleInitialIR(Any IR) = 0;
// called before and after a pass to get the representation of the IR
virtual void generateIRRepresentation(Any IR, StringRef PassID,
IRUnitT &Output) = 0;
// called when the pass is not iteresting
virtual void omitAfter(StringRef PassID, std::string &Name) = 0;
// called when an interesting IR has changed
virtual void handleAfter(StringRef PassID, std::string &Name,
const IRUnitT &Before, const IRUnitT &After,
Any) = 0;
// called when an interesting pass is invalidated
virtual void handleInvalidated(StringRef PassID) = 0;
// called when the IR or pass is not interesting
virtual void handleFiltered(StringRef PassID, std::string &Name) = 0;
// called when an ignored pass is encountered
virtual void handleIgnored(StringRef PassID, std::string &Name) = 0;
// called to compare the before and after representations of the IR
virtual bool same(const IRUnitT &Before, const IRUnitT &After) = 0;
// stack of IRs before passes
std::vector<IRUnitT> BeforeStack;
// Is this the first IR seen?
bool InitialIR;
};
// A change printer based on the string representation of the IR as created
// by unwrapAndPrint. The string representation is stored in a std::string
// to preserve it as the IR changes in each pass. Note that the banner is
// included in this representation but it is massaged before reporting.
class IRChangePrinter : public ChangePrinter<std::string> {
public:
IRChangePrinter();
~IRChangePrinter() override;
void registerCallbacks(PassInstrumentationCallbacks &PIC);
protected:
// called on the first IR processed
void handleInitialIR(Any IR) override;
// called before and after a pass to get the representation of the IR
void generateIRRepresentation(Any IR, StringRef PassID,
std::string &Output) override;
// called when the pass is not iteresting
void omitAfter(StringRef PassID, std::string &Name) override;
// called when an interesting IR has changed
void handleAfter(StringRef PassID, std::string &Name,
const std::string &Before, const std::string &After,
Any) override;
// called when an interesting pass is invalidated
void handleInvalidated(StringRef PassID) override;
// called when the IR or pass is not interesting
void handleFiltered(StringRef PassID, std::string &Name) override;
// called when an ignored pass is encountered
void handleIgnored(StringRef PassID, std::string &Name) override;
// called to compare the before and after representations of the IR
bool same(const std::string &Before, const std::string &After) override;
raw_ostream &Out;
};
/// This class provides an interface to register all the standard pass
/// instrumentations and manages their state (if any).
class StandardInstrumentations {
@ -223,7 +132,6 @@ class StandardInstrumentations {
TimePassesHandler TimePasses;
OptNoneInstrumentation OptNone;
PreservedCFGCheckerInstrumentation PreservedCFGChecker;
IRChangePrinter PrintChangedIR;
public:
StandardInstrumentations(bool DebugLogging) : PrintPass(DebugLogging) {}

View File

@ -87,14 +87,14 @@ static cl::opt<bool> PrintAfterAll("print-after-all",
static cl::opt<bool>
PrintModuleScope("print-module-scope",
cl::desc("When printing IR for print-[before|after]{-all} "
"and change reporters always print a module IR"),
"always print a module IR"),
cl::init(false), cl::Hidden);
static cl::list<std::string>
PrintFuncsList("filter-print-funcs", cl::value_desc("function names"),
cl::desc("Only print IR for functions whose name "
"match this for all print-[before|after][-all] "
"and change reporter options"),
"options"),
cl::CommaSeparated, cl::Hidden);
/// This is a helper to determine whether to print IR before or

View File

@ -26,7 +26,6 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include <unordered_set>
#include <vector>
using namespace llvm;
@ -52,34 +51,6 @@ static cl::opt<bool>
cl::desc("Print all pass management debugging information. "
"`-debug-pass-manager` must also be specified"));
// A hidden option that prints out the IR after passes, similar to
// -print-after-all except that it only prints the IR after passes that
// change the IR. Those passes that do not make changes to the IR are
// reported as not making any changes. In addition, the initial IR is
// also reported. Other hidden options affect the output from this
// option. -filter-passes will limit the output to the named passes
// that actually change the IR and other passes are reported as filtered out.
// The specified passes will either be reported as making no changes (with
// no IR reported) or the changed IR will be reported. Also, the
// -filter-print-funcs and -print-module-scope options will do similar
// filtering based on function name, reporting changed IRs as functions(or
// modules if -print-module-scope is specified) for a particular function
// or indicating that the IR has been filtered out. The extra options
// can be combined, allowing only changed IRs for certain passes on certain
// functions to be reported in different formats, with the rest being
// reported as filtered out.
static cl::opt<bool> PrintChanged("print-changed",
cl::desc("Print changed IRs"),
cl::init(false), cl::Hidden);
// A hidden option that supports the -print-changed option. See
// the description for -print-changed for an explanation of the use
// of this option. Note that this option has no effect without -print-changed.
static cl::list<std::string>
PrintPassesList("filter-passes", cl::value_desc("pass names"),
cl::desc("Only consider IR changes for passes whose names "
"match for the print-changed option"),
cl::CommaSeparated, cl::Hidden);
namespace {
/// Extracting Module out of \p IR unit. Also fills a textual description
@ -136,8 +107,7 @@ void printIR(raw_ostream &OS, const Function *F, StringRef Banner,
}
void printIR(raw_ostream &OS, const Module *M, StringRef Banner,
StringRef Extra = StringRef(), bool Brief = false,
bool ShouldPreserveUseListOrder = false) {
StringRef Extra = StringRef(), bool Brief = false) {
if (Brief) {
OS << M->getName() << '\n';
return;
@ -145,7 +115,7 @@ void printIR(raw_ostream &OS, const Module *M, StringRef Banner,
if (llvm::isFunctionInPrintList("*") || llvm::forcePrintModuleIR()) {
OS << Banner << Extra << "\n";
M->print(OS, nullptr, ShouldPreserveUseListOrder);
M->print(OS, nullptr, false);
} else {
for (const auto &F : M->functions()) {
printIR(OS, &F, Banner, Extra);
@ -189,19 +159,17 @@ void printIR(raw_ostream &OS, const Loop *L, StringRef Banner,
/// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into
/// llvm::Any and does actual print job.
void unwrapAndPrint(raw_ostream &OS, Any IR, StringRef Banner,
bool ForceModule = false, bool Brief = false,
bool ShouldPreserveUseListOrder = false) {
bool ForceModule = false, bool Brief = false) {
if (ForceModule) {
if (auto UnwrappedModule = unwrapModule(IR))
printIR(OS, UnwrappedModule->first, Banner, UnwrappedModule->second,
Brief, ShouldPreserveUseListOrder);
printIR(OS, UnwrappedModule->first, Banner, UnwrappedModule->second);
return;
}
if (any_isa<const Module *>(IR)) {
const Module *M = any_cast<const Module *>(IR);
assert(M && "module should be valid for printing");
printIR(OS, M, Banner, "", Brief, ShouldPreserveUseListOrder);
printIR(OS, M, Banner, "", Brief);
return;
}
@ -229,193 +197,8 @@ void unwrapAndPrint(raw_ostream &OS, Any IR, StringRef Banner,
llvm_unreachable("Unknown wrapped IR type");
}
// Return true when this is a pass for which changes should be ignored
inline bool isIgnored(StringRef PassID) {
return isSpecialPass(PassID,
{"PassManager", "PassAdaptor", "AnalysisManagerProxy"});
}
// Return true when this is a defined function for which printing
// of changes is desired.
inline bool isInterestingFunction(const Function &F) {
return llvm::isFunctionInPrintList(F.getName());
}
// Return true when this is a pass for which printing of changes is desired.
inline bool isInterestingPass(StringRef PassID) {
if (isIgnored(PassID))
return false;
static std::unordered_set<std::string> PrintPassNames(PrintPassesList.begin(),
PrintPassesList.end());
return PrintPassNames.empty() || PrintPassNames.count(PassID.str());
}
// Return true when this is a pass on IR for which printing
// of changes is desired.
bool isInteresting(Any IR, StringRef PassID) {
if (!isInterestingPass(PassID))
return false;
if (any_isa<const Function *>(IR))
return isInterestingFunction(*any_cast<const Function *>(IR));
return true;
}
} // namespace
template <typename IRUnitT>
void ChangePrinter<IRUnitT>::saveIRBeforePass(Any IR, StringRef PassID) {
// Always need to place something on the stack because invalidated passes
// are not given the IR so it cannot be determined whether the pass was for
// something that was filtered out.
BeforeStack.emplace_back();
if (!isInteresting(IR, PassID))
return;
// Is this the initial IR?
if (InitialIR) {
InitialIR = false;
handleInitialIR(IR);
}
// Save the IR representation on the stack.
auto &Data = BeforeStack.back();
generateIRRepresentation(IR, PassID, Data);
}
template <typename IRUnitT>
void ChangePrinter<IRUnitT>::handleIRAfterPass(Any IR, StringRef PassID) {
assert(!BeforeStack.empty() && "Unexpected empty stack encountered.");
std::string Name;
// unwrapModule has inconsistent handling of names for function IRs.
if (any_isa<const Function *>(IR)) {
const Function *F = any_cast<const Function *>(IR);
Name = formatv(" (function: {0})", F->getName()).str();
} else {
if (auto UM = unwrapModule(IR))
Name = UM->second;
}
if (Name == "")
Name = " (module)";
if (isIgnored(PassID))
handleIgnored(PassID, Name);
else if (!isInteresting(IR, PassID))
handleFiltered(PassID, Name);
else {
// Get the before rep from the stack
IRUnitT &Before = BeforeStack.back();
// Create the after rep
IRUnitT After;
generateIRRepresentation(IR, PassID, After);
// was there a change in IR?
if (same(Before, After))
omitAfter(PassID, Name);
else
handleAfter(PassID, Name, Before, After, IR);
}
BeforeStack.pop_back();
}
template <typename IRUnitT>
void ChangePrinter<IRUnitT>::handleInvalidatedPass(StringRef PassID) {
assert(!BeforeStack.empty() && "Unexpected empty stack encountered.");
// Always flag it as invalidated as we cannot determine when
// a pass for a filtered function is invalidated since we do not
// get the IR in the call. Also, the output is just alternate
// forms of the banner anyway.
handleInvalidated(PassID);
BeforeStack.pop_back();
}
template <typename IRUnitT> ChangePrinter<IRUnitT>::~ChangePrinter<IRUnitT>() {
assert(BeforeStack.empty() && "Problem with Change Printer stack.");
}
IRChangePrinter::IRChangePrinter() : Out(dbgs()) {}
IRChangePrinter::~IRChangePrinter() {
}
void IRChangePrinter::registerCallbacks(PassInstrumentationCallbacks &PIC) {
if (!PrintChanged)
return;
PIC.registerBeforePassCallback([this](StringRef P, Any IR) {
saveIRBeforePass(IR, P);
return true;
});
PIC.registerAfterPassCallback(
[this](StringRef P, Any IR, const PreservedAnalyses &) {
handleIRAfterPass(IR, P);
});
PIC.registerAfterPassInvalidatedCallback(
[this](StringRef P, const PreservedAnalyses &) {
handleInvalidatedPass(P);
});
}
void IRChangePrinter::handleInitialIR(Any IR) {
StringRef Banner("*** IR Dump At Start: ***");
unwrapAndPrint(Out, IR, Banner, true,
/*Brief*/ false, /*ShouldPreserveUseListOrder*/ true);
}
void IRChangePrinter::generateIRRepresentation(Any IR, StringRef PassID,
std::string &Output) {
raw_string_ostream OS(Output);
// use the after banner for all cases so it will match
SmallString<20> Banner = formatv("*** IR Dump After {0} ***", PassID);
unwrapAndPrint(OS, IR, Banner, llvm::forcePrintModuleIR(),
/*Brief*/ false, /*ShouldPreserveUseListOrder*/ true);
OS.str();
}
void IRChangePrinter::omitAfter(StringRef PassID, std::string &Name) {
Out << formatv("*** IR Dump After {0}{1} omitted because no change ***\n",
PassID, Name);
}
void IRChangePrinter::handleAfter(StringRef PassID, std::string &Name,
const std::string &Before,
const std::string &After, Any) {
assert(After.find("*** IR Dump") == 0 && "Unexpected banner format.");
StringRef AfterRef = After;
StringRef Banner =
AfterRef.take_until([](char C) -> bool { return C == '\n'; });
Out << Banner;
// LazyCallGraph::SCC already has "(scc:..." in banner so only add
// in the name if it isn't already there.
if (Name.substr(0, 6).compare(" (scc:") != 0 && !llvm::forcePrintModuleIR())
Out << Name;
Out << After.substr(Banner.size());
}
void IRChangePrinter::handleInvalidated(StringRef PassID) {
Out << formatv("*** IR Pass {0} invalidated ***\n", PassID);
}
void IRChangePrinter::handleFiltered(StringRef PassID, std::string &Name) {
SmallString<20> Banner =
formatv("*** IR Dump After {0}{1} filtered out ***\n", PassID, Name);
Out << Banner;
}
void IRChangePrinter::handleIgnored(StringRef PassID, std::string &Name) {
Out << formatv("*** IR Pass {0}{1} ignored ***\n", PassID, Name);
}
bool IRChangePrinter::same(const std::string &Before,
const std::string &After) {
return Before.compare(After) == 0;
}
PrintIRInstrumentation::~PrintIRInstrumentation() {
assert(ModuleDescStack.empty() && "ModuleDescStack is not empty at exit");
}
@ -725,5 +508,4 @@ void StandardInstrumentations::registerCallbacks(
TimePasses.registerCallbacks(PIC);
OptNone.registerCallbacks(PIC);
PreservedCFGChecker.registerCallbacks(PIC);
PrintChangedIR.registerCallbacks(PIC);
}

View File

@ -1,109 +0,0 @@
; Simple checks of -print-changed functionality
;
; Note that (mostly) only the banners are checked.
;
; Simple functionality check.
; RUN: opt -S -print-changed -passes=instsimplify 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK_SIMPLE
;
; Check that only the passes that change the IR are printed and that the
; others (including g) are filtered out.
; RUN: opt -S -print-changed -passes=instsimplify -filter-print-funcs=f 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK_FUNC_FILTER
;
; Check that the reporting of IRs respects -print-module-scope
; RUN: opt -S -print-changed -passes=instsimplify -print-module-scope 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK_PRINT_MOD_SCOPE
;
; Check that the reporting of IRs respects -print-module-scope
; RUN: opt -S -print-changed -passes=instsimplify -filter-print-funcs=f -print-module-scope 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK_FUNC_FILTER_MOD_SCOPE
;
; Check that reporting of multiple functions happens
; RUN: opt -S -print-changed -passes=instsimplify -filter-print-funcs="f,g" 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK_FILTER_MULT_FUNC
;
; Check that the reporting of IRs respects -filter-passes
; RUN: opt -S -print-changed -passes="instsimplify,no-op-function" -filter-passes="NoOpFunctionPass" 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK_FILTER_PASSES
;
; Check that the reporting of IRs respects -filter-passes with multiple passes
; RUN: opt -S -print-changed -passes="instsimplify,no-op-function" -filter-passes="NoOpFunctionPass,InstSimplifyPass" 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK_FILTER_MULT_PASSES
;
; Check that the reporting of IRs respects both -filter-passes and -filter-print-funcs
; RUN: opt -S -print-changed -passes="instsimplify,no-op-function" -filter-passes="NoOpFunctionPass,InstSimplifyPass" -filter-print-funcs=f 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK_FILTER_FUNC_PASSES
;
; Check that the reporting of IRs respects -filter-passes, -filter-print-funcs and -print-module-scope
; RUN: opt -S -print-changed -passes="instsimplify,no-op-function" -filter-passes="NoOpFunctionPass,InstSimplifyPass" -filter-print-funcs=f -print-module-scope 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK_FILTER_FUNC_PASSES_MOD_SCOPE
;
; Check that repeated passes that change the IR are printed and that the
; others (including g) are filtered out. Note that the second time
; instsimplify is run on f, it does not change the IR
; RUN: opt -S -print-changed -passes="instsimplify,instsimplify" -filter-print-funcs=f 2>&1 -o /dev/null < %s | FileCheck %s --check-prefix=CHECK_MULT_PASSES_FILTER_FUNC
define i32 @g() {
entry:
%a = add i32 2, 3
ret i32 %a
}
define i32 @f() {
entry:
%a = add i32 2, 3
ret i32 %a
}
; CHECK_SIMPLE: *** IR Dump At Start: ***
; CHECK_SIMPLE: ; ModuleID = '<stdin>'
; CHECK_SIMPLE: *** IR Dump After VerifierPass (module) omitted because no change ***
; CHECK_SIMPLE: *** IR Dump After InstSimplifyPass *** (function: g)
; CHECK_SIMPLE: *** IR Pass PassManager<llvm::Function> (function: g) ignored ***
; CHECK_SIMPLE: *** IR Dump After InstSimplifyPass *** (function: f)
; CHECK_SIMPLE: *** IR Pass PassManager<llvm::Function> (function: f) ignored ***
; CHECK_SIMPLE: *** IR Pass ModuleToFunctionPassAdaptor<llvm::PassManager<llvm::Function>{{ ?}}> (module) ignored ***
; CHECK_SIMPLE: *** IR Dump After VerifierPass (module) omitted because no change ***
; CHECK_SIMPLE: *** IR Dump After PrintModulePass (module) omitted because no change ***
; CHECK_FUNC_FILTER: *** IR Dump At Start: ***
; CHECK_FUNC_FILTER: *** IR Dump After InstSimplifyPass (function: g) filtered out ***
; CHECK_FUNC_FILTER: *** IR Dump After InstSimplifyPass *** (function: f)
; CHECK_PRINT_MOD_SCOPE: *** IR Dump At Start: ***
; CHECK_PRINT_MOD_SCOPE: *** IR Dump After InstSimplifyPass *** (function: g)
; CHECK_PRINT_MOD_SCOPE: ModuleID = '<stdin>'
; CHECK_PRINT_MOD_SCOPE: *** IR Dump After InstSimplifyPass *** (function: f)
; CHECK_PRINT_MOD_SCOPE: ModuleID = '<stdin>'
; CHECK_FUNC_FILTER_MOD_SCOPE: *** IR Dump At Start: ***
; CHECK_FUNC_FILTER_MOD_SCOPE: *** IR Dump After InstSimplifyPass (function: g) filtered out ***
; CHECK_FUNC_FILTER_MOD_SCOPE: *** IR Dump After InstSimplifyPass *** (function: f)
; CHECK_FUNC_FILTER_MOD_SCOPE: ModuleID = '<stdin>'
; CHECK_FILTER_MULT_FUNC: *** IR Dump At Start: ***
; CHECK_FILTER_MULT_FUNC: *** IR Dump After InstSimplifyPass *** (function: g)
; CHECK_FILTER_MULT_FUNC: *** IR Dump After InstSimplifyPass *** (function: f)
; CHECK_FILTER_PASSES: *** IR Dump After InstSimplifyPass (function: g) filtered out ***
; CHECK_FILTER_PASSES: *** IR Dump At Start: *** (function: g)
; CHECK_FILTER_PASSES: *** IR Dump After NoOpFunctionPass (function: g) omitted because no change ***
; CHECK_FILTER_PASSES: *** IR Dump After InstSimplifyPass (function: f) filtered out ***
; CHECK_FILTER_PASSES: *** IR Dump After NoOpFunctionPass (function: f) omitted because no change ***
; CHECK_FILTER_MULT_PASSES: *** IR Dump At Start: *** (function: g)
; CHECK_FILTER_MULT_PASSES: *** IR Dump After InstSimplifyPass *** (function: g)
; CHECK_FILTER_MULT_PASSES: *** IR Dump After NoOpFunctionPass (function: g) omitted because no change ***
; CHECK_FILTER_MULT_PASSES: *** IR Dump After InstSimplifyPass *** (function: f)
; CHECK_FILTER_MULT_PASSES: *** IR Dump After NoOpFunctionPass (function: f) omitted because no change ***
; CHECK_FILTER_FUNC_PASSES: *** IR Dump After InstSimplifyPass (function: g) filtered out ***
; CHECK_FILTER_FUNC_PASSES: *** IR Dump After NoOpFunctionPass (function: g) filtered out ***
; CHECK_FILTER_FUNC_PASSES: *** IR Dump At Start: *** (function: f)
; CHECK_FILTER_FUNC_PASSES: *** IR Dump After InstSimplifyPass *** (function: f)
; CHECK_FILTER_FUNC_PASSES: *** IR Dump After NoOpFunctionPass (function: f) omitted because no change ***
; CHECK_FILTER_FUNC_PASSES_MOD_SCOPE: *** IR Dump After InstSimplifyPass (function: g) filtered out ***
; CHECK_FILTER_FUNC_PASSES_MOD_SCOPE: *** IR Dump After NoOpFunctionPass (function: g) filtered out ***
; CHECK_FILTER_FUNC_PASSES_MOD_SCOPE: *** IR Dump At Start: *** (function: f)
; CHECK_FILTER_FUNC_PASSES_MOD_SCOPE: *** IR Dump After InstSimplifyPass *** (function: f)
; CHECK_FILTER_FUNC_PASSES_MOD_SCOPE: ModuleID = '<stdin>'
; CHECK_FILTER_FUNC_PASSES_MOD_SCOPE: *** IR Dump After NoOpFunctionPass (function: f) omitted because no change ***
; CHECK_MULT_PASSES_FILTER_FUNC: *** IR Dump At Start: ***
; CHECK_MULT_PASSES_FILTER_FUNC: *** IR Dump After InstSimplifyPass (function: g) filtered out ***
; CHECK_MULT_PASSES_FILTER_FUNC: *** IR Dump After InstSimplifyPass (function: g) filtered out ***
; CHECK_MULT_PASSES_FILTER_FUNC: *** IR Dump After InstSimplifyPass *** (function: f)
; CHECK_MULT_PASSES_FILTER_FUNC: *** IR Dump After InstSimplifyPass (function: f) omitted because no change ***