diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /tools/opt/opt.cpp | |
parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) | |
download | src-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.cpp | 159 |
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(); |