diff options
Diffstat (limited to 'llvm/tools/opt/opt.cpp')
-rw-r--r-- | llvm/tools/opt/opt.cpp | 170 |
1 files changed, 116 insertions, 54 deletions
diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp index 75a6cdc3892b..c250eefb8c43 100644 --- a/llvm/tools/opt/opt.cpp +++ b/llvm/tools/opt/opt.cpp @@ -21,18 +21,19 @@ #include "llvm/Analysis/RegionPass.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/AsmParser/Parser.h" #include "llvm/Bitcode/BitcodeWriterPass.h" -#include "llvm/CodeGen/CommandFlags.inc" +#include "llvm/CodeGen/CommandFlags.h" #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" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LLVMRemarkStreamer.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/LegacyPassNameParser.h" #include "llvm/IR/Module.h" -#include "llvm/IR/RemarkStreamer.h" #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" #include "llvm/InitializePasses.h" @@ -54,6 +55,7 @@ #include "llvm/Transforms/Coroutines.h" #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/Transforms/IPO/WholeProgramDevirt.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/Debugify.h" #include <algorithm> @@ -61,12 +63,17 @@ using namespace llvm; using namespace opt_tool; +static codegen::RegisterCodeGenFlags CFG; + // The OptimizationList is automatically populated with registered Passes by the // PassNameParser. // static cl::list<const PassInfo*, bool, PassNameParser> PassList(cl::desc("Optimizations available:")); +static cl::opt<bool> EnableNewPassManager( + "enable-new-pm", cl::desc("Enable the new pass manager"), cl::init(false)); + // This flag specifies a textual description of the optimization pass pipeline // to run over the module. This flag switches opt to use the new pass manager // infrastructure, completely disabling all of the flags specific to the old @@ -115,8 +122,12 @@ static cl::opt<std::string> ThinLinkBitcodeFile( static cl::opt<bool> NoVerify("disable-verify", cl::desc("Do not run the verifier"), cl::Hidden); -static cl::opt<bool> -VerifyEach("verify-each", cl::desc("Verify after each transform")); +static cl::opt<bool> NoUpgradeDebugInfo("disable-upgrade-debug-info", + cl::desc("Generate invalid output"), + cl::ReallyHidden); + +static cl::opt<bool> VerifyEach("verify-each", + cl::desc("Verify after each transform")); static cl::opt<bool> DisableDITypeMap("disable-debug-info-type-map", @@ -172,15 +183,9 @@ CodeGenOptLevel("codegen-opt-level", static cl::opt<std::string> TargetTriple("mtriple", cl::desc("Override target triple for module")); -static cl::opt<bool> -DisableLoopUnrolling("disable-loop-unrolling", - cl::desc("Disable loop unrolling in all relevant passes"), - cl::init(false)); - -static cl::opt<bool> -DisableSLPVectorization("disable-slp-vectorization", - cl::desc("Disable the slp vectorization pass"), - cl::init(false)); +cl::opt<bool> DisableLoopUnrolling( + "disable-loop-unrolling", + cl::desc("Disable loop unrolling in all relevant passes"), cl::init(false)); static cl::opt<bool> EmitSummaryIndex("module-summary", cl::desc("Emit module summary index"), @@ -198,13 +203,6 @@ DisableBuiltins("disable-builtin", cl::desc("Disable specific target library builtin function"), cl::ZeroOrMore); - -static cl::opt<bool> -Quiet("q", cl::desc("Obsolete option"), cl::Hidden); - -static cl::alias -QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet)); - static cl::opt<bool> AnalyzeOnly("analyze", cl::desc("Only perform analysis, no optimization")); @@ -257,6 +255,20 @@ static cl::opt<bool> Coroutines( cl::desc("Enable coroutine passes."), cl::init(false), cl::Hidden); +static cl::opt<bool> TimeTrace( + "time-trace", + cl::desc("Record time trace")); + +static cl::opt<unsigned> TimeTraceGranularity( + "time-trace-granularity", + cl::desc("Minimum time granularity (in microseconds) traced by time profiler"), + cl::init(500), cl::Hidden); + +static cl::opt<std::string> + TimeTraceFile("time-trace-file", + cl::desc("Specify time trace file destination"), + cl::value_desc("filename")); + static cl::opt<bool> RemarksWithHotness( "pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), @@ -389,18 +401,9 @@ static void AddOptimizationPasses(legacy::PassManagerBase &MPM, Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ? DisableLoopUnrolling : OptLevel == 0; - // Check if vectorization is explicitly disabled via -vectorize-loops=false. - // The flag enables vectorization in the LoopVectorize pass, it is on by - // default, and if it was disabled, leave it disabled here. - // Another flag that exists: -loop-vectorize, controls adding the pass to the - // pass manager. If set, the pass is added, and there is no additional check - // here for it. - if (Builder.LoopVectorize) - Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; + Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; - // When #pragma vectorize is on for SLP, do the same as above - Builder.SLPVectorize = - DisableSLPVectorization ? false : OptLevel > 1 && SizeLevel < 2; + Builder.SLPVectorize = OptLevel > 1 && SizeLevel < 2; if (TM) TM->adjustPassManager(Builder); @@ -470,16 +473,17 @@ static TargetMachine* GetTargetMachine(Triple TheTriple, StringRef CPUStr, StringRef FeaturesStr, const TargetOptions &Options) { std::string Error; - const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, - Error); + const Target *TheTarget = + TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); // Some modules don't specify a triple, and this is okay. if (!TheTarget) { return nullptr; } - return TheTarget->createTargetMachine(TheTriple.getTriple(), CPUStr, - FeaturesStr, Options, getRelocModel(), - getCodeModel(), GetCodeGenOptLevel()); + return TheTarget->createTargetMachine( + TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(), + Options, codegen::getExplicitRelocModel(), + codegen::getExplicitCodeModel(), GetCodeGenOptLevel()); } #ifdef BUILD_EXAMPLES @@ -508,6 +512,24 @@ void exportDebugifyStats(llvm::StringRef Path, const DebugifyStatsMap &Map) { } } +struct TimeTracerRAII { + TimeTracerRAII(StringRef ProgramName) { + if (TimeTrace) + timeTraceProfilerInitialize(TimeTraceGranularity, ProgramName); + } + ~TimeTracerRAII() { + if (TimeTrace) { + if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) { + handleAllErrors(std::move(E), [&](const StringError &SE) { + errs() << SE.getMessage() << "\n"; + }); + return; + } + timeTraceProfilerCleanup(); + } + } +}; + //===----------------------------------------------------------------------===// // main for opt // @@ -575,6 +597,8 @@ int main(int argc, char **argv) { return 1; } + TimeTracerRAII TimeTracer(argv[0]); + SMDiagnostic Err; Context.setDiscardValueNames(DiscardValueNames); @@ -582,9 +606,9 @@ int main(int argc, char **argv) { Context.enableDebugTypeODRUniquing(); Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr = - setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses, - RemarksFormat, RemarksWithHotness, - RemarksHotnessThreshold); + setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses, + RemarksFormat, RemarksWithHotness, + RemarksHotnessThreshold); if (Error E = RemarksFileOrErr.takeError()) { errs() << toString(std::move(E)) << '\n'; return 1; @@ -592,8 +616,18 @@ int main(int argc, char **argv) { std::unique_ptr<ToolOutputFile> RemarksFile = std::move(*RemarksFileOrErr); // Load the input module... - std::unique_ptr<Module> M = - parseIRFile(InputFilename, Err, Context, !NoVerify, ClDataLayout); + auto SetDataLayout = [](StringRef) -> Optional<std::string> { + if (ClDataLayout.empty()) + return None; + return ClDataLayout; + }; + std::unique_ptr<Module> M; + if (NoUpgradeDebugInfo) + M = parseAssemblyFileWithIndexNoUpgradeDebugInfo( + InputFilename, Err, Context, nullptr, SetDataLayout) + .Mod; + else + M = parseIRFile(InputFilename, Err, Context, SetDataLayout); if (!M) { Err.print(argv[0], errs()); @@ -625,6 +659,13 @@ int main(int argc, char **argv) { return 1; } + // Enable testing of whole program devirtualization on this module by invoking + // the facility for updating public visibility to linkage unit visibility when + // specified by an internal option. This is normally done during LTO which is + // not performed via opt. + updateVCallVisibilityInModule(*M, + /* WholeProgramVisibilityEnabledInLTO */ false); + // Figure out what stream we are supposed to write to... std::unique_ptr<ToolOutputFile> Out; std::unique_ptr<ToolOutputFile> ThinLinkOut; @@ -659,11 +700,11 @@ int main(int argc, char **argv) { Triple ModuleTriple(M->getTargetTriple()); std::string CPUStr, FeaturesStr; TargetMachine *Machine = nullptr; - const TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); + const TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(); if (ModuleTriple.getArch()) { - CPUStr = getCPUStr(); - FeaturesStr = getFeaturesStr(); + CPUStr = codegen::getCPUStr(); + FeaturesStr = codegen::getFeaturesStr(); Machine = GetTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options); } else if (ModuleTriple.getArchName() != "unknown" && ModuleTriple.getArchName() != "") { @@ -676,19 +717,40 @@ int main(int argc, char **argv) { // Override function attributes based on CPUStr, FeaturesStr, and command line // flags. - setFunctionAttributes(CPUStr, FeaturesStr, *M); + codegen::setFunctionAttributes(CPUStr, FeaturesStr, *M); // If the output is set to be emitted to standard out, and standard out is a // console, print out a warning message and refuse to do it. We don't // impress anyone by spewing tons of binary goo to a terminal. if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly) - if (CheckBitcodeOutputToConsole(Out->os(), !Quiet)) + if (CheckBitcodeOutputToConsole(Out->os())) NoOutput = true; if (OutputThinLTOBC) M->addModuleFlag(Module::Error, "EnableSplitLTOUnit", SplitLTOUnit); - if (PassPipeline.getNumOccurrences() > 0) { + if (EnableNewPassManager || PassPipeline.getNumOccurrences() > 0) { + if (PassPipeline.getNumOccurrences() > 0 && PassList.size() > 0) { + errs() + << "Cannot specify passes via both -foo-pass and --passes=foo-pass"; + return 1; + } + SmallVector<StringRef, 4> Passes; + for (const auto &P : PassList) { + Passes.push_back(P->getPassArgument()); + } + if (OptLevelO0) + Passes.push_back("default<O0>"); + if (OptLevelO1) + Passes.push_back("default<O1>"); + if (OptLevelO2) + Passes.push_back("default<O2>"); + if (OptLevelO3) + Passes.push_back("default<O3>"); + if (OptLevelOs) + Passes.push_back("default<Os>"); + if (OptLevelOz) + Passes.push_back("default<Oz>"); OutputKind OK = OK_NoOutput; if (!NoOutput) OK = OutputAssembly @@ -705,10 +767,10 @@ int main(int argc, char **argv) { // string. Hand off the rest of the functionality to the new code for that // layer. return runPassPipeline(argv[0], *M, TM.get(), Out.get(), ThinLinkOut.get(), - RemarksFile.get(), PassPipeline, OK, VK, + RemarksFile.get(), PassPipeline, Passes, OK, VK, PreserveAssemblyUseListOrder, PreserveBitcodeUseListOrder, EmitSummaryIndex, - EmitModuleHash, EnableDebugify) + EmitModuleHash, EnableDebugify, Coroutines) ? 0 : 1; } @@ -831,19 +893,19 @@ int main(int argc, char **argv) { if (AnalyzeOnly) { switch (Kind) { case PT_Region: - Passes.add(createRegionPassPrinter(PassInf, Out->os(), Quiet)); + Passes.add(createRegionPassPrinter(PassInf, Out->os())); break; case PT_Loop: - Passes.add(createLoopPassPrinter(PassInf, Out->os(), Quiet)); + Passes.add(createLoopPassPrinter(PassInf, Out->os())); break; case PT_Function: - Passes.add(createFunctionPassPrinter(PassInf, Out->os(), Quiet)); + Passes.add(createFunctionPassPrinter(PassInf, Out->os())); break; case PT_CallGraphSCC: - Passes.add(createCallGraphPassPrinter(PassInf, Out->os(), Quiet)); + Passes.add(createCallGraphPassPrinter(PassInf, Out->os())); break; default: - Passes.add(createModulePassPrinter(PassInf, Out->os(), Quiet)); + Passes.add(createModulePassPrinter(PassInf, Out->os())); break; } } |