aboutsummaryrefslogtreecommitdiff
path: root/tools/opt/opt.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
commiteb11fae6d08f479c0799db45860a98af528fa6e7 (patch)
tree44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /tools/opt/opt.cpp
parentb8a2042aa938069e862750553db0e4d82d25822c (diff)
downloadsrc-eb11fae6d08f479c0799db45860a98af528fa6e7.tar.gz
src-eb11fae6d08f479c0799db45860a98af528fa6e7.zip
Vendor import of llvm trunk r338150:vendor/llvm/llvm-trunk-r338150
Notes
Notes: svn path=/vendor/llvm/dist/; revision=336809 svn path=/vendor/llvm/llvm-trunk-r338150/; revision=336814; tag=vendor/llvm/llvm-trunk-r338150
Diffstat (limited to 'tools/opt/opt.cpp')
-rw-r--r--tools/opt/opt.cpp159
1 files changed, 119 insertions, 40 deletions
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 5bc00ea35ae5..6e287b6c0ab6 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "BreakpointPrinter.h"
+#include "Debugify.h"
#include "NewPMDriver.h"
#include "PassPrinters.h"
#include "llvm/ADT/Triple.h"
@@ -23,8 +24,9 @@
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
-#include "llvm/CodeGen/CommandFlags.def"
+#include "llvm/CodeGen/CommandFlags.inc"
#include "llvm/CodeGen/TargetPassConfig.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/IRPrintingPasses.h"
@@ -41,10 +43,8 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
-#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/PluginLoader.h"
-#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/TargetRegistry.h"
@@ -123,7 +123,11 @@ StripDebug("strip-debug",
cl::desc("Strip debugger symbol info from translation unit"));
static cl::opt<bool>
-DisableInline("disable-inlining", cl::desc("Do not run the inliner pass"));
+ StripNamedMetadata("strip-named-metadata",
+ cl::desc("Strip module-level named metadata"));
+
+static cl::opt<bool> DisableInline("disable-inlining",
+ cl::desc("Do not run the inliner pass"));
static cl::opt<bool>
DisableOptimizations("disable-opt",
@@ -203,6 +207,21 @@ QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet));
static cl::opt<bool>
AnalyzeOnly("analyze", cl::desc("Only perform analysis, no optimization"));
+static cl::opt<bool> EnableDebugify(
+ "enable-debugify",
+ cl::desc(
+ "Start the pipeline with debugify and end it with check-debugify"));
+
+static cl::opt<bool> DebugifyEach(
+ "debugify-each",
+ cl::desc(
+ "Start each pass with debugify and end it with check-debugify"));
+
+static cl::opt<std::string>
+ DebugifyExport("debugify-export",
+ cl::desc("Export per-pass debugify statistics to this file"),
+ cl::value_desc("filename"), cl::init(""));
+
static cl::opt<bool>
PrintBreakpoints("print-breakpoints-for-testing",
cl::desc("Print select breakpoints location for testing"));
@@ -252,6 +271,48 @@ static cl::opt<std::string>
cl::desc("YAML output filename for pass remarks"),
cl::value_desc("filename"));
+class OptCustomPassManager : public legacy::PassManager {
+ DebugifyStatsMap DIStatsMap;
+
+public:
+ using super = legacy::PassManager;
+
+ void add(Pass *P) override {
+ // Wrap each pass with (-check)-debugify passes if requested, making
+ // exceptions for passes which shouldn't see -debugify instrumentation.
+ bool WrapWithDebugify = DebugifyEach && !P->getAsImmutablePass() &&
+ !isIRPrintingPass(P) && !isBitcodeWriterPass(P);
+ if (!WrapWithDebugify) {
+ super::add(P);
+ return;
+ }
+
+ // Apply -debugify/-check-debugify before/after each pass and collect
+ // debug info loss statistics.
+ PassKind Kind = P->getPassKind();
+ StringRef Name = P->getPassName();
+
+ // TODO: Implement Debugify for BasicBlockPass, LoopPass.
+ switch (Kind) {
+ case PT_Function:
+ super::add(createDebugifyFunctionPass());
+ super::add(P);
+ super::add(createCheckDebugifyFunctionPass(true, Name, &DIStatsMap));
+ break;
+ case PT_Module:
+ super::add(createDebugifyModulePass());
+ super::add(P);
+ super::add(createCheckDebugifyModulePass(true, Name, &DIStatsMap));
+ break;
+ default:
+ super::add(P);
+ break;
+ }
+ }
+
+ const DebugifyStatsMap &getDebugifyStatsMap() const { return DIStatsMap; }
+};
+
static inline void addPass(legacy::PassManagerBase &PM, Pass *P) {
// Add the pass to the pass manager...
PM.add(P);
@@ -362,13 +423,11 @@ void initializePollyPasses(llvm::PassRegistry &Registry);
// main for opt
//
int main(int argc, char **argv) {
- sys::PrintStackTraceOnErrorSignal(argv[0]);
- llvm::PrettyStackTraceProgram X(argc, argv);
+ InitLLVM X(argc, argv);
// Enable debug stream buffering.
EnableDebugBuffering = true;
- llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
LLVMContext Context;
InitializeAllTargets();
@@ -387,6 +446,7 @@ int main(int argc, char **argv) {
initializeAnalysis(Registry);
initializeTransformUtils(Registry);
initializeInstCombine(Registry);
+ initializeAggressiveInstCombine(Registry);
initializeInstrumentation(Registry);
initializeTarget(Registry);
// For codegen passes, only passes that do IR to IR transformation are
@@ -402,11 +462,13 @@ int main(int argc, char **argv) {
initializeSjLjEHPreparePass(Registry);
initializePreISelIntrinsicLoweringLegacyPassPass(Registry);
initializeGlobalMergePass(Registry);
+ initializeIndirectBrExpandPassPass(Registry);
initializeInterleavedAccessPass(Registry);
initializeEntryExitInstrumenterPass(Registry);
initializePostInlineEntryExitInstrumenterPass(Registry);
initializeUnreachableBlockElimLegacyPassPass(Registry);
initializeExpandReductionsPass(Registry);
+ initializeWasmEHPreparePass(Registry);
initializeWriteBitcodePassPass(Registry);
#ifdef LINK_POLLY_INTO_TOOLS
@@ -448,7 +510,7 @@ int main(int argc, char **argv) {
// Load the input module...
std::unique_ptr<Module> M =
- parseIRFile(InputFilename, Err, Context, !NoVerify);
+ parseIRFile(InputFilename, Err, Context, !NoVerify, ClDataLayout);
if (!M) {
Err.print(argv[0], errs());
@@ -459,6 +521,18 @@ int main(int argc, char **argv) {
if (StripDebug)
StripDebugInfo(*M);
+ // Erase module-level named metadata, if requested.
+ if (StripNamedMetadata) {
+ while (!M->named_metadata_empty()) {
+ NamedMDNode *NMD = &*M->named_metadata_begin();
+ M->eraseNamedMetadata(NMD);
+ }
+ }
+
+ // If we are supposed to override the target triple or data layout, do so now.
+ if (!TargetTriple.empty())
+ M->setTargetTriple(Triple::normalize(TargetTriple));
+
// Immediately run the verifier to catch any problems before starting up the
// pass pipelines. Otherwise we can crash on broken code during
// doInitialization().
@@ -468,12 +542,6 @@ int main(int argc, char **argv) {
return 1;
}
- // If we are supposed to override the target triple or data layout, do so now.
- if (!TargetTriple.empty())
- M->setTargetTriple(Triple::normalize(TargetTriple));
- if (!ClDataLayout.empty())
- M->setDataLayout(ClDataLayout);
-
// Figure out what stream we are supposed to write to...
std::unique_ptr<ToolOutputFile> Out;
std::unique_ptr<ToolOutputFile> ThinLinkOut;
@@ -547,15 +615,15 @@ int main(int argc, char **argv) {
OptRemarkFile.get(), PassPipeline, OK, VK,
PreserveAssemblyUseListOrder,
PreserveBitcodeUseListOrder, EmitSummaryIndex,
- EmitModuleHash)
+ EmitModuleHash, EnableDebugify)
? 0
: 1;
}
// Create a PassManager to hold and optimize the collection of passes we are
// about to build.
- //
- legacy::PassManager Passes;
+ OptCustomPassManager Passes;
+ bool AddOneTimeDebugifyPasses = EnableDebugify && !DebugifyEach;
// Add an appropriate TargetLibraryInfo pass for the module's triple.
TargetLibraryInfoImpl TLII(ModuleTriple);
@@ -569,6 +637,9 @@ int main(int argc, char **argv) {
Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis()
: TargetIRAnalysis()));
+ if (AddOneTimeDebugifyPasses)
+ Passes.add(createDebugifyModulePass());
+
std::unique_ptr<legacy::FunctionPassManager> FPasses;
if (OptLevelO0 || OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz ||
OptLevelO3) {
@@ -714,12 +785,15 @@ int main(int argc, char **argv) {
if (!NoVerify && !VerifyEach)
Passes.add(createVerifierPass());
+ if (AddOneTimeDebugifyPasses)
+ Passes.add(createCheckDebugifyModulePass(false));
+
// In run twice mode, we want to make sure the output is bit-by-bit
// equivalent if we run the pass manager again, so setup two buffers and
// a stream to write to them. Note that llc does something similar and it
// may be worth to abstract this out in the future.
SmallVector<char, 0> Buffer;
- SmallVector<char, 0> CompileTwiceBuffer;
+ SmallVector<char, 0> FirstRunBuffer;
std::unique_ptr<raw_svector_ostream> BOS;
raw_ostream *OS = nullptr;
@@ -748,28 +822,30 @@ int main(int argc, char **argv) {
// Before executing passes, print the final values of the LLVM options.
cl::PrintOptionValues();
- // If requested, run all passes again with the same pass manager to catch
- // bugs caused by persistent state in the passes
- if (RunTwice) {
- std::unique_ptr<Module> M2(CloneModule(M.get()));
- Passes.run(*M2);
- CompileTwiceBuffer = Buffer;
- Buffer.clear();
- }
-
- // Now that we have all of the passes ready, run them.
- Passes.run(*M);
-
- // Compare the two outputs and make sure they're the same
- if (RunTwice) {
+ if (!RunTwice) {
+ // Now that we have all of the passes ready, run them.
+ Passes.run(*M);
+ } else {
+ // If requested, run all passes twice with the same pass manager to catch
+ // bugs caused by persistent state in the passes.
+ std::unique_ptr<Module> M2(CloneModule(*M));
+ // Run all passes on the original module first, so the second run processes
+ // the clone to catch CloneModule bugs.
+ Passes.run(*M);
+ FirstRunBuffer = Buffer;
+ Buffer.clear();
+
+ Passes.run(*M2);
+
+ // Compare the two outputs and make sure they're the same
assert(Out);
- if (Buffer.size() != CompileTwiceBuffer.size() ||
- (memcmp(Buffer.data(), CompileTwiceBuffer.data(), Buffer.size()) !=
- 0)) {
- errs() << "Running the pass manager twice changed the output.\n"
- "Writing the result of the second run to the specified output.\n"
- "To generate the one-run comparison binary, just run without\n"
- "the compile-twice option\n";
+ if (Buffer.size() != FirstRunBuffer.size() ||
+ (memcmp(Buffer.data(), FirstRunBuffer.data(), Buffer.size()) != 0)) {
+ errs()
+ << "Running the pass manager twice changed the output.\n"
+ "Writing the result of the second run to the specified output.\n"
+ "To generate the one-run comparison binary, just run without\n"
+ "the compile-twice option\n";
Out->os() << BOS->str();
Out->keep();
if (OptRemarkFile)
@@ -779,6 +855,9 @@ int main(int argc, char **argv) {
Out->os() << BOS->str();
}
+ if (DebugifyEach && !DebugifyExport.empty())
+ exportDebugifyStats(DebugifyExport, Passes.getDebugifyStatsMap());
+
// Declare success.
if (!NoOutput || PrintBreakpoints)
Out->keep();