-print-changed for new pass manager is handy beside -print-after-all.
Port it to MachineFunctionPass.
Note: lib/Passes/StandardInstrumentations.cpp implements a number of
misc features. If we want to use them for codegen, we may need to lift
some functionality to LLVMIR.
Reviewed By: aeubanks, jamieschmeiser
Differential Revision: https://reviews.llvm.org/D130434
#define LLVM_IR_PRINTPASSES_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CommandLine.h"
#include <vector>
namespace llvm {
+enum class ChangePrinter {
+ None,
+ Verbose,
+ Quiet,
+ DiffVerbose,
+ DiffQuiet,
+ ColourDiffVerbose,
+ ColourDiffQuiet,
+ DotCfgVerbose,
+ DotCfgQuiet
+};
+
+extern cl::opt<ChangePrinter> PrintChanged;
+
// Returns true if printing before/after some pass is enabled, whether all
// passes or a specific pass.
bool shouldPrintBeforeSomePass();
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/PrintPasses.h"
using namespace llvm;
using namespace ore;
if (ShouldEmitSizeRemarks)
CountBefore = MF.getInstructionCount();
+ // For --print-changed, if the function name is a candidate, save the
+ // serialized MF to be compared later.
+ // TODO Implement --filter-passes.
+ SmallString<0> BeforeStr, AfterStr;
+ bool ShouldPrintChanged = PrintChanged != ChangePrinter::None &&
+ isFunctionInPrintList(MF.getName());
+ if (ShouldPrintChanged) {
+ raw_svector_ostream OS(BeforeStr);
+ MF.print(OS);
+ }
+
bool RV = runOnMachineFunction(MF);
if (ShouldEmitSizeRemarks) {
MFProps.set(SetProperties);
MFProps.reset(ClearedProperties);
+
+ // For --print-changed, print if the serialized MF has changed. Modes other
+ // than quiet/verbose are unimplemented and treated the same as 'quiet'.
+ if (ShouldPrintChanged) {
+ raw_svector_ostream OS(AfterStr);
+ MF.print(OS);
+ if (BeforeStr != AfterStr) {
+ StringRef Arg;
+ if (const PassInfo *PI = Pass::lookupPassInfo(getPassID()))
+ Arg = PI->getPassArgument();
+ errs() << ("*** IR Dump After " + getPassName() + " (" + Arg + ") on " +
+ MF.getName() + " ***\n" + AfterStr);
+ } else if (PrintChanged == ChangePrinter::Verbose) {
+ errs() << ("*** IR Dump After " + getPassName() + " on " + MF.getName() +
+ " omitted because no change ***\n");
+ }
+ }
return RV;
}
llvm::cl::desc("Print IR after each pass"),
cl::init(false), cl::Hidden);
+// Print 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. The -print-before-changed
+// option will print the IR as it was before each pass that changed it. The
+// optional value of quiet will only report when the IR changes, suppressing all
+// other messages, including the initial IR. The values "diff" and "diff-quiet"
+// will present the changes in a form similar to a patch, in either verbose or
+// quiet mode, respectively. The lines that are removed and added are prefixed
+// with '-' and '+', respectively. The -filter-print-funcs and -filter-passes
+// can be used to filter the output. This reporter relies on the linux diff
+// utility to do comparisons and insert the prefixes. For systems that do not
+// have the necessary facilities, the error message will be shown in place of
+// the expected output.
+cl::opt<ChangePrinter> llvm::PrintChanged(
+ "print-changed", cl::desc("Print changed IRs"), cl::Hidden,
+ cl::ValueOptional, cl::init(ChangePrinter::None),
+ cl::values(
+ clEnumValN(ChangePrinter::Quiet, "quiet", "Run in quiet mode"),
+ clEnumValN(ChangePrinter::DiffVerbose, "diff",
+ "Display patch-like changes"),
+ clEnumValN(ChangePrinter::DiffQuiet, "diff-quiet",
+ "Display patch-like changes in quiet mode"),
+ clEnumValN(ChangePrinter::ColourDiffVerbose, "cdiff",
+ "Display patch-like changes with color"),
+ clEnumValN(ChangePrinter::ColourDiffQuiet, "cdiff-quiet",
+ "Display patch-like changes in quiet mode with color"),
+ clEnumValN(ChangePrinter::DotCfgVerbose, "dot-cfg",
+ "Create a website with graphical changes"),
+ clEnumValN(ChangePrinter::DotCfgQuiet, "dot-cfg-quiet",
+ "Create a website with graphical changes in quiet mode"),
+ // Sentinel value for unspecified option.
+ clEnumValN(ChangePrinter::Verbose, "", "")));
+
static cl::opt<bool>
PrintModuleScope("print-module-scope",
cl::desc("When printing IR for print-[before|after]{-all} "
#endif
);
-// An 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. The -print-before-changed option will print
-// the IR as it was before each pass that changed it. The optional
-// value of quiet will only report when the IR changes, suppressing
-// all other messages, including the initial IR. The values "diff" and
-// "diff-quiet" will present the changes in a form similar to a patch, in
-// either verbose or quiet mode, respectively. The lines that are removed
-// and added are prefixed with '-' and '+', respectively. The
-// -filter-print-funcs and -filter-passes can be used to filter the output.
-// This reporter relies on the linux diff utility to do comparisons and
-// insert the prefixes. For systems that do not have the necessary
-// facilities, the error message will be shown in place of the expected output.
-//
-enum class ChangePrinter {
- None,
- Verbose,
- Quiet,
- DiffVerbose,
- DiffQuiet,
- ColourDiffVerbose,
- ColourDiffQuiet,
- DotCfgVerbose,
- DotCfgQuiet,
-};
-static cl::opt<ChangePrinter> PrintChanged(
- "print-changed", cl::desc("Print changed IRs"), cl::Hidden,
- cl::ValueOptional, cl::init(ChangePrinter::None),
- cl::values(
- clEnumValN(ChangePrinter::Quiet, "quiet", "Run in quiet mode"),
- clEnumValN(ChangePrinter::DiffVerbose, "diff",
- "Display patch-like changes"),
- clEnumValN(ChangePrinter::DiffQuiet, "diff-quiet",
- "Display patch-like changes in quiet mode"),
- clEnumValN(ChangePrinter::ColourDiffVerbose, "cdiff",
- "Display patch-like changes with color"),
- clEnumValN(ChangePrinter::ColourDiffQuiet, "cdiff-quiet",
- "Display patch-like changes in quiet mode with color"),
- clEnumValN(ChangePrinter::DotCfgVerbose, "dot-cfg",
- "Create a website with graphical changes"),
- clEnumValN(ChangePrinter::DotCfgQuiet, "dot-cfg-quiet",
- "Create a website with graphical changes in quiet mode"),
- // Sentinel value for unspecified option.
- clEnumValN(ChangePrinter::Verbose, "", "")));
-
// An 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.
--- /dev/null
+; REQUIRES: aarch64-registered-target
+; RUN: llc -filetype=null -mtriple=aarch64 -O0 -print-changed %s 2>&1 | FileCheck %s --check-prefixes=VERBOSE,VERBOSE-BAR
+; RUN: llc -filetype=null -mtriple=aarch64 -O0 -print-changed -filter-print-funcs=foo %s 2>&1 | FileCheck %s --check-prefixes=VERBOSE,NO-BAR
+
+; VERBOSE: *** IR Dump After IRTranslator (irtranslator) on foo ***
+; VERBOSE-NEXT: # Machine code for function foo: IsSSA, TracksLiveness{{$}}
+; VERBOSE-NEXT: Function Live Ins: $w0
+; VERBOSE-EMPTY:
+; VERBOSE-NEXT: bb.1.entry:
+; VERBOSE: *** IR Dump After Analysis for ComputingKnownBits on foo omitted because no change ***
+; VERBOSE-NEXT: *** IR Dump After AArch64O0PreLegalizerCombiner on foo omitted because no change ***
+; VERBOSE: *** IR Dump After Legalizer (legalizer) on foo ***
+; VERBOSE-NEXT: # Machine code for function foo: IsSSA, TracksLiveness, Legalized
+; VERBOSE-NEXT: Function Live Ins: $w0
+; VERBOSE-EMPTY:
+; VERBOSE-NEXT: bb.1.entry:
+
+; VERBOSE-BAR: *** IR Dump After IRTranslator (irtranslator) on bar ***
+; NO-BAR-NOT: on bar ***
+
+; RUN: llc -filetype=null -mtriple=aarch64 -O0 -print-changed=quiet %s 2>&1 | FileCheck %s --check-prefix=QUIET
+
+; QUIET: *** IR Dump After IRTranslator (irtranslator) on foo ***
+; QUIET-NOT: ***
+; QUIET: *** IR Dump After Legalizer (legalizer) on foo ***
+
+;; Other modes are unimplemented. Currently they behave like 'quiet'.
+; RUN: llc -filetype=null -mtriple=aarch64 -O0 -print-changed=diff %s 2>&1 | FileCheck %s --check-prefix=QUIET
+
+@var = global i32 0
+
+define void @foo(i32 %a) {
+entry:
+ %b = add i32 %a, 1
+ store i32 %b, ptr @var
+ ret void
+}
+
+define void @bar(i32 %a) {
+entry:
+ %b = add i32 %a, 2
+ store i32 %b, ptr @var
+ ret void
+}