mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[NewPM] Support --print-before/after in NPM
This changes --print-before/after to be a list of strings rather than legacy passes. (this also has the effect of not showing the entire list of passes in --help-hidden after --print-before/after, which IMO is great for making it less verbose). Currently PrintIRInstrumentation passes the class name rather than pass name to llvm::shouldPrintBeforePass(), meaning llvm::shouldPrintBeforePass() never functions as intended in the NPM. There is no easy way of converting class names to pass names outside of within an instance of PassBuilder. This adds a map of pass class names to their short names in PassRegistry.def within PassInstrumentationCallbacks. It is populated inside the constructor of PassBuilder, which takes a PassInstrumentationCallbacks. Add a pointer to PassInstrumentationCallbacks inside PrintIRInstrumentation and use the newly created map. This is a bit hacky, but I can't think of a better way since the short id to class name only exists within PassRegistry.def. This also doesn't handle passes not in PassRegistry.def but rather added via PassBuilder::registerPipelineParsingCallback(). llvm/test/CodeGen/Generic/print-after.ll doesn't seem very useful now with this change. Reviewed By: ychen, jamieschmeiser Differential Revision: https://reviews.llvm.org/D87216
This commit is contained in:
parent
2eefcbd100
commit
5bc5d5ec44
@ -45,22 +45,6 @@ void printLLVMNameWithoutPrefix(raw_ostream &OS, StringRef Name);
|
|||||||
/// Return true if a pass is for IR printing.
|
/// Return true if a pass is for IR printing.
|
||||||
bool isIRPrintingPass(Pass *P);
|
bool isIRPrintingPass(Pass *P);
|
||||||
|
|
||||||
/// isFunctionInPrintList - returns true if a function should be printed via
|
|
||||||
// debugging options like -print-after-all/-print-before-all.
|
|
||||||
// Tells if the function IR should be printed by PrinterPass.
|
|
||||||
extern bool isFunctionInPrintList(StringRef FunctionName);
|
|
||||||
|
|
||||||
/// forcePrintModuleIR - returns true if IR printing passes should
|
|
||||||
// be printing module IR (even for local-pass printers e.g. function-pass)
|
|
||||||
// to provide more context, as enabled by debugging option -print-module-scope
|
|
||||||
// Tells if IR printer should be printing module IR
|
|
||||||
extern bool forcePrintModuleIR();
|
|
||||||
|
|
||||||
extern bool shouldPrintBeforePass();
|
|
||||||
extern bool shouldPrintBeforePass(StringRef);
|
|
||||||
extern bool shouldPrintAfterPass();
|
|
||||||
extern bool shouldPrintAfterPass(StringRef);
|
|
||||||
|
|
||||||
/// Pass for printing a Module as LLVM's text IR assembly.
|
/// Pass for printing a Module as LLVM's text IR assembly.
|
||||||
///
|
///
|
||||||
/// Note: This pass is for use with the new pass manager. Use the create...Pass
|
/// Note: This pass is for use with the new pass manager. Use the create...Pass
|
||||||
@ -95,6 +79,6 @@ public:
|
|||||||
static bool isRequired() { return true; }
|
static bool isRequired() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // namespace llvm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include "llvm/ADT/Any.h"
|
#include "llvm/ADT/Any.h"
|
||||||
#include "llvm/ADT/FunctionExtras.h"
|
#include "llvm/ADT/FunctionExtras.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
#include "llvm/ADT/StringMap.h"
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -122,6 +123,13 @@ public:
|
|||||||
AfterAnalysisCallbacks.emplace_back(std::move(C));
|
AfterAnalysisCallbacks.emplace_back(std::move(C));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a class name to pass name mapping for use by pass instrumentation.
|
||||||
|
void addClassToPassName(StringRef ClassName, StringRef PassName);
|
||||||
|
/// Get the pass name for a given pass class name.
|
||||||
|
StringRef getPassNameForClassName(StringRef ClassName);
|
||||||
|
/// Whether or not the class to pass name map contains the pass name.
|
||||||
|
bool hasPassName(StringRef PassName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class PassInstrumentation;
|
friend class PassInstrumentation;
|
||||||
|
|
||||||
@ -146,6 +154,8 @@ private:
|
|||||||
/// These are run on analyses that have been run.
|
/// These are run on analyses that have been run.
|
||||||
SmallVector<llvm::unique_function<AfterAnalysisFunc>, 4>
|
SmallVector<llvm::unique_function<AfterAnalysisFunc>, 4>
|
||||||
AfterAnalysisCallbacks;
|
AfterAnalysisCallbacks;
|
||||||
|
|
||||||
|
StringMap<std::string> ClassToPassName;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This class provides instrumentation entry points for the Pass Manager,
|
/// This class provides instrumentation entry points for the Pass Manager,
|
||||||
|
44
include/llvm/IR/PrintPasses.h
Normal file
44
include/llvm/IR/PrintPasses.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//===- PrintPasses.h - Determining whether/when to print IR ---------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_IR_PRINTPASSES_H
|
||||||
|
#define LLVM_IR_PRINTPASSES_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
// Returns true if printing before/after some pass is enabled, whether all
|
||||||
|
// passes or a specific pass.
|
||||||
|
bool shouldPrintBeforeSomePass();
|
||||||
|
bool shouldPrintAfterSomePass();
|
||||||
|
|
||||||
|
// Returns true if we should print before/after a specific pass. The argument
|
||||||
|
// should be the pass ID, e.g. "instcombine".
|
||||||
|
bool shouldPrintBeforePass(StringRef PassID);
|
||||||
|
bool shouldPrintAfterPass(StringRef PassID);
|
||||||
|
|
||||||
|
// Returns true if we should print before/after all passes.
|
||||||
|
bool shouldPrintBeforeAll();
|
||||||
|
bool shouldPrintAfterAll();
|
||||||
|
|
||||||
|
// The list of passes to print before/after, if we only want to print
|
||||||
|
// before/after specific passes.
|
||||||
|
std::vector<std::string> printBeforePasses();
|
||||||
|
std::vector<std::string> printAfterPasses();
|
||||||
|
|
||||||
|
// Returns true if we should always print the entire module.
|
||||||
|
bool forcePrintModuleIR();
|
||||||
|
|
||||||
|
// Returns true if we should print the function.
|
||||||
|
bool isFunctionInPrintList(StringRef FunctionName);
|
||||||
|
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif // LLVM_IR_PRINTPASSES_H
|
@ -19,7 +19,6 @@
|
|||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/IR/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
#include "llvm/IR/OptBisect.h"
|
#include "llvm/IR/OptBisect.h"
|
||||||
#include "llvm/IR/PassInstrumentation.h"
|
|
||||||
#include "llvm/IR/PassTimingInfo.h"
|
#include "llvm/IR/PassTimingInfo.h"
|
||||||
#include "llvm/IR/ValueHandle.h"
|
#include "llvm/IR/ValueHandle.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
@ -31,6 +30,7 @@ namespace llvm {
|
|||||||
|
|
||||||
class Module;
|
class Module;
|
||||||
class Function;
|
class Function;
|
||||||
|
class PassInstrumentationCallbacks;
|
||||||
|
|
||||||
/// Instrumentation to print IR before/after passes.
|
/// Instrumentation to print IR before/after passes.
|
||||||
///
|
///
|
||||||
@ -47,11 +47,15 @@ private:
|
|||||||
void printAfterPass(StringRef PassID, Any IR);
|
void printAfterPass(StringRef PassID, Any IR);
|
||||||
void printAfterPassInvalidated(StringRef PassID);
|
void printAfterPassInvalidated(StringRef PassID);
|
||||||
|
|
||||||
|
bool shouldPrintBeforePass(StringRef PassID);
|
||||||
|
bool shouldPrintAfterPass(StringRef PassID);
|
||||||
|
|
||||||
using PrintModuleDesc = std::tuple<const Module *, std::string, StringRef>;
|
using PrintModuleDesc = std::tuple<const Module *, std::string, StringRef>;
|
||||||
|
|
||||||
void pushModuleDesc(StringRef PassID, Any IR);
|
void pushModuleDesc(StringRef PassID, Any IR);
|
||||||
PrintModuleDesc popModuleDesc(StringRef PassID);
|
PrintModuleDesc popModuleDesc(StringRef PassID);
|
||||||
|
|
||||||
|
PassInstrumentationCallbacks *PIC;
|
||||||
/// Stack of Module description, enough to print the module after a given
|
/// Stack of Module description, enough to print the module after a given
|
||||||
/// pass.
|
/// pass.
|
||||||
SmallVector<PrintModuleDesc, 2> ModuleDescStack;
|
SmallVector<PrintModuleDesc, 2> ModuleDescStack;
|
||||||
|
@ -21,13 +21,13 @@
|
|||||||
#include "llvm/Analysis/CallGraph.h"
|
#include "llvm/Analysis/CallGraph.h"
|
||||||
#include "llvm/IR/AbstractCallSite.h"
|
#include "llvm/IR/AbstractCallSite.h"
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/IR/IRPrintingPasses.h"
|
|
||||||
#include "llvm/IR/Intrinsics.h"
|
#include "llvm/IR/Intrinsics.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
#include "llvm/IR/LegacyPassManagers.h"
|
#include "llvm/IR/LegacyPassManagers.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/IR/OptBisect.h"
|
#include "llvm/IR/OptBisect.h"
|
||||||
#include "llvm/IR/PassTimingInfo.h"
|
#include "llvm/IR/PassTimingInfo.h"
|
||||||
|
#include "llvm/IR/PrintPasses.h"
|
||||||
#include "llvm/IR/StructuralHash.h"
|
#include "llvm/IR/StructuralHash.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
#include "llvm/IR/Metadata.h"
|
#include "llvm/IR/Metadata.h"
|
||||||
#include "llvm/IR/PassManager.h"
|
#include "llvm/IR/PassManager.h"
|
||||||
|
#include "llvm/IR/PrintPasses.h"
|
||||||
#include "llvm/InitializePasses.h"
|
#include "llvm/InitializePasses.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
#include "llvm/Analysis/LoopPass.h"
|
#include "llvm/Analysis/LoopPass.h"
|
||||||
#include "llvm/Analysis/LoopAnalysisManager.h"
|
#include "llvm/Analysis/LoopAnalysisManager.h"
|
||||||
#include "llvm/IR/Dominators.h"
|
#include "llvm/IR/Dominators.h"
|
||||||
#include "llvm/IR/IRPrintingPasses.h"
|
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
#include "llvm/IR/OptBisect.h"
|
#include "llvm/IR/OptBisect.h"
|
||||||
#include "llvm/IR/PassManager.h"
|
#include "llvm/IR/PassManager.h"
|
||||||
#include "llvm/IR/PassTimingInfo.h"
|
#include "llvm/IR/PassTimingInfo.h"
|
||||||
|
#include "llvm/IR/PrintPasses.h"
|
||||||
#include "llvm/IR/StructuralHash.h"
|
#include "llvm/IR/StructuralHash.h"
|
||||||
#include "llvm/InitializePasses.h"
|
#include "llvm/InitializePasses.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
#include "llvm/CodeGen/Passes.h"
|
#include "llvm/CodeGen/Passes.h"
|
||||||
#include "llvm/CodeGen/SlotIndexes.h"
|
#include "llvm/CodeGen/SlotIndexes.h"
|
||||||
#include "llvm/IR/IRPrintingPasses.h"
|
#include "llvm/IR/PrintPasses.h"
|
||||||
#include "llvm/InitializePasses.h"
|
#include "llvm/InitializePasses.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
@ -44,7 +44,7 @@ struct MachineFunctionPrinterPass : public MachineFunctionPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool runOnMachineFunction(MachineFunction &MF) override {
|
bool runOnMachineFunction(MachineFunction &MF) override {
|
||||||
if (!llvm::isFunctionInPrintList(MF.getName()))
|
if (!isFunctionInPrintList(MF.getName()))
|
||||||
return false;
|
return false;
|
||||||
OS << "# " << Banner << ":\n";
|
OS << "# " << Banner << ":\n";
|
||||||
MF.print(OS, getAnalysisIfAvailable<SlotIndexes>());
|
MF.print(OS, getAnalysisIfAvailable<SlotIndexes>());
|
||||||
|
@ -44,6 +44,7 @@ add_llvm_component_library(LLVMCore
|
|||||||
PassManager.cpp
|
PassManager.cpp
|
||||||
PassRegistry.cpp
|
PassRegistry.cpp
|
||||||
PassTimingInfo.cpp
|
PassTimingInfo.cpp
|
||||||
|
PrintPasses.cpp
|
||||||
SafepointIRVerifier.cpp
|
SafepointIRVerifier.cpp
|
||||||
ProfileSummary.cpp
|
ProfileSummary.cpp
|
||||||
Statepoint.cpp
|
Statepoint.cpp
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/IR/PrintPasses.h"
|
||||||
#include "llvm/InitializePasses.h"
|
#include "llvm/InitializePasses.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "llvm/IR/LegacyPassNameParser.h"
|
#include "llvm/IR/LegacyPassNameParser.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/IR/PassTimingInfo.h"
|
#include "llvm/IR/PassTimingInfo.h"
|
||||||
|
#include "llvm/IR/PrintPasses.h"
|
||||||
#include "llvm/IR/StructuralHash.h"
|
#include "llvm/IR/StructuralHash.h"
|
||||||
#include "llvm/Support/Chrono.h"
|
#include "llvm/Support/Chrono.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
@ -49,7 +50,7 @@ namespace {
|
|||||||
enum PassDebugLevel {
|
enum PassDebugLevel {
|
||||||
Disabled, Arguments, Structure, Executions, Details
|
Disabled, Arguments, Structure, Executions, Details
|
||||||
};
|
};
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
static cl::opt<enum PassDebugLevel>
|
static cl::opt<enum PassDebugLevel>
|
||||||
PassDebugging("debug-pass", cl::Hidden,
|
PassDebugging("debug-pass", cl::Hidden,
|
||||||
@ -61,80 +62,6 @@ PassDebugging("debug-pass", cl::Hidden,
|
|||||||
clEnumVal(Executions, "print pass name before it is executed"),
|
clEnumVal(Executions, "print pass name before it is executed"),
|
||||||
clEnumVal(Details , "print pass details when it is executed")));
|
clEnumVal(Details , "print pass details when it is executed")));
|
||||||
|
|
||||||
namespace {
|
|
||||||
typedef llvm::cl::list<const llvm::PassInfo *, bool, PassNameParser>
|
|
||||||
PassOptionList;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print IR out before/after specified passes.
|
|
||||||
static PassOptionList
|
|
||||||
PrintBefore("print-before",
|
|
||||||
llvm::cl::desc("Print IR before specified passes"),
|
|
||||||
cl::Hidden);
|
|
||||||
|
|
||||||
static PassOptionList
|
|
||||||
PrintAfter("print-after",
|
|
||||||
llvm::cl::desc("Print IR after specified passes"),
|
|
||||||
cl::Hidden);
|
|
||||||
|
|
||||||
static cl::opt<bool> PrintBeforeAll("print-before-all",
|
|
||||||
llvm::cl::desc("Print IR before each pass"),
|
|
||||||
cl::init(false), cl::Hidden);
|
|
||||||
static cl::opt<bool> PrintAfterAll("print-after-all",
|
|
||||||
llvm::cl::desc("Print IR after each pass"),
|
|
||||||
cl::init(false), cl::Hidden);
|
|
||||||
|
|
||||||
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"),
|
|
||||||
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"),
|
|
||||||
cl::CommaSeparated, cl::Hidden);
|
|
||||||
|
|
||||||
/// This is a helper to determine whether to print IR before or
|
|
||||||
/// after a pass.
|
|
||||||
|
|
||||||
bool llvm::shouldPrintBeforePass() {
|
|
||||||
return PrintBeforeAll || !PrintBefore.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool llvm::shouldPrintAfterPass() {
|
|
||||||
return PrintAfterAll || !PrintAfter.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ShouldPrintBeforeOrAfterPass(StringRef PassID,
|
|
||||||
PassOptionList &PassesToPrint) {
|
|
||||||
for (auto *PassInf : PassesToPrint) {
|
|
||||||
if (PassInf)
|
|
||||||
if (PassInf->getPassArgument() == PassID) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool llvm::shouldPrintBeforePass(StringRef PassID) {
|
|
||||||
return PrintBeforeAll || ShouldPrintBeforeOrAfterPass(PassID, PrintBefore);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool llvm::shouldPrintAfterPass(StringRef PassID) {
|
|
||||||
return PrintAfterAll || ShouldPrintBeforeOrAfterPass(PassID, PrintAfter);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
|
|
||||||
|
|
||||||
bool llvm::isFunctionInPrintList(StringRef FunctionName) {
|
|
||||||
static std::unordered_set<std::string> PrintFuncNames(PrintFuncsList.begin(),
|
|
||||||
PrintFuncsList.end());
|
|
||||||
return PrintFuncNames.empty() ||
|
|
||||||
PrintFuncNames.count(std::string(FunctionName));
|
|
||||||
}
|
|
||||||
/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
|
/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
|
||||||
/// or higher is specified.
|
/// or higher is specified.
|
||||||
bool PMDataManager::isPassDebuggingExecutionsOrMore() const {
|
bool PMDataManager::isPassDebuggingExecutionsOrMore() const {
|
||||||
|
@ -17,6 +17,24 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
void PassInstrumentationCallbacks::addClassToPassName(StringRef ClassName,
|
||||||
|
StringRef PassName) {
|
||||||
|
ClassToPassName[ClassName] = PassName.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PassInstrumentationCallbacks::hasPassName(StringRef PassName) {
|
||||||
|
for (const auto &E : ClassToPassName) {
|
||||||
|
if (E.getValue() == PassName)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRef
|
||||||
|
PassInstrumentationCallbacks::getPassNameForClassName(StringRef ClassName) {
|
||||||
|
return ClassToPassName[ClassName];
|
||||||
|
}
|
||||||
|
|
||||||
AnalysisKey PassInstrumentationAnalysis::Key;
|
AnalysisKey PassInstrumentationAnalysis::Key;
|
||||||
|
|
||||||
bool isSpecialPass(StringRef PassID, const std::vector<StringRef> &Specials) {
|
bool isSpecialPass(StringRef PassID, const std::vector<StringRef> &Specials) {
|
||||||
|
92
lib/IR/PrintPasses.cpp
Normal file
92
lib/IR/PrintPasses.cpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
//===- PrintPasses.cpp ----------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/IR/PrintPasses.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
// Print IR out before/after specified passes.
|
||||||
|
static cl::list<std::string>
|
||||||
|
PrintBefore("print-before",
|
||||||
|
llvm::cl::desc("Print IR before specified passes"),
|
||||||
|
cl::CommaSeparated, cl::Hidden);
|
||||||
|
|
||||||
|
static cl::list<std::string>
|
||||||
|
PrintAfter("print-after", llvm::cl::desc("Print IR after specified passes"),
|
||||||
|
cl::CommaSeparated, cl::Hidden);
|
||||||
|
|
||||||
|
static cl::opt<bool> PrintBeforeAll("print-before-all",
|
||||||
|
llvm::cl::desc("Print IR before each pass"),
|
||||||
|
cl::init(false), cl::Hidden);
|
||||||
|
static cl::opt<bool> PrintAfterAll("print-after-all",
|
||||||
|
llvm::cl::desc("Print IR after each pass"),
|
||||||
|
cl::init(false), cl::Hidden);
|
||||||
|
|
||||||
|
static cl::opt<bool>
|
||||||
|
PrintModuleScope("print-module-scope",
|
||||||
|
cl::desc("When printing IR for print-[before|after]{-all} "
|
||||||
|
"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] "
|
||||||
|
"options"),
|
||||||
|
cl::CommaSeparated, cl::Hidden);
|
||||||
|
|
||||||
|
/// This is a helper to determine whether to print IR before or
|
||||||
|
/// after a pass.
|
||||||
|
|
||||||
|
bool llvm::shouldPrintBeforeSomePass() {
|
||||||
|
return PrintBeforeAll || !PrintBefore.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool llvm::shouldPrintAfterSomePass() {
|
||||||
|
return PrintAfterAll || !PrintAfter.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool shouldPrintBeforeOrAfterPass(StringRef PassID,
|
||||||
|
ArrayRef<std::string> PassesToPrint) {
|
||||||
|
for (auto &Pass : PassesToPrint) {
|
||||||
|
if (Pass == PassID)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool llvm::shouldPrintBeforeAll() { return PrintBeforeAll; }
|
||||||
|
|
||||||
|
bool llvm::shouldPrintAfterAll() { return PrintAfterAll; }
|
||||||
|
|
||||||
|
bool llvm::shouldPrintBeforePass(StringRef PassID) {
|
||||||
|
return PrintBeforeAll || shouldPrintBeforeOrAfterPass(PassID, PrintBefore);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool llvm::shouldPrintAfterPass(StringRef PassID) {
|
||||||
|
return PrintAfterAll || shouldPrintBeforeOrAfterPass(PassID, PrintAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> llvm::printBeforePasses() {
|
||||||
|
return std::vector<std::string>(PrintBefore);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> llvm::printAfterPasses() {
|
||||||
|
return std::vector<std::string>(PrintAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
|
||||||
|
|
||||||
|
bool llvm::isFunctionInPrintList(StringRef FunctionName) {
|
||||||
|
static std::unordered_set<std::string> PrintFuncNames(PrintFuncsList.begin(),
|
||||||
|
PrintFuncsList.end());
|
||||||
|
return PrintFuncNames.empty() ||
|
||||||
|
PrintFuncNames.count(std::string(FunctionName));
|
||||||
|
}
|
@ -70,10 +70,12 @@
|
|||||||
#include "llvm/IR/Dominators.h"
|
#include "llvm/IR/Dominators.h"
|
||||||
#include "llvm/IR/IRPrintingPasses.h"
|
#include "llvm/IR/IRPrintingPasses.h"
|
||||||
#include "llvm/IR/PassManager.h"
|
#include "llvm/IR/PassManager.h"
|
||||||
|
#include "llvm/IR/PrintPasses.h"
|
||||||
#include "llvm/IR/SafepointIRVerifier.h"
|
#include "llvm/IR/SafepointIRVerifier.h"
|
||||||
#include "llvm/IR/Verifier.h"
|
#include "llvm/IR/Verifier.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/FormatVariadic.h"
|
#include "llvm/Support/FormatVariadic.h"
|
||||||
#include "llvm/Support/Regex.h"
|
#include "llvm/Support/Regex.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
@ -415,6 +417,16 @@ AnalysisKey NoOpCGSCCAnalysis::Key;
|
|||||||
AnalysisKey NoOpFunctionAnalysis::Key;
|
AnalysisKey NoOpFunctionAnalysis::Key;
|
||||||
AnalysisKey NoOpLoopAnalysis::Key;
|
AnalysisKey NoOpLoopAnalysis::Key;
|
||||||
|
|
||||||
|
/// Whether or not we should populate a PassInstrumentationCallbacks's class to
|
||||||
|
/// pass name map.
|
||||||
|
///
|
||||||
|
/// This is for optimization purposes so we don't populate it if we never use
|
||||||
|
/// it. This should be updated if new pass instrumentation wants to use the map.
|
||||||
|
/// We currently only use this for --print-before/after.
|
||||||
|
bool shouldPopulateClassToPassNames() {
|
||||||
|
return !printBeforePasses().empty() || !printAfterPasses().empty();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
PassBuilder::PassBuilder(bool DebugLogging, TargetMachine *TM,
|
PassBuilder::PassBuilder(bool DebugLogging, TargetMachine *TM,
|
||||||
@ -423,6 +435,33 @@ PassBuilder::PassBuilder(bool DebugLogging, TargetMachine *TM,
|
|||||||
: DebugLogging(DebugLogging), TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) {
|
: DebugLogging(DebugLogging), TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) {
|
||||||
if (TM)
|
if (TM)
|
||||||
TM->registerPassBuilderCallbacks(*this, DebugLogging);
|
TM->registerPassBuilderCallbacks(*this, DebugLogging);
|
||||||
|
if (PIC && shouldPopulateClassToPassNames()) {
|
||||||
|
#define MODULE_PASS(NAME, CREATE_PASS) \
|
||||||
|
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
|
||||||
|
#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
|
||||||
|
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
|
||||||
|
#define FUNCTION_PASS(NAME, CREATE_PASS) \
|
||||||
|
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
|
||||||
|
#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
|
||||||
|
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
|
||||||
|
#define LOOP_PASS(NAME, CREATE_PASS) \
|
||||||
|
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
|
||||||
|
#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
|
||||||
|
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
|
||||||
|
#define CGSCC_PASS(NAME, CREATE_PASS) \
|
||||||
|
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
|
||||||
|
#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
|
||||||
|
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
|
||||||
|
#include "PassRegistry.def"
|
||||||
|
for (const auto &P : printBeforePasses()) {
|
||||||
|
if (!PIC->hasPassName(P))
|
||||||
|
report_fatal_error("unrecognized pass name: " + P);
|
||||||
|
}
|
||||||
|
for (const auto &P : printAfterPasses()) {
|
||||||
|
if (!PIC->hasPassName(P))
|
||||||
|
report_fatal_error("unrecognized pass name: " + P);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PassBuilder::invokePeepholeEPCallbacks(
|
void PassBuilder::invokePeepholeEPCallbacks(
|
||||||
|
@ -15,13 +15,14 @@
|
|||||||
#include "llvm/Passes/StandardInstrumentations.h"
|
#include "llvm/Passes/StandardInstrumentations.h"
|
||||||
#include "llvm/ADT/Any.h"
|
#include "llvm/ADT/Any.h"
|
||||||
#include "llvm/ADT/Optional.h"
|
#include "llvm/ADT/Optional.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/Analysis/CallGraphSCCPass.h"
|
#include "llvm/Analysis/CallGraphSCCPass.h"
|
||||||
#include "llvm/Analysis/LazyCallGraph.h"
|
#include "llvm/Analysis/LazyCallGraph.h"
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
#include "llvm/IR/IRPrintingPasses.h"
|
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/IR/PassInstrumentation.h"
|
#include "llvm/IR/PassInstrumentation.h"
|
||||||
|
#include "llvm/IR/PrintPasses.h"
|
||||||
#include "llvm/IR/Verifier.h"
|
#include "llvm/IR/Verifier.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
@ -94,7 +95,7 @@ unwrapModule(Any IR, bool Force = false) {
|
|||||||
|
|
||||||
if (any_isa<const Function *>(IR)) {
|
if (any_isa<const Function *>(IR)) {
|
||||||
const Function *F = any_cast<const Function *>(IR);
|
const Function *F = any_cast<const Function *>(IR);
|
||||||
if (!Force && !llvm::isFunctionInPrintList(F->getName()))
|
if (!Force && !isFunctionInPrintList(F->getName()))
|
||||||
return None;
|
return None;
|
||||||
|
|
||||||
const Module *M = F->getParent();
|
const Module *M = F->getParent();
|
||||||
@ -136,7 +137,7 @@ void printIR(raw_ostream &OS, const Function *F, StringRef Banner,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!llvm::isFunctionInPrintList(F->getName()))
|
if (!isFunctionInPrintList(F->getName()))
|
||||||
return;
|
return;
|
||||||
OS << Banner << Extra << "\n" << static_cast<const Value &>(*F);
|
OS << Banner << Extra << "\n" << static_cast<const Value &>(*F);
|
||||||
}
|
}
|
||||||
@ -149,7 +150,7 @@ void printIR(raw_ostream &OS, const Module *M, StringRef Banner,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (llvm::isFunctionInPrintList("*") || llvm::forcePrintModuleIR()) {
|
if (isFunctionInPrintList("*") || forcePrintModuleIR()) {
|
||||||
OS << Banner << Extra << "\n";
|
OS << Banner << Extra << "\n";
|
||||||
M->print(OS, nullptr, ShouldPreserveUseListOrder);
|
M->print(OS, nullptr, ShouldPreserveUseListOrder);
|
||||||
} else {
|
} else {
|
||||||
@ -169,7 +170,7 @@ void printIR(raw_ostream &OS, const LazyCallGraph::SCC *C, StringRef Banner,
|
|||||||
bool BannerPrinted = false;
|
bool BannerPrinted = false;
|
||||||
for (const LazyCallGraph::Node &N : *C) {
|
for (const LazyCallGraph::Node &N : *C) {
|
||||||
const Function &F = N.getFunction();
|
const Function &F = N.getFunction();
|
||||||
if (!F.isDeclaration() && llvm::isFunctionInPrintList(F.getName())) {
|
if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
|
||||||
if (!BannerPrinted) {
|
if (!BannerPrinted) {
|
||||||
OS << Banner << Extra << "\n";
|
OS << Banner << Extra << "\n";
|
||||||
BannerPrinted = true;
|
BannerPrinted = true;
|
||||||
@ -187,9 +188,9 @@ void printIR(raw_ostream &OS, const Loop *L, StringRef Banner,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Function *F = L->getHeader()->getParent();
|
const Function *F = L->getHeader()->getParent();
|
||||||
if (!llvm::isFunctionInPrintList(F->getName()))
|
if (!isFunctionInPrintList(F->getName()))
|
||||||
return;
|
return;
|
||||||
llvm::printLoop(const_cast<Loop &>(*L), OS, std::string(Banner));
|
printLoop(const_cast<Loop &>(*L), OS, std::string(Banner));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into
|
/// Generic IR-printing helper that unpacks a pointer to IRUnit wrapped into
|
||||||
@ -250,7 +251,7 @@ ChangeReporter<IRUnitT>::~ChangeReporter<IRUnitT>() {
|
|||||||
|
|
||||||
template <typename IRUnitT>
|
template <typename IRUnitT>
|
||||||
bool ChangeReporter<IRUnitT>::isInterestingFunction(const Function &F) {
|
bool ChangeReporter<IRUnitT>::isInterestingFunction(const Function &F) {
|
||||||
return llvm::isFunctionInPrintList(F.getName());
|
return isFunctionInPrintList(F.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename IRUnitT>
|
template <typename IRUnitT>
|
||||||
@ -430,7 +431,7 @@ void IRChangedPrinter::handleAfter(StringRef PassID, std::string &Name,
|
|||||||
Out << "*** IR Dump Before" << Banner.substr(17);
|
Out << "*** IR Dump Before" << Banner.substr(17);
|
||||||
// LazyCallGraph::SCC already has "(scc:..." in banner so only add
|
// LazyCallGraph::SCC already has "(scc:..." in banner so only add
|
||||||
// in the name if it isn't already there.
|
// in the name if it isn't already there.
|
||||||
if (Name.substr(0, 6) != " (scc:" && !llvm::forcePrintModuleIR())
|
if (Name.substr(0, 6) != " (scc:" && !forcePrintModuleIR())
|
||||||
Out << Name;
|
Out << Name;
|
||||||
|
|
||||||
StringRef BeforeRef = Before;
|
StringRef BeforeRef = Before;
|
||||||
@ -441,7 +442,7 @@ void IRChangedPrinter::handleAfter(StringRef PassID, std::string &Name,
|
|||||||
|
|
||||||
// LazyCallGraph::SCC already has "(scc:..." in banner so only add
|
// LazyCallGraph::SCC already has "(scc:..." in banner so only add
|
||||||
// in the name if it isn't already there.
|
// in the name if it isn't already there.
|
||||||
if (Name.substr(0, 6) != " (scc:" && !llvm::forcePrintModuleIR())
|
if (Name.substr(0, 6) != " (scc:" && !forcePrintModuleIR())
|
||||||
Out << Name;
|
Out << Name;
|
||||||
|
|
||||||
Out << After.substr(Banner.size());
|
Out << After.substr(Banner.size());
|
||||||
@ -480,14 +481,14 @@ void PrintIRInstrumentation::printBeforePass(StringRef PassID, Any IR) {
|
|||||||
// Note: here we rely on a fact that we do not change modules while
|
// Note: here we rely on a fact that we do not change modules while
|
||||||
// traversing the pipeline, so the latest captured module is good
|
// traversing the pipeline, so the latest captured module is good
|
||||||
// for all print operations that has not happen yet.
|
// for all print operations that has not happen yet.
|
||||||
if (StoreModuleDesc && llvm::shouldPrintAfterPass(PassID))
|
if (StoreModuleDesc && shouldPrintAfterPass(PassID))
|
||||||
pushModuleDesc(PassID, IR);
|
pushModuleDesc(PassID, IR);
|
||||||
|
|
||||||
if (!llvm::shouldPrintBeforePass(PassID))
|
if (!shouldPrintBeforePass(PassID))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SmallString<20> Banner = formatv("*** IR Dump Before {0} ***", PassID);
|
SmallString<20> Banner = formatv("*** IR Dump Before {0} ***", PassID);
|
||||||
unwrapAndPrint(dbgs(), IR, Banner, llvm::forcePrintModuleIR());
|
unwrapAndPrint(dbgs(), IR, Banner, forcePrintModuleIR());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,18 +496,19 @@ void PrintIRInstrumentation::printAfterPass(StringRef PassID, Any IR) {
|
|||||||
if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<"))
|
if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!llvm::shouldPrintAfterPass(PassID))
|
if (!shouldPrintAfterPass(PassID))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (StoreModuleDesc)
|
if (StoreModuleDesc)
|
||||||
popModuleDesc(PassID);
|
popModuleDesc(PassID);
|
||||||
|
|
||||||
SmallString<20> Banner = formatv("*** IR Dump After {0} ***", PassID);
|
SmallString<20> Banner = formatv("*** IR Dump After {0} ***", PassID);
|
||||||
unwrapAndPrint(dbgs(), IR, Banner, llvm::forcePrintModuleIR());
|
unwrapAndPrint(dbgs(), IR, Banner, forcePrintModuleIR());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) {
|
void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) {
|
||||||
if (!StoreModuleDesc || !llvm::shouldPrintAfterPass(PassID))
|
StringRef PassName = PIC->getPassNameForClassName(PassID);
|
||||||
|
if (!StoreModuleDesc || !shouldPrintAfterPass(PassName))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<"))
|
if (PassID.startswith("PassManager<") || PassID.contains("PassAdaptor<"))
|
||||||
@ -526,16 +528,42 @@ void PrintIRInstrumentation::printAfterPassInvalidated(StringRef PassID) {
|
|||||||
printIR(dbgs(), M, Banner, Extra);
|
printIR(dbgs(), M, Banner, Extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PrintIRInstrumentation::shouldPrintBeforePass(StringRef PassID) {
|
||||||
|
if (shouldPrintBeforeAll())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
StringRef PassName = PIC->getPassNameForClassName(PassID);
|
||||||
|
for (const auto &P : printBeforePasses()) {
|
||||||
|
if (PassName == P)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PrintIRInstrumentation::shouldPrintAfterPass(StringRef PassID) {
|
||||||
|
if (shouldPrintAfterAll())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
StringRef PassName = PIC->getPassNameForClassName(PassID);
|
||||||
|
for (const auto &P : printAfterPasses()) {
|
||||||
|
if (PassName == P)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void PrintIRInstrumentation::registerCallbacks(
|
void PrintIRInstrumentation::registerCallbacks(
|
||||||
PassInstrumentationCallbacks &PIC) {
|
PassInstrumentationCallbacks &PIC) {
|
||||||
|
this->PIC = &PIC;
|
||||||
|
|
||||||
// BeforePass callback is not just for printing, it also saves a Module
|
// BeforePass callback is not just for printing, it also saves a Module
|
||||||
// for later use in AfterPassInvalidated.
|
// for later use in AfterPassInvalidated.
|
||||||
StoreModuleDesc = llvm::forcePrintModuleIR() && llvm::shouldPrintAfterPass();
|
StoreModuleDesc = forcePrintModuleIR() && shouldPrintAfterSomePass();
|
||||||
if (llvm::shouldPrintBeforePass() || StoreModuleDesc)
|
if (shouldPrintBeforeSomePass() || StoreModuleDesc)
|
||||||
PIC.registerBeforeNonSkippedPassCallback(
|
PIC.registerBeforeNonSkippedPassCallback(
|
||||||
[this](StringRef P, Any IR) { this->printBeforePass(P, IR); });
|
[this](StringRef P, Any IR) { this->printBeforePass(P, IR); });
|
||||||
|
|
||||||
if (llvm::shouldPrintAfterPass()) {
|
if (shouldPrintAfterSomePass()) {
|
||||||
PIC.registerAfterPassCallback(
|
PIC.registerAfterPassCallback(
|
||||||
[this](StringRef P, Any IR, const PreservedAnalyses &) {
|
[this](StringRef P, Any IR, const PreservedAnalyses &) {
|
||||||
this->printAfterPass(P, IR);
|
this->printAfterPass(P, IR);
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
; RUN: llc --help-hidden 2>&1 | FileCheck %s
|
|
||||||
|
|
||||||
; CHECK: -print-after
|
|
||||||
; CHECK-NOT: -print-after-all
|
|
||||||
; CHECK: =simple-register-coalescing
|
|
||||||
; CHECK: -print-after-all
|
|
@ -1,23 +1,23 @@
|
|||||||
; This test checks -print-after/before on loop passes
|
; This test checks -print-after/before on loop passes
|
||||||
; Besides of the loop itself it should be dumping loop pre-header and exits.
|
; Besides of the loop itself it should be dumping loop pre-header and exits.
|
||||||
;
|
;
|
||||||
; RUN: opt -enable-new-pm=0 < %s 2>&1 -disable-output \
|
; RUN: opt < %s 2>&1 -disable-output \
|
||||||
; RUN: -loop-deletion -print-before=loop-deletion \
|
; RUN: -loop-deletion -print-before=loop-deletion \
|
||||||
; RUN: | FileCheck %s -check-prefix=DEL
|
; RUN: | FileCheck %s -check-prefix=DEL
|
||||||
; RUN: opt < %s 2>&1 -disable-output \
|
; RUN: opt < %s 2>&1 -disable-output \
|
||||||
; RUN: -passes='loop(loop-deletion)' -print-before-all \
|
; RUN: -passes='loop(loop-deletion)' -print-before=loop-deletion \
|
||||||
; RUN: | FileCheck %s -check-prefix=DEL
|
; RUN: | FileCheck %s -check-prefix=DEL
|
||||||
; RUN: opt -enable-new-pm=0 < %s 2>&1 -disable-output \
|
; RUN: opt -enable-new-pm=0 < %s 2>&1 -disable-output \
|
||||||
; RUN: -loop-unroll -print-after=loop-unroll -filter-print-funcs=bar \
|
; RUN: -loop-unroll -print-after=loop-unroll -filter-print-funcs=bar \
|
||||||
; RUN: | FileCheck %s -check-prefix=BAR -check-prefix=BAR-OLD
|
; RUN: | FileCheck %s -check-prefix=BAR -check-prefix=BAR-OLD
|
||||||
; RUN: opt < %s 2>&1 -disable-output \
|
; RUN: opt < %s 2>&1 -disable-output \
|
||||||
; RUN: -passes='require<opt-remark-emit>,loop(loop-unroll-full)' -print-after-all -filter-print-funcs=bar \
|
; RUN: -passes='require<opt-remark-emit>,loop(loop-unroll-full)' -print-after=loop-unroll-full -filter-print-funcs=bar \
|
||||||
; RUN: | FileCheck %s -check-prefix=BAR
|
; RUN: | FileCheck %s -check-prefix=BAR
|
||||||
; RUN: opt -enable-new-pm=0 < %s 2>&1 -disable-output \
|
; RUN: opt -enable-new-pm=0 < %s 2>&1 -disable-output \
|
||||||
; RUN: -loop-unroll -print-after=loop-unroll -filter-print-funcs=foo -print-module-scope \
|
; RUN: -loop-unroll -print-after=loop-unroll -filter-print-funcs=foo -print-module-scope \
|
||||||
; RUN: | FileCheck %s -check-prefix=FOO-MODULE -check-prefix=FOO-MODULE-OLD
|
; RUN: | FileCheck %s -check-prefix=FOO-MODULE -check-prefix=FOO-MODULE-OLD
|
||||||
; RUN: opt < %s 2>&1 -disable-output \
|
; RUN: opt < %s 2>&1 -disable-output \
|
||||||
; RUN: -passes='require<opt-remark-emit>,loop(loop-unroll-full)' -print-after-all -filter-print-funcs=foo -print-module-scope \
|
; RUN: -passes='require<opt-remark-emit>,loop(loop-unroll-full)' -print-after=loop-unroll-full -filter-print-funcs=foo -print-module-scope \
|
||||||
; RUN: | FileCheck %s -check-prefix=FOO-MODULE
|
; RUN: | FileCheck %s -check-prefix=FOO-MODULE
|
||||||
|
|
||||||
; DEL: IR Dump Before {{Delete dead loops|LoopDeletionPass}}
|
; DEL: IR Dump Before {{Delete dead loops|LoopDeletionPass}}
|
||||||
|
33
test/Other/print-before-after.ll
Normal file
33
test/Other/print-before-after.ll
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
; RUN: not --crash opt < %s -disable-output -passes='no-op-module' -print-before=bleh 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty
|
||||||
|
; RUN: not --crash opt < %s -disable-output -passes='no-op-module' -print-after=bleh 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty
|
||||||
|
; RUN: opt < %s -disable-output -passes='no-op-module' -print-before=no-op-function 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty
|
||||||
|
; RUN: opt < %s -disable-output -passes='no-op-module' -print-after=no-op-function 2>&1 | FileCheck %s --check-prefix=NONE --allow-empty
|
||||||
|
; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-before=no-op-module 2>&1 | FileCheck %s --check-prefix=ONCE
|
||||||
|
; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-after=no-op-module 2>&1 | FileCheck %s --check-prefix=ONCE
|
||||||
|
; RUN: opt < %s -disable-output -passes='no-op-function' -print-before=no-op-function 2>&1 | FileCheck %s --check-prefix=ONCE
|
||||||
|
; RUN: opt < %s -disable-output -passes='no-op-function' -print-after=no-op-function 2>&1 | FileCheck %s --check-prefix=ONCE
|
||||||
|
; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-before=no-op-function --print-module-scope 2>&1 | FileCheck %s --check-prefix=TWICE
|
||||||
|
; RUN: opt < %s -disable-output -passes='no-op-module,no-op-function' -print-after=no-op-function --print-module-scope 2>&1 | FileCheck %s --check-prefix=TWICE
|
||||||
|
|
||||||
|
; NONE-NOT: @foo
|
||||||
|
; NONE-NOT: @bar
|
||||||
|
|
||||||
|
; ONCE: @foo
|
||||||
|
; ONCE: @bar
|
||||||
|
; ONCE-NOT: @foo
|
||||||
|
; ONCE-NOT: @bar
|
||||||
|
|
||||||
|
; TWICE: @foo
|
||||||
|
; TWICE: @bar
|
||||||
|
; TWICE: @foo
|
||||||
|
; TWICE: @bar
|
||||||
|
; TWICE-NOT: @foo
|
||||||
|
; TWICE-NOT: @bar
|
||||||
|
|
||||||
|
define void @foo() {
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @bar() {
|
||||||
|
ret void
|
||||||
|
}
|
@ -59,6 +59,7 @@ static_library("IR") {
|
|||||||
"PassManager.cpp",
|
"PassManager.cpp",
|
||||||
"PassRegistry.cpp",
|
"PassRegistry.cpp",
|
||||||
"PassTimingInfo.cpp",
|
"PassTimingInfo.cpp",
|
||||||
|
"PrintPasses.cpp",
|
||||||
"ProfileSummary.cpp",
|
"ProfileSummary.cpp",
|
||||||
"SafepointIRVerifier.cpp",
|
"SafepointIRVerifier.cpp",
|
||||||
"Statepoint.cpp",
|
"Statepoint.cpp",
|
||||||
|
Loading…
Reference in New Issue
Block a user