summaryrefslogtreecommitdiff
path: root/llvm/tools/opt
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/opt')
-rw-r--r--llvm/tools/opt/AnalysisWrappers.cpp9
-rw-r--r--llvm/tools/opt/NewPMDriver.cpp135
-rw-r--r--llvm/tools/opt/NewPMDriver.h8
-rw-r--r--llvm/tools/opt/PassPrinters.cpp82
-rw-r--r--llvm/tools/opt/PassPrinters.h17
-rw-r--r--llvm/tools/opt/PrintSCC.cpp11
-rw-r--r--llvm/tools/opt/opt.cpp170
7 files changed, 257 insertions, 175 deletions
diff --git a/llvm/tools/opt/AnalysisWrappers.cpp b/llvm/tools/opt/AnalysisWrappers.cpp
index b888605a516c..2ae1da84a9a0 100644
--- a/llvm/tools/opt/AnalysisWrappers.cpp
+++ b/llvm/tools/opt/AnalysisWrappers.cpp
@@ -17,7 +17,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/CallGraph.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"
@@ -40,11 +39,11 @@ namespace {
Instruction *UI = dyn_cast<Instruction>(U);
if (!UI) continue;
- CallSite CS(cast<Value>(UI));
- if (!CS) continue;
+ CallBase *CB = dyn_cast<CallBase>(UI);
+ if (!CB)
+ continue;
- for (CallSite::arg_iterator AI = CS.arg_begin(),
- E = CS.arg_end(); AI != E; ++AI) {
+ for (auto AI = CB->arg_begin(), E = CB->arg_end(); AI != E; ++AI) {
if (!isa<Constant>(*AI)) continue;
if (!PrintedFn) {
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index ac04a32d93fd..b94c58decdda 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -14,6 +14,7 @@
#include "NewPMDriver.h"
#include "PassPrinters.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CGSCCPassManager.h"
@@ -100,6 +101,9 @@ static cl::opt<std::string> OptimizerLastEPPipeline(
"the OptimizerLast extension point into default pipelines"),
cl::Hidden);
+// Individual pipeline tuning options.
+extern cl::opt<bool> DisableLoopUnrolling;
+
extern cl::opt<PGOKind> PGOKindFlag;
extern cl::opt<std::string> ProfileFile;
extern cl::opt<CSPGOKind> CSPGOKindFlag;
@@ -194,7 +198,7 @@ static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass,
});
if (tryParsePipelineText<FunctionPassManager>(PB, OptimizerLastEPPipeline))
PB.registerOptimizerLastEPCallback(
- [&PB, VerifyEachPass, DebugLogging](FunctionPassManager &PM,
+ [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM,
PassBuilder::OptimizationLevel) {
ExitOnError Err("Unable to parse OptimizerLastEP pipeline: ");
Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline, VerifyEachPass,
@@ -209,57 +213,63 @@ static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass,
bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
ToolOutputFile *Out, ToolOutputFile *ThinLTOLinkOut,
ToolOutputFile *OptRemarkFile,
- StringRef PassPipeline, OutputKind OK,
- VerifierKind VK,
+ StringRef PassPipeline, ArrayRef<StringRef> Passes,
+ OutputKind OK, VerifierKind VK,
bool ShouldPreserveAssemblyUseListOrder,
bool ShouldPreserveBitcodeUseListOrder,
bool EmitSummaryIndex, bool EmitModuleHash,
- bool EnableDebugify) {
+ bool EnableDebugify, bool Coroutines) {
bool VerifyEachPass = VK == VK_VerifyEachPass;
Optional<PGOOptions> P;
switch (PGOKindFlag) {
- case InstrGen:
- P = PGOOptions(ProfileFile, "", "", PGOOptions::IRInstr);
- break;
- case InstrUse:
- P = PGOOptions(ProfileFile, "", ProfileRemappingFile, PGOOptions::IRUse);
- break;
- case SampleUse:
- P = PGOOptions(ProfileFile, "", ProfileRemappingFile,
- PGOOptions::SampleUse);
- break;
- case NoPGO:
- if (DebugInfoForProfiling)
- P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction,
- true);
- else
- P = None;
- }
- if (CSPGOKindFlag != NoCSPGO) {
- if (P && (P->Action == PGOOptions::IRInstr ||
- P->Action == PGOOptions::SampleUse))
- errs() << "CSPGOKind cannot be used with IRInstr or SampleUse";
- if (CSPGOKindFlag == CSInstrGen) {
- if (CSProfileGenFile.empty())
- errs() << "CSInstrGen needs to specify CSProfileGenFile";
- if (P) {
- P->CSAction = PGOOptions::CSIRInstr;
- P->CSProfileGenFile = CSProfileGenFile;
- } else
- P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile,
- PGOOptions::NoAction, PGOOptions::CSIRInstr);
- } else /* CSPGOKindFlag == CSInstrUse */ {
- if (!P)
- errs() << "CSInstrUse needs to be together with InstrUse";
- P->CSAction = PGOOptions::CSIRUse;
- }
+ case InstrGen:
+ P = PGOOptions(ProfileFile, "", "", PGOOptions::IRInstr);
+ break;
+ case InstrUse:
+ P = PGOOptions(ProfileFile, "", ProfileRemappingFile, PGOOptions::IRUse);
+ break;
+ case SampleUse:
+ P = PGOOptions(ProfileFile, "", ProfileRemappingFile,
+ PGOOptions::SampleUse);
+ break;
+ case NoPGO:
+ if (DebugInfoForProfiling)
+ P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction,
+ true);
+ else
+ P = None;
+ }
+ if (CSPGOKindFlag != NoCSPGO) {
+ if (P && (P->Action == PGOOptions::IRInstr ||
+ P->Action == PGOOptions::SampleUse))
+ errs() << "CSPGOKind cannot be used with IRInstr or SampleUse";
+ if (CSPGOKindFlag == CSInstrGen) {
+ if (CSProfileGenFile.empty())
+ errs() << "CSInstrGen needs to specify CSProfileGenFile";
+ if (P) {
+ P->CSAction = PGOOptions::CSIRInstr;
+ P->CSProfileGenFile = CSProfileGenFile;
+ } else
+ P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile,
+ PGOOptions::NoAction, PGOOptions::CSIRInstr);
+ } else /* CSPGOKindFlag == CSInstrUse */ {
+ if (!P)
+ errs() << "CSInstrUse needs to be together with InstrUse";
+ P->CSAction = PGOOptions::CSIRUse;
}
+ }
PassInstrumentationCallbacks PIC;
StandardInstrumentations SI;
SI.registerCallbacks(PIC);
- PassBuilder PB(TM, PipelineTuningOptions(), P, &PIC);
+ PipelineTuningOptions PTO;
+ // LoopUnrolling defaults on to true and DisableLoopUnrolling is initialized
+ // to false above so we shouldn't necessarily need to check whether or not the
+ // option has been enabled.
+ PTO.LoopUnrolling = !DisableLoopUnrolling;
+ PTO.Coroutines = Coroutines;
+ PassBuilder PB(TM, PTO, P, &PIC);
registerEPCallbacks(PB, VerifyEachPass, DebugPM);
// Load requested pass plugins and let them register pass builder callbacks
@@ -295,9 +305,26 @@ bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
// Specially handle the alias analysis manager so that we can register
// a custom pipeline of AA passes with it.
AAManager AA;
- if (auto Err = PB.parseAAPipeline(AA, AAPipeline)) {
- errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
- return false;
+ if (!AAPipeline.empty()) {
+ assert(Passes.empty() &&
+ "--aa-pipeline and -foo-pass should not both be specified");
+ if (auto Err = PB.parseAAPipeline(AA, AAPipeline)) {
+ errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
+ return false;
+ }
+ }
+ // For compatibility with legacy pass manager.
+ // Alias analyses are not specially specified when using the legacy PM.
+ SmallVector<StringRef, 4> NonAAPasses;
+ for (auto PassName : Passes) {
+ if (PB.isAAPassName(PassName)) {
+ if (auto Err = PB.parseAAPipeline(AA, PassName)) {
+ errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
+ return false;
+ }
+ } else {
+ NonAAPasses.push_back(PassName);
+ }
}
LoopAnalysisManager LAM(DebugPM);
@@ -321,10 +348,24 @@ bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
if (EnableDebugify)
MPM.addPass(NewPMDebugifyPass());
- if (auto Err =
- PB.parsePassPipeline(MPM, PassPipeline, VerifyEachPass, DebugPM)) {
- errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
- return false;
+ if (!PassPipeline.empty()) {
+ assert(Passes.empty() &&
+ "PassPipeline and Passes should not both contain passes");
+ if (auto Err =
+ PB.parsePassPipeline(MPM, PassPipeline, VerifyEachPass, DebugPM)) {
+ errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
+ return false;
+ }
+ }
+ for (auto PassName : NonAAPasses) {
+ std::string ModifiedPassName(PassName.begin(), PassName.end());
+ if (PB.isAnalysisPassName(PassName))
+ ModifiedPassName = "require<" + ModifiedPassName + ">";
+ if (auto Err = PB.parsePassPipeline(MPM, ModifiedPassName, VerifyEachPass,
+ DebugPM)) {
+ errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
+ return false;
+ }
}
if (VK > VK_NoVerifier)
diff --git a/llvm/tools/opt/NewPMDriver.h b/llvm/tools/opt/NewPMDriver.h
index b672c97c9aa3..7ae273a2c1f4 100644
--- a/llvm/tools/opt/NewPMDriver.h
+++ b/llvm/tools/opt/NewPMDriver.h
@@ -20,9 +20,10 @@
#ifndef LLVM_TOOLS_OPT_NEWPMDRIVER_H
#define LLVM_TOOLS_OPT_NEWPMDRIVER_H
+#include "llvm/ADT/ArrayRef.h"
+
namespace llvm {
class StringRef;
-class LLVMContext;
class Module;
class TargetMachine;
class ToolOutputFile;
@@ -60,11 +61,12 @@ enum CSPGOKind { NoCSPGO, CSInstrGen, CSInstrUse };
bool runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
ToolOutputFile *Out, ToolOutputFile *ThinLinkOut,
ToolOutputFile *OptRemarkFile, StringRef PassPipeline,
- opt_tool::OutputKind OK, opt_tool::VerifierKind VK,
+ ArrayRef<StringRef> PassInfos, opt_tool::OutputKind OK,
+ opt_tool::VerifierKind VK,
bool ShouldPreserveAssemblyUseListOrder,
bool ShouldPreserveBitcodeUseListOrder,
bool EmitSummaryIndex, bool EmitModuleHash,
- bool EnableDebugify);
+ bool EnableDebugify, bool Coroutines);
} // namespace llvm
#endif
diff --git a/llvm/tools/opt/PassPrinters.cpp b/llvm/tools/opt/PassPrinters.cpp
index a877d9dc90f4..4e81b5d29c4d 100644
--- a/llvm/tools/opt/PassPrinters.cpp
+++ b/llvm/tools/opt/PassPrinters.cpp
@@ -33,18 +33,16 @@ struct FunctionPassPrinter : public FunctionPass {
raw_ostream &Out;
static char ID;
std::string PassName;
- bool QuietPass;
- FunctionPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet)
- : FunctionPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) {
- std::string PassToPrintName = PassToPrint->getPassName();
+ FunctionPassPrinter(const PassInfo *PI, raw_ostream &out)
+ : FunctionPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = std::string(PassToPrint->getPassName());
PassName = "FunctionPass Printer: " + PassToPrintName;
}
bool runOnFunction(Function &F) override {
- if (!QuietPass)
- Out << "Printing analysis '" << PassToPrint->getPassName()
- << "' for function '" << F.getName() << "':\n";
+ Out << "Printing analysis '" << PassToPrint->getPassName()
+ << "' for function '" << F.getName() << "':\n";
// Get and print pass...
getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, F.getParent());
@@ -66,17 +64,15 @@ struct CallGraphSCCPassPrinter : public CallGraphSCCPass {
const PassInfo *PassToPrint;
raw_ostream &Out;
std::string PassName;
- bool QuietPass;
- CallGraphSCCPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet)
- : CallGraphSCCPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) {
- std::string PassToPrintName = PassToPrint->getPassName();
+ CallGraphSCCPassPrinter(const PassInfo *PI, raw_ostream &out)
+ : CallGraphSCCPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = std::string(PassToPrint->getPassName());
PassName = "CallGraphSCCPass Printer: " + PassToPrintName;
}
bool runOnSCC(CallGraphSCC &SCC) override {
- if (!QuietPass)
- Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+ Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
// Get and print pass...
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
@@ -103,17 +99,15 @@ struct ModulePassPrinter : public ModulePass {
const PassInfo *PassToPrint;
raw_ostream &Out;
std::string PassName;
- bool QuietPass;
- ModulePassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet)
- : ModulePass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) {
- std::string PassToPrintName = PassToPrint->getPassName();
+ ModulePassPrinter(const PassInfo *PI, raw_ostream &out)
+ : ModulePass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = std::string(PassToPrint->getPassName());
PassName = "ModulePass Printer: " + PassToPrintName;
}
bool runOnModule(Module &M) override {
- if (!QuietPass)
- Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+ Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
// Get and print pass...
getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, &M);
@@ -135,17 +129,15 @@ struct LoopPassPrinter : public LoopPass {
const PassInfo *PassToPrint;
raw_ostream &Out;
std::string PassName;
- bool QuietPass;
- LoopPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet)
- : LoopPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) {
- std::string PassToPrintName = PassToPrint->getPassName();
+ LoopPassPrinter(const PassInfo *PI, raw_ostream &out)
+ : LoopPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = std::string(PassToPrint->getPassName());
PassName = "LoopPass Printer: " + PassToPrintName;
}
bool runOnLoop(Loop *L, LPPassManager &LPM) override {
- if (!QuietPass)
- Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
+ Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n";
// Get and print pass...
getAnalysisID<Pass>(PassToPrint->getTypeInfo())
@@ -168,20 +160,17 @@ struct RegionPassPrinter : public RegionPass {
const PassInfo *PassToPrint;
raw_ostream &Out;
std::string PassName;
- bool QuietPass;
- RegionPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet)
- : RegionPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) {
- std::string PassToPrintName = PassToPrint->getPassName();
+ RegionPassPrinter(const PassInfo *PI, raw_ostream &out)
+ : RegionPass(ID), PassToPrint(PI), Out(out) {
+ std::string PassToPrintName = std::string(PassToPrint->getPassName());
PassName = "RegionPass Printer: " + PassToPrintName;
}
bool runOnRegion(Region *R, RGPassManager &RGM) override {
- if (!QuietPass) {
- Out << "Printing analysis '" << PassToPrint->getPassName() << "' for "
- << "region: '" << R->getNameStr() << "' in function '"
- << R->getEntry()->getParent()->getName() << "':\n";
- }
+ Out << "Printing analysis '" << PassToPrint->getPassName() << "' for "
+ << "region: '" << R->getNameStr() << "' in function '"
+ << R->getEntry()->getParent()->getName() << "':\n";
// Get and print pass...
getAnalysisID<Pass>(PassToPrint->getTypeInfo())
.print(Out, R->getEntry()->getParent()->getParent());
@@ -201,28 +190,23 @@ char RegionPassPrinter::ID = 0;
} // end anonymous namespace
FunctionPass *llvm::createFunctionPassPrinter(const PassInfo *PI,
- raw_ostream &OS, bool Quiet) {
- return new FunctionPassPrinter(PI, OS, Quiet);
+ raw_ostream &OS) {
+ return new FunctionPassPrinter(PI, OS);
}
CallGraphSCCPass *llvm::createCallGraphPassPrinter(const PassInfo *PI,
- raw_ostream &OS,
- bool Quiet) {
- return new CallGraphSCCPassPrinter(PI, OS, Quiet);
+ raw_ostream &OS) {
+ return new CallGraphSCCPassPrinter(PI, OS);
}
-ModulePass *llvm::createModulePassPrinter(const PassInfo *PI, raw_ostream &OS,
- bool Quiet) {
- return new ModulePassPrinter(PI, OS, Quiet);
+ModulePass *llvm::createModulePassPrinter(const PassInfo *PI, raw_ostream &OS) {
+ return new ModulePassPrinter(PI, OS);
}
-LoopPass *llvm::createLoopPassPrinter(const PassInfo *PI, raw_ostream &OS,
- bool Quiet) {
- return new LoopPassPrinter(PI, OS, Quiet);
+LoopPass *llvm::createLoopPassPrinter(const PassInfo *PI, raw_ostream &OS) {
+ return new LoopPassPrinter(PI, OS);
}
-RegionPass *llvm::createRegionPassPrinter(const PassInfo *PI, raw_ostream &OS,
- bool Quiet) {
- return new RegionPassPrinter(PI, OS, Quiet);
+RegionPass *llvm::createRegionPassPrinter(const PassInfo *PI, raw_ostream &OS) {
+ return new RegionPassPrinter(PI, OS);
}
-
diff --git a/llvm/tools/opt/PassPrinters.h b/llvm/tools/opt/PassPrinters.h
index 692befbdae75..a4e1921399fc 100644
--- a/llvm/tools/opt/PassPrinters.h
+++ b/llvm/tools/opt/PassPrinters.h
@@ -14,8 +14,6 @@
#ifndef LLVM_TOOLS_OPT_PASSPRINTERS_H
#define LLVM_TOOLS_OPT_PASSPRINTERS_H
-#include "llvm/IR/PassManager.h"
-
namespace llvm {
class CallGraphSCCPass;
@@ -25,22 +23,17 @@ class LoopPass;
class PassInfo;
class raw_ostream;
class RegionPass;
-class Module;
-FunctionPass *createFunctionPassPrinter(const PassInfo *PI, raw_ostream &out,
- bool Quiet);
+FunctionPass *createFunctionPassPrinter(const PassInfo *PI, raw_ostream &out);
CallGraphSCCPass *createCallGraphPassPrinter(const PassInfo *PI,
- raw_ostream &out, bool Quiet);
+ raw_ostream &out);
-ModulePass *createModulePassPrinter(const PassInfo *PI, raw_ostream &out,
- bool Quiet);
+ModulePass *createModulePassPrinter(const PassInfo *PI, raw_ostream &out);
-LoopPass *createLoopPassPrinter(const PassInfo *PI, raw_ostream &out,
- bool Quiet);
+LoopPass *createLoopPassPrinter(const PassInfo *PI, raw_ostream &out);
-RegionPass *createRegionPassPrinter(const PassInfo *PI, raw_ostream &out,
- bool Quiet);
+RegionPass *createRegionPassPrinter(const PassInfo *PI, raw_ostream &out);
} // end namespace llvm
diff --git a/llvm/tools/opt/PrintSCC.cpp b/llvm/tools/opt/PrintSCC.cpp
index 419886d6cc60..1ca52745ff40 100644
--- a/llvm/tools/opt/PrintSCC.cpp
+++ b/llvm/tools/opt/PrintSCC.cpp
@@ -76,10 +76,11 @@ bool CFGSCC::runOnFunction(Function &F) {
for (scc_iterator<Function*> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) {
const std::vector<BasicBlock *> &nextSCC = *SCCI;
errs() << "\nSCC #" << ++sccNum << " : ";
- for (std::vector<BasicBlock*>::const_iterator I = nextSCC.begin(),
- E = nextSCC.end(); I != E; ++I)
- errs() << (*I)->getName() << ", ";
- if (nextSCC.size() == 1 && SCCI.hasLoop())
+ for (BasicBlock *BB : nextSCC) {
+ BB->printAsOperand(errs(), false);
+ errs() << ", ";
+ }
+ if (nextSCC.size() == 1 && SCCI.hasCycle())
errs() << " (Has self-loop).";
}
errs() << "\n";
@@ -101,7 +102,7 @@ bool CallGraphSCC::runOnModule(Module &M) {
E = nextSCC.end(); I != E; ++I)
errs() << ((*I)->getFunction() ? (*I)->getFunction()->getName()
: "external node") << ", ";
- if (nextSCC.size() == 1 && SCCI.hasLoop())
+ if (nextSCC.size() == 1 && SCCI.hasCycle())
errs() << " (Has self-loop).";
}
errs() << "\n";
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;
}
}