diff options
Diffstat (limited to 'tools/opt/opt.cpp')
-rw-r--r-- | tools/opt/opt.cpp | 151 |
1 files changed, 104 insertions, 47 deletions
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index a4967a234d9c..ccf8b073b82b 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -1,9 +1,8 @@ //===- opt.cpp - The LLVM Modular Optimizer -------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -34,6 +33,7 @@ #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" @@ -173,18 +173,9 @@ static cl::opt<std::string> TargetTriple("mtriple", cl::desc("Override target triple for module")); static cl::opt<bool> -UnitAtATime("funit-at-a-time", - cl::desc("Enable IPO. This corresponds to gcc's -funit-at-a-time"), - cl::init(true)); - -static cl::opt<bool> DisableLoopUnrolling("disable-loop-unrolling", cl::desc("Disable loop unrolling in all relevant passes"), cl::init(false)); -static cl::opt<bool> -DisableLoopVectorization("disable-loop-vectorization", - cl::desc("Disable the loop vectorization pass"), - cl::init(false)); static cl::opt<bool> DisableSLPVectorization("disable-slp-vectorization", @@ -260,21 +251,62 @@ static cl::opt<bool> Coroutines( cl::desc("Enable coroutine passes."), cl::init(false), cl::Hidden); -static cl::opt<bool> PassRemarksWithHotness( +static cl::opt<bool> RemarksWithHotness( "pass-remarks-with-hotness", cl::desc("With PGO, include profile count in optimization remarks"), cl::Hidden); -static cl::opt<unsigned> PassRemarksHotnessThreshold( - "pass-remarks-hotness-threshold", - cl::desc("Minimum profile count required for an optimization remark to be output"), - cl::Hidden); +static cl::opt<unsigned> + RemarksHotnessThreshold("pass-remarks-hotness-threshold", + cl::desc("Minimum profile count required for " + "an optimization remark to be output"), + cl::Hidden); static cl::opt<std::string> RemarksFilename("pass-remarks-output", - cl::desc("YAML output filename for pass remarks"), + cl::desc("Output filename for pass remarks"), cl::value_desc("filename")); +static cl::opt<std::string> + RemarksPasses("pass-remarks-filter", + cl::desc("Only record optimization remarks from passes whose " + "names match the given regular expression"), + cl::value_desc("regex")); + +static cl::opt<std::string> RemarksFormat( + "pass-remarks-format", + cl::desc("The format used for serializing remarks (default: YAML)"), + cl::value_desc("format"), cl::init("yaml")); + +cl::opt<PGOKind> + PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden, + cl::desc("The kind of profile guided optimization"), + cl::values(clEnumValN(NoPGO, "nopgo", "Do not use PGO."), + clEnumValN(InstrGen, "pgo-instr-gen-pipeline", + "Instrument the IR to generate profile."), + clEnumValN(InstrUse, "pgo-instr-use-pipeline", + "Use instrumented profile to guide PGO."), + clEnumValN(SampleUse, "pgo-sample-use-pipeline", + "Use sampled profile to guide PGO."))); +cl::opt<std::string> ProfileFile("profile-file", + cl::desc("Path to the profile."), cl::Hidden); + +cl::opt<CSPGOKind> CSPGOKindFlag( + "cspgo-kind", cl::init(NoCSPGO), cl::Hidden, + cl::desc("The kind of context sensitive profile guided optimization"), + cl::values( + clEnumValN(NoCSPGO, "nocspgo", "Do not use CSPGO."), + clEnumValN( + CSInstrGen, "cspgo-instr-gen-pipeline", + "Instrument (context sensitive) the IR to generate profile."), + clEnumValN( + CSInstrUse, "cspgo-instr-use-pipeline", + "Use instrumented (context sensitive) profile to guide PGO."))); +cl::opt<std::string> CSProfileGenFile( + "cs-profilegen-file", + cl::desc("Path to the instrumented context sensitive profile."), + cl::Hidden); + class OptCustomPassManager : public legacy::PassManager { DebugifyStatsMap DIStatsMap; @@ -348,15 +380,16 @@ static void AddOptimizationPasses(legacy::PassManagerBase &MPM, } else { Builder.Inliner = createAlwaysInlinerLegacyPass(); } - Builder.DisableUnitAtATime = !UnitAtATime; Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ? DisableLoopUnrolling : OptLevel == 0; - // This is final, unless there is a #pragma vectorize enable - if (DisableLoopVectorization) - Builder.LoopVectorize = false; - // If option wasn't forced via cmd line (-vectorize-loops, -loop-vectorize) - else if (!Builder.LoopVectorize) + // 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; // When #pragma vectorize is on for SLP, do the same as above @@ -369,6 +402,32 @@ static void AddOptimizationPasses(legacy::PassManagerBase &MPM, if (Coroutines) addCoroutinePassesToExtensionPoints(Builder); + switch (PGOKindFlag) { + case InstrGen: + Builder.EnablePGOInstrGen = true; + Builder.PGOInstrGen = ProfileFile; + break; + case InstrUse: + Builder.PGOInstrUse = ProfileFile; + break; + case SampleUse: + Builder.PGOSampleUse = ProfileFile; + break; + default: + break; + } + + switch (CSPGOKindFlag) { + case CSInstrGen: + Builder.EnablePGOCSInstrGen = true; + break; + case CSInstrUse: + Builder.EnablePGOCSInstrUse = true; + break; + default: + break; + } + Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); } @@ -464,6 +523,7 @@ int main(int argc, char **argv) { initializeDwarfEHPreparePass(Registry); initializeSafeStackLegacyPassPass(Registry); initializeSjLjEHPreparePass(Registry); + initializeStackProtectorPass(Registry); initializePreISelIntrinsicLoweringLegacyPassPass(Registry); initializeGlobalMergePass(Registry); initializeIndirectBrExpandPassPass(Registry); @@ -475,6 +535,7 @@ int main(int argc, char **argv) { initializeExpandReductionsPass(Registry); initializeWasmEHPreparePass(Registry); initializeWriteBitcodePassPass(Registry); + initializeHardwareLoopsPass(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); @@ -494,24 +555,15 @@ int main(int argc, char **argv) { if (!DisableDITypeMap) Context.enableDebugTypeODRUniquing(); - if (PassRemarksWithHotness) - Context.setDiagnosticsHotnessRequested(true); - - if (PassRemarksHotnessThreshold) - Context.setDiagnosticsHotnessThreshold(PassRemarksHotnessThreshold); - - std::unique_ptr<ToolOutputFile> OptRemarkFile; - if (RemarksFilename != "") { - std::error_code EC; - OptRemarkFile = - llvm::make_unique<ToolOutputFile>(RemarksFilename, EC, sys::fs::F_None); - if (EC) { - errs() << EC.message() << '\n'; - return 1; - } - Context.setDiagnosticsOutputFile( - llvm::make_unique<yaml::Output>(OptRemarkFile->os())); + Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr = + setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses, + RemarksFormat, RemarksWithHotness, + RemarksHotnessThreshold); + if (Error E = RemarksFileOrErr.takeError()) { + errs() << toString(std::move(E)) << '\n'; + return 1; } + std::unique_ptr<ToolOutputFile> RemarksFile = std::move(*RemarksFileOrErr); // Load the input module... std::unique_ptr<Module> M = @@ -585,6 +637,11 @@ int main(int argc, char **argv) { CPUStr = getCPUStr(); FeaturesStr = getFeaturesStr(); Machine = GetTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options); + } else if (ModuleTriple.getArchName() != "unknown" && + ModuleTriple.getArchName() != "") { + errs() << argv[0] << ": unrecognized architecture '" + << ModuleTriple.getArchName() << "' provided.\n"; + return 1; } std::unique_ptr<TargetMachine> TM(Machine); @@ -620,7 +677,7 @@ 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(), - OptRemarkFile.get(), PassPipeline, OK, VK, + RemarksFile.get(), PassPipeline, OK, VK, PreserveAssemblyUseListOrder, PreserveBitcodeUseListOrder, EmitSummaryIndex, EmitModuleHash, EnableDebugify) @@ -856,8 +913,8 @@ int main(int argc, char **argv) { "the compile-twice option\n"; Out->os() << BOS->str(); Out->keep(); - if (OptRemarkFile) - OptRemarkFile->keep(); + if (RemarksFile) + RemarksFile->keep(); return 1; } Out->os() << BOS->str(); @@ -870,8 +927,8 @@ int main(int argc, char **argv) { if (!NoOutput || PrintBreakpoints) Out->keep(); - if (OptRemarkFile) - OptRemarkFile->keep(); + if (RemarksFile) + RemarksFile->keep(); if (ThinLinkOut) ThinLinkOut->keep(); |