aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/opt/opt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/opt/opt.cpp')
-rw-r--r--llvm/tools/opt/opt.cpp170
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;
}
}