1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
//===- 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);
// 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} "
"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) {
return llvm::is_contained(PassesToPrint, PassID);
}
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));
}
|