aboutsummaryrefslogtreecommitdiffstats
path: root/tools/opt
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-04-23 16:57:46 -0700
committerStephen Hines <srhines@google.com>2014-04-24 15:53:16 -0700
commit36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch)
treee6cfb69fbbd937f450eeb83bfb83b9da3b01275a /tools/opt
parent69a8640022b04415ae9fac62f8ab090601d8f889 (diff)
downloadexternal_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'tools/opt')
-rw-r--r--tools/opt/AnalysisWrappers.cpp31
-rw-r--r--tools/opt/Android.mk4
-rw-r--r--tools/opt/BreakpointPrinter.cpp82
-rw-r--r--tools/opt/BreakpointPrinter.h25
-rw-r--r--tools/opt/CMakeLists.txt36
-rw-r--r--tools/opt/GraphPrinters.cpp11
-rw-r--r--tools/opt/LLVMBuild.txt2
-rw-r--r--tools/opt/Makefile5
-rw-r--r--tools/opt/NewPMDriver.cpp81
-rw-r--r--tools/opt/NewPMDriver.h55
-rw-r--r--tools/opt/PassPrinters.cpp260
-rw-r--r--tools/opt/PassPrinters.h47
-rw-r--r--tools/opt/Passes.cpp209
-rw-r--r--tools/opt/Passes.h57
-rw-r--r--tools/opt/PrintSCC.cpp25
-rw-r--r--tools/opt/opt.cpp415
16 files changed, 981 insertions, 364 deletions
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<Instruction>(*UI);
- if (!User) continue;
-
- CallSite CS(cast<Value>(User));
+ for (User *U : I->users()) {
+ Instruction *UI = dyn_cast<Instruction>(U);
+ if (!UI) continue;
+
+ CallSite CS(cast<Value>(UI));
if (!CS) continue;
-
+
for (CallSite::arg_iterator AI = CS.arg_begin(),
E = CS.arg_end(); AI != E; ++AI) {
if (!isa<Constant>(*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<CallGraph>();
+ AU.addRequiredTransitive<CallGraphWrapperPass>();
}
- virtual bool runOnModule(Module &M) {
- getAnalysis<CallGraph>().print(errs(), &M);
+ bool runOnModule(Module &M) override {
+ getAnalysis<CallGraphWrapperPass>().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<DominatorTree>();
-
+ AU.addRequired<DominatorTreeWrapperPass>();
}
- virtual bool runOnFunction(Function &F) {
- getAnalysis<DominatorTree>().dump();
+ bool runOnFunction(Function &F) override {
+ getAnalysis<DominatorTreeWrapperPass>().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 <string>
+
+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<Pass>(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<Pass>(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<Pass>(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<Pass>(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<Pass>(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<Pass>(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<CallGraph>();
+ AU.addRequired<CallGraphWrapperPass>();
}
};
}
@@ -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<Function*> SCCI = scc_begin(&F),
- E = scc_end(&F); SCCI != E; ++SCCI) {
+ for (scc_iterator<Function*> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) {
std::vector<BasicBlock*> &nextSCC = *SCCI;
errs() << "\nSCC #" << ++sccNum << " : ";
for (std::vector<BasicBlock*>::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<CallGraph>().getRoot();
+ CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
unsigned sccNum = 0;
errs() << "SCCs for the program in PostOrder:";
- for (scc_iterator<CallGraphNode*> SCCI = scc_begin(rootNode),
- E = scc_end(rootNode); SCCI != E; ++SCCI) {
+ for (scc_iterator<CallGraph*> SCCI = scc_begin(&CG); !SCCI.isAtEnd();
+ ++SCCI) {
const std::vector<CallGraphNode*> &nextSCC = *SCCI;
errs() << "\nSCC #" << ++sccNum << " : ";
for (std::vector<CallGraphNode*>::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 <algorithm>
#include <memory>
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<const PassInfo*, bool, PassNameParser>
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<std::string> PassPipeline(
+ "passes",
+ cl::desc("A textual description of the pass pipeline for optimizing"),
+ cl::Hidden);
+
// Other command line options...
//
static cl::opt<std::string>
@@ -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<Pass>(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<Pass>(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<Pass>(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<Pass>(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<Pass>(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<Pass>(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<Module> M;
+ std::unique_ptr<Module> 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<tool_output_file> Out;
+ std::unique_ptr<tool_output_file> 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<TargetMachine> TM(Machine);
+ std::unique_ptr<TargetMachine> TM(Machine);
// Add internal analysis passes from the target machine.
if (TM.get())
TM->addAnalysisPasses(Passes);
- OwningPtr<FunctionPassManager> FPasses;
+ std::unique_ptr<FunctionPassManager> 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()));
}