diff options
Diffstat (limited to 'llvm/tools/opt')
-rw-r--r-- | llvm/tools/opt/AnalysisWrappers.cpp | 9 | ||||
-rw-r--r-- | llvm/tools/opt/NewPMDriver.cpp | 135 | ||||
-rw-r--r-- | llvm/tools/opt/NewPMDriver.h | 8 | ||||
-rw-r--r-- | llvm/tools/opt/PassPrinters.cpp | 82 | ||||
-rw-r--r-- | llvm/tools/opt/PassPrinters.h | 17 | ||||
-rw-r--r-- | llvm/tools/opt/PrintSCC.cpp | 11 | ||||
-rw-r--r-- | llvm/tools/opt/opt.cpp | 170 |
7 files changed, 257 insertions, 175 deletions
diff --git a/llvm/tools/opt/AnalysisWrappers.cpp b/llvm/tools/opt/AnalysisWrappers.cpp index b888605a516c7..2ae1da84a9a0f 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 ac04a32d93fd5..b94c58decdda2 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 b672c97c9aa35..7ae273a2c1f46 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 a877d9dc90f48..4e81b5d29c4d6 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 692befbdae758..a4e1921399fc6 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 419886d6cc60a..1ca52745ff400 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 75a6cdc3892b3..c250eefb8c430 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; } } |