From 36b56886974eae4f9c5ebc96befd3e7bfe5de338 Mon Sep 17 00:00:00 2001 From: Stephen Hines Date: Wed, 23 Apr 2014 16:57:46 -0700 Subject: Update to LLVM 3.5a. Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617 --- tools/opt/AnalysisWrappers.cpp | 31 ++- tools/opt/Android.mk | 4 +- tools/opt/BreakpointPrinter.cpp | 82 ++++++++ tools/opt/BreakpointPrinter.h | 25 +++ tools/opt/CMakeLists.txt | 36 +++- tools/opt/GraphPrinters.cpp | 11 +- tools/opt/LLVMBuild.txt | 2 +- tools/opt/Makefile | 5 +- tools/opt/NewPMDriver.cpp | 81 ++++++++ tools/opt/NewPMDriver.h | 55 ++++++ tools/opt/PassPrinters.cpp | 260 +++++++++++++++++++++++++ tools/opt/PassPrinters.h | 47 +++++ tools/opt/Passes.cpp | 209 ++++++++++++++++++++ tools/opt/Passes.h | 57 ++++++ tools/opt/PrintSCC.cpp | 25 ++- tools/opt/opt.cpp | 415 +++++++++------------------------------- 16 files changed, 981 insertions(+), 364 deletions(-) create mode 100644 tools/opt/BreakpointPrinter.cpp create mode 100644 tools/opt/BreakpointPrinter.h create mode 100644 tools/opt/NewPMDriver.cpp create mode 100644 tools/opt/NewPMDriver.h create mode 100644 tools/opt/PassPrinters.cpp create mode 100644 tools/opt/PassPrinters.h create mode 100644 tools/opt/Passes.cpp create mode 100644 tools/opt/Passes.h (limited to 'tools/opt') diff --git a/tools/opt/AnalysisWrappers.cpp b/tools/opt/AnalysisWrappers.cpp index 55f544f..4bdc268 100644 --- a/tools/opt/AnalysisWrappers.cpp +++ b/tools/opt/AnalysisWrappers.cpp @@ -18,9 +18,9 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/CallGraph.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/Module.h" #include "llvm/Pass.h" -#include "llvm/Support/CallSite.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -32,19 +32,18 @@ namespace { struct ExternalFunctionsPassedConstants : public ModulePass { static char ID; // Pass ID, replacement for typeid ExternalFunctionsPassedConstants() : ModulePass(ID) {} - virtual bool runOnModule(Module &M) { + bool runOnModule(Module &M) override { for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (!I->isDeclaration()) continue; - + bool PrintedFn = false; - for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); - UI != E; ++UI) { - Instruction *User = dyn_cast(*UI); - if (!User) continue; - - CallSite CS(cast(User)); + for (User *U : I->users()) { + Instruction *UI = dyn_cast(U); + if (!UI) continue; + + CallSite CS(cast(UI)); if (!CS) continue; - + for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end(); AI != E; ++AI) { if (!isa(*AI)) continue; @@ -53,7 +52,7 @@ namespace { errs() << "Function '" << I->getName() << "':\n"; PrintedFn = true; } - errs() << *User; + errs() << *UI; break; } } @@ -62,7 +61,7 @@ namespace { return false; } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); } }; @@ -78,12 +77,12 @@ namespace { static char ID; // Pass ID, replacement for typeid CallGraphPrinter() : ModulePass(ID) {} - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); - AU.addRequiredTransitive(); + AU.addRequiredTransitive(); } - virtual bool runOnModule(Module &M) { - getAnalysis().print(errs(), &M); + bool runOnModule(Module &M) override { + getAnalysis().print(errs(), &M); return false; } }; diff --git a/tools/opt/Android.mk b/tools/opt/Android.mk index 77183aa..9ba9584 100644 --- a/tools/opt/Android.mk +++ b/tools/opt/Android.mk @@ -58,6 +58,7 @@ include $(BUILD_HOST_EXECUTABLE) # opt command line tool (target) #===---------------------------------------------------------------=== +ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS)) include $(CLEAR_VARS) LOCAL_MODULE := opt @@ -70,10 +71,11 @@ LOCAL_STATIC_LIBRARIES := $(llvm_opt_STATIC_LIBRARIES) LOCAL_SHARED_LIBRARIES := \ libcutils \ libdl \ - libstlport + libcxx include $(LLVM_ROOT_PATH)/llvm.mk include $(LLVM_DEVICE_BUILD_MK) include $(LLVM_GEN_INTRINSICS_MK) include $(BUILD_EXECUTABLE) +endif diff --git a/tools/opt/BreakpointPrinter.cpp b/tools/opt/BreakpointPrinter.cpp new file mode 100644 index 0000000..44f4a11 --- /dev/null +++ b/tools/opt/BreakpointPrinter.cpp @@ -0,0 +1,82 @@ +//===- BreakpointPrinter.cpp - Breakpoint location printer ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Breakpoint location printer. +/// +//===----------------------------------------------------------------------===// +#include "BreakpointPrinter.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +namespace { + +struct BreakpointPrinter : public ModulePass { + raw_ostream &Out; + static char ID; + DITypeIdentifierMap TypeIdentifierMap; + + BreakpointPrinter(raw_ostream &out) : ModulePass(ID), Out(out) {} + + void getContextName(DIDescriptor Context, std::string &N) { + if (Context.isNameSpace()) { + DINameSpace NS(Context); + if (!NS.getName().empty()) { + getContextName(NS.getContext(), N); + N = N + NS.getName().str() + "::"; + } + } else if (Context.isType()) { + DIType TY(Context); + if (!TY.getName().empty()) { + getContextName(TY.getContext().resolve(TypeIdentifierMap), N); + N = N + TY.getName().str() + "::"; + } + } + } + + bool runOnModule(Module &M) override { + TypeIdentifierMap.clear(); + NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu"); + if (CU_Nodes) + TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes); + + StringSet<> Processed; + if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + std::string Name; + DISubprogram SP(NMD->getOperand(i)); + assert((!SP || SP.isSubprogram()) && + "A MDNode in llvm.dbg.sp should be null or a DISubprogram."); + if (!SP) + continue; + getContextName(SP.getContext().resolve(TypeIdentifierMap), Name); + Name = Name + SP.getDisplayName().str(); + if (!Name.empty() && Processed.insert(Name)) { + Out << Name << "\n"; + } + } + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; + +char BreakpointPrinter::ID = 0; +} + +ModulePass *llvm::createBreakpointPrinter(raw_ostream &out) { + return new BreakpointPrinter(out); +} diff --git a/tools/opt/BreakpointPrinter.h b/tools/opt/BreakpointPrinter.h new file mode 100644 index 0000000..81c88e1 --- /dev/null +++ b/tools/opt/BreakpointPrinter.h @@ -0,0 +1,25 @@ +//===- BreakpointPrinter.h - Breakpoint location printer ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Breakpoint location printer. +/// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TOOLS_OPT_BREAKPOINTPRINTER_H +#define LLVM_TOOLS_OPT_BREAKPOINTPRINTER_H + +namespace llvm { + +class ModulePass; +class raw_ostream; + +ModulePass *createBreakpointPrinter(raw_ostream &out); +} + +#endif // LLVM_TOOLS_OPT_BREAKPOINTPRINTER_H diff --git a/tools/opt/CMakeLists.txt b/tools/opt/CMakeLists.txt index 9195911..1d3f08d 100644 --- a/tools/opt/CMakeLists.txt +++ b/tools/opt/CMakeLists.txt @@ -1,9 +1,43 @@ -set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} bitreader asmparser bitwriter irreader instrumentation scalaropts objcarcopts ipo vectorize) +set(LLVM_LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} + Analysis + BitWriter + CodeGen + Core + IPA + IPO + IRReader + InstCombine + Instrumentation + MC + ObjCARCOpts + ScalarOpts + Support + Target + TransformUtils + Vectorize + ) + +# Support plugins. +set(LLVM_NO_DEAD_STRIP 1) add_llvm_tool(opt AnalysisWrappers.cpp + BreakpointPrinter.cpp GraphPrinters.cpp + NewPMDriver.cpp + Passes.cpp + PassPrinters.cpp PrintSCC.cpp opt.cpp ) set_target_properties(opt PROPERTIES ENABLE_EXPORTS 1) + +if(WITH_POLLY AND LINK_POLLY_INTO_TOOLS) + target_link_libraries(opt Polly) + if(POLLY_LINK_LIBS) + foreach(lib ${POLLY_LINK_LIBS}) + target_link_libraries(opt ${lib}) + endforeach(lib) + endif(POLLY_LINK_LIBS) +endif(WITH_POLLY AND LINK_POLLY_INTO_TOOLS) diff --git a/tools/opt/GraphPrinters.cpp b/tools/opt/GraphPrinters.cpp index f271966..640edfe 100644 --- a/tools/opt/GraphPrinters.cpp +++ b/tools/opt/GraphPrinters.cpp @@ -14,7 +14,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/Dominators.h" +#include "llvm/IR/Dominators.h" #include "llvm/Pass.h" using namespace llvm; @@ -29,14 +29,13 @@ namespace { static char ID; // Pass identification, replacement for typeid DomInfoPrinter() : FunctionPass(ID) {} - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); - AU.addRequired(); - + AU.addRequired(); } - virtual bool runOnFunction(Function &F) { - getAnalysis().dump(); + bool runOnFunction(Function &F) override { + getAnalysis().dump(); return false; } }; diff --git a/tools/opt/LLVMBuild.txt b/tools/opt/LLVMBuild.txt index 77b9446..b3589f8 100644 --- a/tools/opt/LLVMBuild.txt +++ b/tools/opt/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = opt parent = Tools -required_libraries = AsmParser BitReader BitWriter IRReader IPO Instrumentation Scalar ObjCARC all-targets +required_libraries = AsmParser BitReader BitWriter CodeGen IRReader IPO Instrumentation Scalar ObjCARC all-targets diff --git a/tools/opt/Makefile b/tools/opt/Makefile index a451005..cfa9c31 100644 --- a/tools/opt/Makefile +++ b/tools/opt/Makefile @@ -9,6 +9,9 @@ LEVEL := ../.. TOOLNAME := opt -LINK_COMPONENTS := bitreader bitwriter asmparser irreader instrumentation scalaropts objcarcopts ipo vectorize all-targets +LINK_COMPONENTS := bitreader bitwriter asmparser irreader instrumentation scalaropts objcarcopts ipo vectorize all-targets codegen + +# Support plugins. +NO_DEAD_STRIP := 1 include $(LEVEL)/Makefile.common diff --git a/tools/opt/NewPMDriver.cpp b/tools/opt/NewPMDriver.cpp new file mode 100644 index 0000000..fc4a1bf --- /dev/null +++ b/tools/opt/NewPMDriver.cpp @@ -0,0 +1,81 @@ +//===- NewPMDriver.cpp - Driver for opt with new PM -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// This file is just a split of the code that logically belongs in opt.cpp but +/// that includes the new pass manager headers. +/// +//===----------------------------------------------------------------------===// + +#include "NewPMDriver.h" +#include "Passes.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/LazyCallGraph.h" +#include "llvm/Bitcode/BitcodeWriterPass.h" +#include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Verifier.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ToolOutputFile.h" + +using namespace llvm; +using namespace opt_tool; + +bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M, + tool_output_file *Out, StringRef PassPipeline, + OutputKind OK, VerifierKind VK) { + FunctionAnalysisManager FAM; + ModuleAnalysisManager MAM; + + // FIXME: Lift this registration of analysis passes into a .def file adjacent + // to the one used to associate names with passes. + MAM.registerPass(LazyCallGraphAnalysis()); + + // Cross register the analysis managers through their proxies. + MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM)); + FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM)); + + ModulePassManager MPM; + if (VK > VK_NoVerifier) + MPM.addPass(VerifierPass()); + + if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass)) { + errs() << Arg0 << ": unable to parse pass pipeline description.\n"; + return false; + } + + if (VK > VK_NoVerifier) + MPM.addPass(VerifierPass()); + + // Add any relevant output pass at the end of the pipeline. + switch (OK) { + case OK_NoOutput: + break; // No output pass needed. + case OK_OutputAssembly: + MPM.addPass(PrintModulePass(Out->os())); + break; + case OK_OutputBitcode: + MPM.addPass(BitcodeWriterPass(Out->os())); + break; + } + + // Before executing passes, print the final values of the LLVM options. + cl::PrintOptionValues(); + + // Now that we have all of the passes ready, run them. + MPM.run(&M, &MAM); + + // Declare success. + if (OK != OK_NoOutput) + Out->keep(); + return true; +} diff --git a/tools/opt/NewPMDriver.h b/tools/opt/NewPMDriver.h new file mode 100644 index 0000000..3661d3e --- /dev/null +++ b/tools/opt/NewPMDriver.h @@ -0,0 +1,55 @@ +//===- NewPMDriver.h - Function to drive opt with the new PM ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// A single function which is called to drive the opt behavior for the new +/// PassManager. +/// +/// This is only in a separate TU with a header to avoid including all of the +/// old pass manager headers and the new pass manager headers into the same +/// file. Eventually all of the routines here will get folded back into +/// opt.cpp. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_OPT_NEW_PM_DRIVER_H +#define LLVM_TOOLS_OPT_NEW_PM_DRIVER_H + +#include "llvm/ADT/StringRef.h" + +namespace llvm { +class LLVMContext; +class Module; +class tool_output_file; + +namespace opt_tool { +enum OutputKind { + OK_NoOutput, + OK_OutputAssembly, + OK_OutputBitcode +}; +enum VerifierKind { + VK_NoVerifier, + VK_VerifyInAndOut, + VK_VerifyEachPass +}; +} + +/// \brief Driver function to run the new pass manager over a module. +/// +/// This function only exists factored away from opt.cpp in order to prevent +/// inclusion of the new pass manager headers and the old headers into the same +/// file. It's interface is consequentially somewhat ad-hoc, but will go away +/// when the transition finishes. +bool runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M, + tool_output_file *Out, StringRef PassPipeline, + opt_tool::OutputKind OK, opt_tool::VerifierKind VK); +} + +#endif diff --git a/tools/opt/PassPrinters.cpp b/tools/opt/PassPrinters.cpp new file mode 100644 index 0000000..d699489 --- /dev/null +++ b/tools/opt/PassPrinters.cpp @@ -0,0 +1,260 @@ +//===- PassPrinters.cpp - Utilities to print analysis info for passes -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Utilities to print analysis info for various kinds of passes. +/// +//===----------------------------------------------------------------------===// +#include "PassPrinters.h" +#include "llvm/Analysis/CallGraphSCCPass.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/RegionPass.h" +#include "llvm/IR/Function.h" +#include "llvm/Pass.h" +#include + +using namespace llvm; + +namespace { + +struct FunctionPassPrinter : public FunctionPass { + const PassInfo *PassToPrint; + 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(); + PassName = "FunctionPass Printer: " + PassToPrintName; + } + + bool runOnFunction(Function &F) override { + if (!QuietPass) + Out << "Printing analysis '" << PassToPrint->getPassName() + << "' for function '" << F.getName() << "':\n"; + + // Get and print pass... + getAnalysisID(PassToPrint->getTypeInfo()).print(Out, F.getParent()); + return false; + } + + const char *getPassName() const override { return PassName.c_str(); } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(PassToPrint->getTypeInfo()); + AU.setPreservesAll(); + } +}; + +char FunctionPassPrinter::ID = 0; + +struct CallGraphSCCPassPrinter : public CallGraphSCCPass { + static char ID; + 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(); + PassName = "CallGraphSCCPass Printer: " + PassToPrintName; + } + + bool runOnSCC(CallGraphSCC &SCC) override { + if (!QuietPass) + Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; + + // Get and print pass... + for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { + Function *F = (*I)->getFunction(); + if (F) + getAnalysisID(PassToPrint->getTypeInfo()) + .print(Out, F->getParent()); + } + return false; + } + + const char *getPassName() const override { return PassName.c_str(); } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(PassToPrint->getTypeInfo()); + AU.setPreservesAll(); + } +}; + +char CallGraphSCCPassPrinter::ID = 0; + +struct ModulePassPrinter : public ModulePass { + static char ID; + 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(); + PassName = "ModulePass Printer: " + PassToPrintName; + } + + bool runOnModule(Module &M) override { + if (!QuietPass) + Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; + + // Get and print pass... + getAnalysisID(PassToPrint->getTypeInfo()).print(Out, &M); + return false; + } + + const char *getPassName() const override { return PassName.c_str(); } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(PassToPrint->getTypeInfo()); + AU.setPreservesAll(); + } +}; + +char ModulePassPrinter::ID = 0; + +struct LoopPassPrinter : public LoopPass { + static char ID; + 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(); + PassName = "LoopPass Printer: " + PassToPrintName; + } + + bool runOnLoop(Loop *L, LPPassManager &LPM) override { + if (!QuietPass) + Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; + + // Get and print pass... + getAnalysisID(PassToPrint->getTypeInfo()) + .print(Out, L->getHeader()->getParent()->getParent()); + return false; + } + + const char *getPassName() const override { return PassName.c_str(); } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(PassToPrint->getTypeInfo()); + AU.setPreservesAll(); + } +}; + +char LoopPassPrinter::ID = 0; + +struct RegionPassPrinter : public RegionPass { + static char ID; + 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(); + 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"; + } + // Get and print pass... + getAnalysisID(PassToPrint->getTypeInfo()) + .print(Out, R->getEntry()->getParent()->getParent()); + return false; + } + + const char *getPassName() const override { return PassName.c_str(); } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(PassToPrint->getTypeInfo()); + AU.setPreservesAll(); + } +}; + +char RegionPassPrinter::ID = 0; + +struct BasicBlockPassPrinter : public BasicBlockPass { + const PassInfo *PassToPrint; + raw_ostream &Out; + static char ID; + std::string PassName; + bool QuietPass; + + BasicBlockPassPrinter(const PassInfo *PI, raw_ostream &out, bool Quiet) + : BasicBlockPass(ID), PassToPrint(PI), Out(out), QuietPass(Quiet) { + std::string PassToPrintName = PassToPrint->getPassName(); + PassName = "BasicBlockPass Printer: " + PassToPrintName; + } + + bool runOnBasicBlock(BasicBlock &BB) override { + if (!QuietPass) + Out << "Printing Analysis info for BasicBlock '" << BB.getName() + << "': Pass " << PassToPrint->getPassName() << ":\n"; + + // Get and print pass... + getAnalysisID(PassToPrint->getTypeInfo()) + .print(Out, BB.getParent()->getParent()); + return false; + } + + const char *getPassName() const override { return PassName.c_str(); } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(PassToPrint->getTypeInfo()); + AU.setPreservesAll(); + } +}; + +char BasicBlockPassPrinter::ID = 0; +} + +FunctionPass *llvm::createFunctionPassPrinter(const PassInfo *PI, + raw_ostream &OS, bool Quiet) { + return new FunctionPassPrinter(PI, OS, Quiet); +} + +CallGraphSCCPass *llvm::createCallGraphPassPrinter(const PassInfo *PI, + raw_ostream &OS, + bool Quiet) { + return new CallGraphSCCPassPrinter(PI, OS, Quiet); +} + +ModulePass *llvm::createModulePassPrinter(const PassInfo *PI, raw_ostream &OS, + bool Quiet) { + return new ModulePassPrinter(PI, OS, Quiet); +} + +LoopPass *llvm::createLoopPassPrinter(const PassInfo *PI, raw_ostream &OS, + bool Quiet) { + return new LoopPassPrinter(PI, OS, Quiet); +} + +RegionPass *llvm::createRegionPassPrinter(const PassInfo *PI, raw_ostream &OS, + bool Quiet) { + return new RegionPassPrinter(PI, OS, Quiet); +} + +BasicBlockPass *llvm::createBasicBlockPassPrinter(const PassInfo *PI, + raw_ostream &OS, bool Quiet) { + return new BasicBlockPassPrinter(PI, OS, Quiet); +} diff --git a/tools/opt/PassPrinters.h b/tools/opt/PassPrinters.h new file mode 100644 index 0000000..cf46ef9 --- /dev/null +++ b/tools/opt/PassPrinters.h @@ -0,0 +1,47 @@ +//===- PassPrinters.h - Utilities to print analysis info for passes -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Utilities to print analysis info for various kinds of passes. +/// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TOOLS_OPT_PASSPRINTERS_H +#define LLVM_TOOLS_OPT_PASSPRINTERS_H + +namespace llvm { + +class BasicBlockPass; +class CallGraphSCCPass; +class FunctionPass; +class ModulePass; +class LoopPass; +class PassInfo; +class RegionPass; +class raw_ostream; + +FunctionPass *createFunctionPassPrinter(const PassInfo *PI, raw_ostream &out, + bool Quiet); + +CallGraphSCCPass *createCallGraphPassPrinter(const PassInfo *PI, + raw_ostream &out, bool Quiet); + +ModulePass *createModulePassPrinter(const PassInfo *PI, raw_ostream &out, + bool Quiet); + +LoopPass *createLoopPassPrinter(const PassInfo *PI, raw_ostream &out, + bool Quiet); + +RegionPass *createRegionPassPrinter(const PassInfo *PI, raw_ostream &out, + bool Quiet); + +BasicBlockPass *createBasicBlockPassPrinter(const PassInfo *PI, + raw_ostream &out, bool Quiet); +} + +#endif // LLVM_TOOLS_OPT_PASSPRINTERS_H diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp new file mode 100644 index 0000000..ffdf9bf --- /dev/null +++ b/tools/opt/Passes.cpp @@ -0,0 +1,209 @@ +//===- Passes.cpp - Parsing, selection, and running of passes -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// This file provides the infrastructure to parse and build a custom pass +/// manager based on a commandline flag. It also provides helpers to aid in +/// analyzing, debugging, and testing pass structures. +/// +//===----------------------------------------------------------------------===// + +#include "Passes.h" +#include "llvm/Analysis/LazyCallGraph.h" +#include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Verifier.h" +#include "llvm/Support/Debug.h" + +using namespace llvm; + +namespace { + +/// \brief No-op module pass which does nothing. +struct NoOpModulePass { + PreservedAnalyses run(Module *M) { return PreservedAnalyses::all(); } + static StringRef name() { return "NoOpModulePass"; } +}; + +/// \brief No-op function pass which does nothing. +struct NoOpFunctionPass { + PreservedAnalyses run(Function *F) { return PreservedAnalyses::all(); } + static StringRef name() { return "NoOpFunctionPass"; } +}; + +} // End anonymous namespace. + +// FIXME: Factor all of the parsing logic into a .def file that we include +// under different macros. +static bool isModulePassName(StringRef Name) { + if (Name == "no-op-module") return true; + if (Name == "print") return true; + if (Name == "print-cg") return true; + + return false; +} + +static bool isFunctionPassName(StringRef Name) { + if (Name == "no-op-function") return true; + if (Name == "print") return true; + + return false; +} + +static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) { + if (Name == "no-op-module") { + MPM.addPass(NoOpModulePass()); + return true; + } + if (Name == "print") { + MPM.addPass(PrintModulePass(dbgs())); + return true; + } + if (Name == "print-cg") { + MPM.addPass(LazyCallGraphPrinterPass(dbgs())); + return true; + } + return false; +} + +static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) { + if (Name == "no-op-function") { + FPM.addPass(NoOpFunctionPass()); + return true; + } + if (Name == "print") { + FPM.addPass(PrintFunctionPass(dbgs())); + return true; + } + return false; +} + +static bool parseFunctionPassPipeline(FunctionPassManager &FPM, + StringRef &PipelineText, + bool VerifyEachPass) { + for (;;) { + // Parse nested pass managers by recursing. + if (PipelineText.startswith("function(")) { + FunctionPassManager NestedFPM; + + // Parse the inner pipeline inte the nested manager. + PipelineText = PipelineText.substr(strlen("function(")); + if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) || + PipelineText.empty()) + return false; + assert(PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + FPM.addPass(std::move(NestedFPM)); + } else { + // Otherwise try to parse a pass name. + size_t End = PipelineText.find_first_of(",)"); + if (!parseFunctionPassName(FPM, PipelineText.substr(0, End))) + return false; + if (VerifyEachPass) + FPM.addPass(VerifierPass()); + + PipelineText = PipelineText.substr(End); + } + + if (PipelineText.empty() || PipelineText[0] == ')') + return true; + + assert(PipelineText[0] == ','); + PipelineText = PipelineText.substr(1); + } +} + +static bool parseModulePassPipeline(ModulePassManager &MPM, + StringRef &PipelineText, + bool VerifyEachPass) { + for (;;) { + // Parse nested pass managers by recursing. + if (PipelineText.startswith("module(")) { + ModulePassManager NestedMPM; + + // Parse the inner pipeline into the nested manager. + PipelineText = PipelineText.substr(strlen("module(")); + if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) || + PipelineText.empty()) + return false; + assert(PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Now add the nested manager as a module pass. + MPM.addPass(std::move(NestedMPM)); + } else if (PipelineText.startswith("function(")) { + FunctionPassManager NestedFPM; + + // Parse the inner pipeline inte the nested manager. + PipelineText = PipelineText.substr(strlen("function(")); + if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) || + PipelineText.empty()) + return false; + assert(PipelineText[0] == ')'); + PipelineText = PipelineText.substr(1); + + // Add the nested pass manager with the appropriate adaptor. + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM))); + } else { + // Otherwise try to parse a pass name. + size_t End = PipelineText.find_first_of(",)"); + if (!parseModulePassName(MPM, PipelineText.substr(0, End))) + return false; + if (VerifyEachPass) + MPM.addPass(VerifierPass()); + + PipelineText = PipelineText.substr(End); + } + + if (PipelineText.empty() || PipelineText[0] == ')') + return true; + + assert(PipelineText[0] == ','); + PipelineText = PipelineText.substr(1); + } +} + +// Primary pass pipeline description parsing routine. +// FIXME: Should this routine accept a TargetMachine or require the caller to +// pre-populate the analysis managers with target-specific stuff? +bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, + bool VerifyEachPass) { + // Look at the first entry to figure out which layer to start parsing at. + if (PipelineText.startswith("module(")) + return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) && + PipelineText.empty(); + if (PipelineText.startswith("function(")) { + FunctionPassManager FPM; + if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) || + !PipelineText.empty()) + return false; + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); + return true; + } + + // This isn't a direct pass manager name, look for the end of a pass name. + StringRef FirstName = + PipelineText.substr(0, PipelineText.find_first_of(",)")); + if (isModulePassName(FirstName)) + return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) && + PipelineText.empty(); + + if (isFunctionPassName(FirstName)) { + FunctionPassManager FPM; + if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) || + !PipelineText.empty()) + return false; + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); + return true; + } + + return false; +} diff --git a/tools/opt/Passes.h b/tools/opt/Passes.h new file mode 100644 index 0000000..3bd6752 --- /dev/null +++ b/tools/opt/Passes.h @@ -0,0 +1,57 @@ +//===- Passes.h - Parsing, selection, and running of passes -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// Interfaces for producing common pass manager configurations and parsing +/// textual pass specifications. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_OPT_PASSES_H +#define LLVM_TOOLS_OPT_PASSES_H + +#include "llvm/ADT/StringRef.h" + +namespace llvm { +class ModulePassManager; + +/// \brief Parse a textual pass pipeline description into a \c ModulePassManager. +/// +/// The format of the textual pass pipeline description looks something like: +/// +/// module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...) +/// +/// Pass managers have ()s describing the nest structure of passes. All passes +/// are comma separated. As a special shortcut, if the very first pass is not +/// a module pass (as a module pass manager is), this will automatically form +/// the shortest stack of pass managers that allow inserting that first pass. +/// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop passes +/// 'lpassN', all of these are valid: +/// +/// fpass1,fpass2,fpass3 +/// cgpass1,cgpass2,cgpass3 +/// lpass1,lpass2,lpass3 +/// +/// And they are equivalent to the following (resp.): +/// +/// module(function(fpass1,fpass2,fpass3)) +/// module(cgscc(cgpass1,cgpass2,cgpass3)) +/// module(function(loop(lpass1,lpass2,lpass3))) +/// +/// This shortcut is especially useful for debugging and testing small pass +/// combinations. Note that these shortcuts don't introduce any other magic. If +/// the sequence of passes aren't all the exact same kind of pass, it will be +/// an error. You cannot mix different levels implicitly, you must explicitly +/// form a pass manager in which to nest passes. +bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, + bool VerifyEachPass = true); + +} + +#endif diff --git a/tools/opt/PrintSCC.cpp b/tools/opt/PrintSCC.cpp index a502fa7..cbc0a55 100644 --- a/tools/opt/PrintSCC.cpp +++ b/tools/opt/PrintSCC.cpp @@ -27,9 +27,9 @@ #include "llvm/ADT/SCCIterator.h" #include "llvm/Analysis/CallGraph.h" +#include "llvm/IR/CFG.h" #include "llvm/IR/Module.h" #include "llvm/Pass.h" -#include "llvm/Support/CFG.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -37,11 +37,11 @@ namespace { struct CFGSCC : public FunctionPass { static char ID; // Pass identification, replacement for typeid CFGSCC() : FunctionPass(ID) {} - bool runOnFunction(Function& func); + bool runOnFunction(Function& func) override; - void print(raw_ostream &O, const Module* = 0) const { } + void print(raw_ostream &O, const Module* = 0) const override { } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); } }; @@ -51,14 +51,14 @@ namespace { CallGraphSCC() : ModulePass(ID) {} // run - Print out SCCs in the call graph for the specified module. - bool runOnModule(Module &M); + bool runOnModule(Module &M) override; - void print(raw_ostream &O, const Module* = 0) const { } + void print(raw_ostream &O, const Module* = 0) const override { } // getAnalysisUsage - This pass requires the CallGraph. - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); - AU.addRequired(); + AU.addRequired(); } }; } @@ -74,8 +74,7 @@ Z("print-callgraph-sccs", "Print SCCs of the Call Graph"); bool CFGSCC::runOnFunction(Function &F) { unsigned sccNum = 0; errs() << "SCCs for Function " << F.getName() << " in PostOrder:"; - for (scc_iterator SCCI = scc_begin(&F), - E = scc_end(&F); SCCI != E; ++SCCI) { + for (scc_iterator SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) { std::vector &nextSCC = *SCCI; errs() << "\nSCC #" << ++sccNum << " : "; for (std::vector::const_iterator I = nextSCC.begin(), @@ -92,11 +91,11 @@ bool CFGSCC::runOnFunction(Function &F) { // run - Print out SCCs in the call graph for the specified module. bool CallGraphSCC::runOnModule(Module &M) { - CallGraphNode* rootNode = getAnalysis().getRoot(); + CallGraph &CG = getAnalysis().getCallGraph(); unsigned sccNum = 0; errs() << "SCCs for the program in PostOrder:"; - for (scc_iterator SCCI = scc_begin(rootNode), - E = scc_end(rootNode); SCCI != E; ++SCCI) { + for (scc_iterator SCCI = scc_begin(&CG); !SCCI.isAtEnd(); + ++SCCI) { const std::vector &nextSCC = *SCCI; errs() << "\nSCC #" << ++sccNum << " : "; for (std::vector::const_iterator I = nextSCC.begin(), diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index dba16f7..5a19881 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -12,28 +12,30 @@ // //===----------------------------------------------------------------------===// -#include "llvm/IR/LLVMContext.h" -#include "llvm/ADT/StringSet.h" +#include "BreakpointPrinter.h" +#include "NewPMDriver.h" +#include "PassPrinters.h" #include "llvm/ADT/Triple.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/RegionPass.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Assembly/PrintModulePass.h" -#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/Bitcode/BitcodeWriterPass.h" #include "llvm/CodeGen/CommandFlags.h" -#include "llvm/DebugInfo.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LegacyPassNameParser.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" +#include "llvm/InitializePasses.h" #include "llvm/LinkAllIR.h" #include "llvm/LinkAllPasses.h" #include "llvm/MC/SubtargetFeature.h" #include "llvm/PassManager.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/PassNameParser.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" @@ -48,6 +50,7 @@ #include #include using namespace llvm; +using namespace opt_tool; // The OptimizationList is automatically populated with registered Passes by the // PassNameParser. @@ -55,6 +58,15 @@ using namespace llvm; static cl::list PassList(cl::desc("Optimizations available:")); +// 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 +// pass management. +static cl::opt PassPipeline( + "passes", + cl::desc("A textual description of the pass pipeline for optimizing"), + cl::Hidden); + // Other command line options... // static cl::opt @@ -172,265 +184,7 @@ DefaultDataLayout("default-data-layout", cl::desc("data layout string to use if not specified by module"), cl::value_desc("layout-string"), cl::init("")); -// ---------- Define Printers for module and function passes ------------ -namespace { - -struct CallGraphSCCPassPrinter : public CallGraphSCCPass { - static char ID; - const PassInfo *PassToPrint; - raw_ostream &Out; - std::string PassName; - - CallGraphSCCPassPrinter(const PassInfo *PI, raw_ostream &out) : - CallGraphSCCPass(ID), PassToPrint(PI), Out(out) { - std::string PassToPrintName = PassToPrint->getPassName(); - PassName = "CallGraphSCCPass Printer: " + PassToPrintName; - } - - virtual bool runOnSCC(CallGraphSCC &SCC) { - if (!Quiet) - Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; - - // Get and print pass... - for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { - Function *F = (*I)->getFunction(); - if (F) - getAnalysisID(PassToPrint->getTypeInfo()).print(Out, - F->getParent()); - } - return false; - } - - virtual const char *getPassName() const { return PassName.c_str(); } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(PassToPrint->getTypeInfo()); - AU.setPreservesAll(); - } -}; - -char CallGraphSCCPassPrinter::ID = 0; - -struct ModulePassPrinter : public ModulePass { - static char ID; - const PassInfo *PassToPrint; - raw_ostream &Out; - std::string PassName; - - ModulePassPrinter(const PassInfo *PI, raw_ostream &out) - : ModulePass(ID), PassToPrint(PI), Out(out) { - std::string PassToPrintName = PassToPrint->getPassName(); - PassName = "ModulePass Printer: " + PassToPrintName; - } - - virtual bool runOnModule(Module &M) { - if (!Quiet) - Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; - - // Get and print pass... - getAnalysisID(PassToPrint->getTypeInfo()).print(Out, &M); - return false; - } - - virtual const char *getPassName() const { return PassName.c_str(); } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(PassToPrint->getTypeInfo()); - AU.setPreservesAll(); - } -}; - -char ModulePassPrinter::ID = 0; -struct FunctionPassPrinter : public FunctionPass { - const PassInfo *PassToPrint; - raw_ostream &Out; - static char ID; - std::string PassName; - - FunctionPassPrinter(const PassInfo *PI, raw_ostream &out) - : FunctionPass(ID), PassToPrint(PI), Out(out) { - std::string PassToPrintName = PassToPrint->getPassName(); - PassName = "FunctionPass Printer: " + PassToPrintName; - } - - virtual bool runOnFunction(Function &F) { - if (!Quiet) - Out << "Printing analysis '" << PassToPrint->getPassName() - << "' for function '" << F.getName() << "':\n"; - - // Get and print pass... - getAnalysisID(PassToPrint->getTypeInfo()).print(Out, - F.getParent()); - return false; - } - - virtual const char *getPassName() const { return PassName.c_str(); } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(PassToPrint->getTypeInfo()); - AU.setPreservesAll(); - } -}; - -char FunctionPassPrinter::ID = 0; - -struct LoopPassPrinter : public LoopPass { - static char ID; - const PassInfo *PassToPrint; - raw_ostream &Out; - std::string PassName; - - LoopPassPrinter(const PassInfo *PI, raw_ostream &out) : - LoopPass(ID), PassToPrint(PI), Out(out) { - std::string PassToPrintName = PassToPrint->getPassName(); - PassName = "LoopPass Printer: " + PassToPrintName; - } - - - virtual bool runOnLoop(Loop *L, LPPassManager &LPM) { - if (!Quiet) - Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; - - // Get and print pass... - getAnalysisID(PassToPrint->getTypeInfo()).print(Out, - L->getHeader()->getParent()->getParent()); - return false; - } - - virtual const char *getPassName() const { return PassName.c_str(); } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(PassToPrint->getTypeInfo()); - AU.setPreservesAll(); - } -}; - -char LoopPassPrinter::ID = 0; - -struct RegionPassPrinter : public RegionPass { - static char ID; - const PassInfo *PassToPrint; - raw_ostream &Out; - std::string PassName; - - RegionPassPrinter(const PassInfo *PI, raw_ostream &out) : RegionPass(ID), - PassToPrint(PI), Out(out) { - std::string PassToPrintName = PassToPrint->getPassName(); - PassName = "RegionPass Printer: " + PassToPrintName; - } - - virtual bool runOnRegion(Region *R, RGPassManager &RGM) { - if (!Quiet) { - Out << "Printing analysis '" << PassToPrint->getPassName() << "' for " - << "region: '" << R->getNameStr() << "' in function '" - << R->getEntry()->getParent()->getName() << "':\n"; - } - // Get and print pass... - getAnalysisID(PassToPrint->getTypeInfo()).print(Out, - R->getEntry()->getParent()->getParent()); - return false; - } - - virtual const char *getPassName() const { return PassName.c_str(); } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(PassToPrint->getTypeInfo()); - AU.setPreservesAll(); - } -}; - -char RegionPassPrinter::ID = 0; - -struct BasicBlockPassPrinter : public BasicBlockPass { - const PassInfo *PassToPrint; - raw_ostream &Out; - static char ID; - std::string PassName; - - BasicBlockPassPrinter(const PassInfo *PI, raw_ostream &out) - : BasicBlockPass(ID), PassToPrint(PI), Out(out) { - std::string PassToPrintName = PassToPrint->getPassName(); - PassName = "BasicBlockPass Printer: " + PassToPrintName; - } - - virtual bool runOnBasicBlock(BasicBlock &BB) { - if (!Quiet) - Out << "Printing Analysis info for BasicBlock '" << BB.getName() - << "': Pass " << PassToPrint->getPassName() << ":\n"; - - // Get and print pass... - getAnalysisID(PassToPrint->getTypeInfo()).print(Out, - BB.getParent()->getParent()); - return false; - } - - virtual const char *getPassName() const { return PassName.c_str(); } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequiredID(PassToPrint->getTypeInfo()); - AU.setPreservesAll(); - } -}; - -char BasicBlockPassPrinter::ID = 0; - -struct BreakpointPrinter : public ModulePass { - raw_ostream &Out; - static char ID; - DITypeIdentifierMap TypeIdentifierMap; - - BreakpointPrinter(raw_ostream &out) - : ModulePass(ID), Out(out) { - } - - void getContextName(DIDescriptor Context, std::string &N) { - if (Context.isNameSpace()) { - DINameSpace NS(Context); - if (!NS.getName().empty()) { - getContextName(NS.getContext(), N); - N = N + NS.getName().str() + "::"; - } - } else if (Context.isType()) { - DIType TY(Context); - if (!TY.getName().empty()) { - getContextName(TY.getContext().resolve(TypeIdentifierMap), N); - N = N + TY.getName().str() + "::"; - } - } - } - - virtual bool runOnModule(Module &M) { - TypeIdentifierMap.clear(); - NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu"); - if (CU_Nodes) - TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes); - - StringSet<> Processed; - if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) - for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { - std::string Name; - DISubprogram SP(NMD->getOperand(i)); - assert((!SP || SP.isSubprogram()) && - "A MDNode in llvm.dbg.sp should be null or a DISubprogram."); - if (!SP) - continue; - getContextName(SP.getContext().resolve(TypeIdentifierMap), Name); - Name = Name + SP.getDisplayName().str(); - if (!Name.empty() && Processed.insert(Name)) { - Out << Name << "\n"; - } - } - return false; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - } -}; - -} // anonymous namespace - -char BreakpointPrinter::ID = 0; static inline void addPass(PassManagerBase &PM, Pass *P) { // Add the pass to the pass manager... @@ -456,14 +210,7 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, if (DisableInline) { // No inlining pass } else if (OptLevel > 1) { - unsigned Threshold = 225; - if (SizeLevel == 1) // -Os - Threshold = 75; - else if (SizeLevel == 2) // -Oz - Threshold = 25; - if (OptLevel > 2) - Threshold = 275; - Builder.Inliner = createFunctionInliningPass(Threshold); + Builder.Inliner = createFunctionInliningPass(OptLevel, SizeLevel); } else { Builder.Inliner = createAlwaysInlinerPass(); } @@ -471,8 +218,14 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ? DisableLoopUnrolling : OptLevel == 0; - Builder.LoopVectorize = - DisableLoopVectorization ? false : OptLevel > 1 && SizeLevel < 2; + // 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) + 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; @@ -514,29 +267,6 @@ static void AddStandardLinkPasses(PassManagerBase &PM) { //===----------------------------------------------------------------------===// // CodeGen-related helper functions. // -static TargetOptions GetTargetOptions() { - TargetOptions Options; - Options.LessPreciseFPMADOption = EnableFPMAD; - Options.NoFramePointerElim = DisableFPElim; - Options.AllowFPOpFusion = FuseFPOps; - Options.UnsafeFPMath = EnableUnsafeFPMath; - Options.NoInfsFPMath = EnableNoInfsFPMath; - Options.NoNaNsFPMath = EnableNoNaNsFPMath; - Options.HonorSignDependentRoundingFPMathOption = - EnableHonorSignDependentRoundingFPMath; - Options.UseSoftFloat = GenerateSoftFloatCalls; - if (FloatABIForCalls != FloatABI::Default) - Options.FloatABIType = FloatABIForCalls; - Options.NoZerosInBSS = DontPlaceZerosInBSS; - Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; - Options.DisableTailCalls = DisableTailCalls; - Options.StackAlignmentOverride = OverrideStackAlignment; - Options.TrapFuncName = TrapFuncName; - Options.PositionIndependentExecutable = EnablePIE; - Options.EnableSegmentedStacks = SegmentedStacks; - Options.UseInitArray = UseInitArray; - return Options; -} CodeGenOpt::Level GetCodeGenOptLevel() { if (OptLevelO1) @@ -568,11 +298,18 @@ static TargetMachine* GetTargetMachine(Triple TheTriple) { } return TheTarget->createTargetMachine(TheTriple.getTriple(), - MCPU, FeaturesStr, GetTargetOptions(), + MCPU, FeaturesStr, + InitTargetOptionsFromCodeGenFlags(), RelocModel, CMModel, GetCodeGenOptLevel()); } +#ifdef LINK_POLLY_INTO_TOOLS +namespace polly { +void initializePollyPasses(llvm::PassRegistry &Registry); +} +#endif + //===----------------------------------------------------------------------===// // main for opt // @@ -603,6 +340,13 @@ int main(int argc, char **argv) { initializeInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); + // For codegen passes, only passes that do IR to IR transformation are + // supported. For now, just add CodeGenPrepare. + initializeCodeGenPreparePass(Registry); + +#ifdef LINK_POLLY_INTO_TOOLS + polly::initializePollyPasses(Registry); +#endif cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); @@ -615,7 +359,7 @@ int main(int argc, char **argv) { SMDiagnostic Err; // Load the input module... - OwningPtr M; + std::unique_ptr M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { @@ -628,7 +372,7 @@ int main(int argc, char **argv) { M->setTargetTriple(Triple::normalize(TargetTriple)); // Figure out what stream we are supposed to write to... - OwningPtr Out; + std::unique_ptr Out; if (NoOutput) { if (!OutputFilename.empty()) errs() << "WARNING: The -o (output filename) option is ignored when\n" @@ -640,7 +384,7 @@ int main(int argc, char **argv) { std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, - sys::fs::F_Binary)); + sys::fs::F_None)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; @@ -654,6 +398,26 @@ int main(int argc, char **argv) { if (CheckBitcodeOutputToConsole(Out->os(), !Quiet)) NoOutput = true; + if (PassPipeline.getNumOccurrences() > 0) { + OutputKind OK = OK_NoOutput; + if (!NoOutput) + OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode; + + VerifierKind VK = VK_VerifyInAndOut; + if (NoVerify) + VK = VK_NoVerifier; + else if (VerifyEach) + VK = VK_VerifyEachPass; + + // The user has asked to use the new pass manager and provided a pipeline + // string. Hand off the rest of the functionality to the new code for that + // layer. + return runPassPipeline(argv[0], Context, *M.get(), Out.get(), PassPipeline, + OK, VK) + ? 0 + : 1; + } + // Create a PassManager to hold and optimize the collection of passes we are // about to build. // @@ -668,31 +432,30 @@ int main(int argc, char **argv) { Passes.add(TLI); // Add an appropriate DataLayout instance for this module. - DataLayout *TD = 0; - const std::string &ModuleDataLayout = M.get()->getDataLayout(); - if (!ModuleDataLayout.empty()) - TD = new DataLayout(ModuleDataLayout); - else if (!DefaultDataLayout.empty()) - TD = new DataLayout(DefaultDataLayout); + const DataLayout *DL = M.get()->getDataLayout(); + if (!DL && !DefaultDataLayout.empty()) { + M->setDataLayout(DefaultDataLayout); + DL = M.get()->getDataLayout(); + } - if (TD) - Passes.add(TD); + if (DL) + Passes.add(new DataLayoutPass(M.get())); Triple ModuleTriple(M->getTargetTriple()); TargetMachine *Machine = 0; if (ModuleTriple.getArch()) Machine = GetTargetMachine(Triple(ModuleTriple)); - OwningPtr TM(Machine); + std::unique_ptr TM(Machine); // Add internal analysis passes from the target machine. if (TM.get()) TM->addAnalysisPasses(Passes); - OwningPtr FPasses; + std::unique_ptr FPasses; if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses.reset(new FunctionPassManager(M.get())); - if (TD) - FPasses->add(new DataLayout(*TD)); + if (DL) + FPasses->add(new DataLayoutPass(M.get())); if (TM.get()) TM->addAnalysisPasses(*FPasses); @@ -706,13 +469,13 @@ int main(int argc, char **argv) { std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, - sys::fs::F_Binary)); + sys::fs::F_None)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } } - Passes.add(new BreakpointPrinter(Out->os())); + Passes.add(createBreakpointPrinter(Out->os())); NoOutput = true; } @@ -764,7 +527,9 @@ int main(int argc, char **argv) { const PassInfo *PassInf = PassList[i]; Pass *P = 0; - if (PassInf->getNormalCtor()) + if (PassInf->getTargetMachineCtor()) + P = PassInf->getTargetMachineCtor()(TM.get()); + else if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); else errs() << argv[0] << ": cannot create pass: " @@ -776,29 +541,29 @@ int main(int argc, char **argv) { if (AnalyzeOnly) { switch (Kind) { case PT_BasicBlock: - Passes.add(new BasicBlockPassPrinter(PassInf, Out->os())); + Passes.add(createBasicBlockPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_Region: - Passes.add(new RegionPassPrinter(PassInf, Out->os())); + Passes.add(createRegionPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_Loop: - Passes.add(new LoopPassPrinter(PassInf, Out->os())); + Passes.add(createLoopPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_Function: - Passes.add(new FunctionPassPrinter(PassInf, Out->os())); + Passes.add(createFunctionPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_CallGraphSCC: - Passes.add(new CallGraphSCCPassPrinter(PassInf, Out->os())); + Passes.add(createCallGraphPassPrinter(PassInf, Out->os(), Quiet)); break; default: - Passes.add(new ModulePassPrinter(PassInf, Out->os())); + Passes.add(createModulePassPrinter(PassInf, Out->os(), Quiet)); break; } } } if (PrintEachXForm) - Passes.add(createPrintModulePass(&errs())); + Passes.add(createPrintModulePass(errs())); } // If -std-compile-opts was specified at the end of the pass list, add them. @@ -841,7 +606,7 @@ int main(int argc, char **argv) { // Write bitcode or assembly to the output as the last step... if (!NoOutput && !AnalyzeOnly) { if (OutputAssembly) - Passes.add(createPrintModulePass(&Out->os())); + Passes.add(createPrintModulePass(Out->os())); else Passes.add(createBitcodeWriterPass(Out->os())); } -- cgit v1.1