summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/Passes.h19
-rw-r--r--include/llvm/Target/TargetMachine.h9
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp27
-rw-r--r--lib/CodeGen/Passes.cpp18
-rw-r--r--lib/Target/CppBackend/CPPBackend.cpp4
-rw-r--r--lib/Target/CppBackend/CPPTargetMachine.h4
-rw-r--r--lib/Target/NVPTX/NVPTXTargetMachine.h6
-rw-r--r--test/CodeGen/Generic/stop-after.ll10
-rw-r--r--tools/llc/llc.cpp44
9 files changed, 118 insertions, 23 deletions
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index b7c81af442..4a24ab0d63 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -55,6 +55,10 @@ public:
private:
PassManagerBase *PM;
+ AnalysisID StartAfter;
+ AnalysisID StopAfter;
+ bool Started;
+ bool Stopped;
protected:
TargetMachine *TM;
@@ -92,6 +96,18 @@ public:
CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); }
+ /// setStartStopPasses - Set the StartAfter and StopAfter passes to allow
+ /// running only a portion of the normal code-gen pass sequence. If the
+ /// Start pass ID is zero, then compilation will begin at the normal point;
+ /// otherwise, clear the Started flag to indicate that passes should not be
+ /// added until the starting pass is seen. If the Stop pass ID is zero,
+ /// then compilation will continue to the end.
+ void setStartStopPasses(AnalysisID Start, AnalysisID Stop) {
+ StartAfter = Start;
+ StopAfter = Stop;
+ Started = (StartAfter == 0);
+ }
+
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
bool getEnableTailMerge() const { return EnableTailMerge; }
@@ -238,7 +254,8 @@ protected:
/// Return the pass that was added, or zero if no pass was added.
AnalysisID addPass(AnalysisID PassID);
- /// Add a pass to the PassManager.
+ /// Add a pass to the PassManager if that pass is supposed to be run, as
+ /// determined by the StartAfter and StopAfter options.
void addPass(Pass *P);
/// addMachinePasses helper to create the target-selected or overriden
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 1a0560478a..e4bf32bd86 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -14,6 +14,7 @@
#ifndef LLVM_TARGET_TARGETMACHINE_H
#define LLVM_TARGET_TARGETMACHINE_H
+#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/StringRef.h"
@@ -247,7 +248,9 @@ public:
virtual bool addPassesToEmitFile(PassManagerBase &,
formatted_raw_ostream &,
CodeGenFileType,
- bool /*DisableVerify*/ = true) {
+ bool /*DisableVerify*/ = true,
+ AnalysisID StartAfter = 0,
+ AnalysisID StopAfter = 0) {
return true;
}
@@ -297,7 +300,9 @@ public:
virtual bool addPassesToEmitFile(PassManagerBase &PM,
formatted_raw_ostream &Out,
CodeGenFileType FileType,
- bool DisableVerify = true);
+ bool DisableVerify = true,
+ AnalysisID StartAfter = 0,
+ AnalysisID StopAfter = 0);
/// addPassesToEmitMachineCode - Add passes to the specified pass manager to
/// get machine code emitted. This uses a JITCodeEmitter object to handle
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 5129caa977..cac0c83bca 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -13,6 +13,7 @@
#include "llvm/Transforms/Scalar.h"
#include "llvm/PassManager.h"
+#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
@@ -81,9 +82,12 @@ LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple,
/// addPassesToX helper drives creation and initialization of TargetPassConfig.
static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,
PassManagerBase &PM,
- bool DisableVerify) {
+ bool DisableVerify,
+ AnalysisID StartAfter,
+ AnalysisID StopAfter) {
// Targets may override createPassConfig to provide a target-specific sublass.
TargetPassConfig *PassConfig = TM->createPassConfig(PM);
+ PassConfig->setStartStopPasses(StartAfter, StopAfter);
// Set PassConfig options provided by TargetMachine.
PassConfig->setDisableVerify(DisableVerify);
@@ -127,12 +131,25 @@ static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
formatted_raw_ostream &Out,
CodeGenFileType FileType,
- bool DisableVerify) {
+ bool DisableVerify,
+ AnalysisID StartAfter,
+ AnalysisID StopAfter) {
// Add common CodeGen passes.
- MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify);
+ MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify,
+ StartAfter, StopAfter);
if (!Context)
return true;
+ if (StopAfter) {
+ // FIXME: The intent is that this should eventually write out a YAML file,
+ // containing the LLVM IR, the machine-level IR (when stopping after a
+ // machine-level pass), and whatever other information is needed to
+ // deserialize the code and resume compilation. For now, just write the
+ // LLVM IR.
+ PM.add(createPrintModulePass(&Out));
+ return false;
+ }
+
if (hasMCSaveTempLabels())
Context->setAllowTemporaryLabels(false);
@@ -216,7 +233,7 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
JITCodeEmitter &JCE,
bool DisableVerify) {
// Add common CodeGen passes.
- MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify);
+ MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify, 0, 0);
if (!Context)
return true;
@@ -236,7 +253,7 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
raw_ostream &Out,
bool DisableVerify) {
// Add common CodeGen passes.
- Ctx = addPassesToGenerateCode(this, PM, DisableVerify);
+ Ctx = addPassesToGenerateCode(this, PM, DisableVerify, 0, 0);
if (!Ctx)
return true;
diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp
index 20a3ff45e8..1fefb9d45f 100644
--- a/lib/CodeGen/Passes.cpp
+++ b/lib/CodeGen/Passes.cpp
@@ -213,7 +213,8 @@ TargetPassConfig::~TargetPassConfig() {
// Out of line constructor provides default values for pass options and
// registers all common codegen passes.
TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm)
- : ImmutablePass(ID), PM(&pm), TM(tm), Impl(0), Initialized(false),
+ : ImmutablePass(ID), PM(&pm), StartAfter(0), StopAfter(0),
+ Started(true), Stopped(false), TM(tm), Impl(0), Initialized(false),
DisableVerify(false),
EnableTailMerge(true) {
@@ -271,11 +272,22 @@ AnalysisID TargetPassConfig::getPassSubstitution(AnalysisID ID) const {
return I->second;
}
-/// Add a pass to the PassManager.
+/// Add a pass to the PassManager if that pass is supposed to be run. If the
+/// Started/Stopped flags indicate either that the compilation should start at
+/// a later pass or that it should stop after an earlier pass, then do not add
+/// the pass. Finally, compare the current pass against the StartAfter
+/// and StopAfter options and change the Started/Stopped flags accordingly.
void TargetPassConfig::addPass(Pass *P) {
assert(!Initialized && "PassConfig is immutable");
- PM->add(P);
+ if (Started && !Stopped)
+ PM->add(P);
+ if (StopAfter == P->getPassID())
+ Stopped = true;
+ if (StartAfter == P->getPassID())
+ Started = true;
+ if (Stopped && !Started)
+ report_fatal_error("Cannot stop compilation after pass that is not run");
}
/// Add a CodeGen pass at this point in the pipeline after checking for target
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index 0ea2a299dd..c8e757becc 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -2101,7 +2101,9 @@ char CppWriter::ID = 0;
bool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
formatted_raw_ostream &o,
CodeGenFileType FileType,
- bool DisableVerify) {
+ bool DisableVerify,
+ AnalysisID StartAfter,
+ AnalysisID StopAfter) {
if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
PM.add(new CppWriter(o));
return false;
diff --git a/lib/Target/CppBackend/CPPTargetMachine.h b/lib/Target/CppBackend/CPPTargetMachine.h
index 92bca6c3c7..9cbe7981a9 100644
--- a/lib/Target/CppBackend/CPPTargetMachine.h
+++ b/lib/Target/CppBackend/CPPTargetMachine.h
@@ -31,7 +31,9 @@ struct CPPTargetMachine : public TargetMachine {
virtual bool addPassesToEmitFile(PassManagerBase &PM,
formatted_raw_ostream &Out,
CodeGenFileType FileType,
- bool DisableVerify);
+ bool DisableVerify,
+ AnalysisID StartAfter,
+ AnalysisID StopAfter);
virtual const TargetData *getTargetData() const { return 0; }
};
diff --git a/lib/Target/NVPTX/NVPTXTargetMachine.h b/lib/Target/NVPTX/NVPTXTargetMachine.h
index 1d82e5c677..b3f9cace6b 100644
--- a/lib/Target/NVPTX/NVPTXTargetMachine.h
+++ b/lib/Target/NVPTX/NVPTXTargetMachine.h
@@ -48,12 +48,6 @@ class NVPTXTargetMachine : public LLVMTargetMachine {
// bool DisableVerify, MCContext *&OutCtx);
public:
- //virtual bool addPassesToEmitFile(PassManagerBase &PM,
- // formatted_raw_ostream &Out,
- // CodeGenFileType FileType,
- // CodeGenOpt::Level OptLevel,
- // bool DisableVerify = true) ;
-
NVPTXTargetMachine(const Target &T, StringRef TT, StringRef CPU,
StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
diff --git a/test/CodeGen/Generic/stop-after.ll b/test/CodeGen/Generic/stop-after.ll
new file mode 100644
index 0000000000..557e097840
--- /dev/null
+++ b/test/CodeGen/Generic/stop-after.ll
@@ -0,0 +1,10 @@
+; RUN: llc < %s -debug-pass=Structure -stop-after=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=STOP
+; RUN: llc < %s -debug-pass=Structure -start-after=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=START
+
+; STOP: -loop-reduce -print-module
+; STOP: Loop Strength Reduction
+; STOP-NEXT: Machine Function Analysis
+
+; START: -machine-branch-prob -gc-lowering
+; START: FunctionPass Manager
+; START-NEXT: Lower Garbage Collection Instructions
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 8095366875..5adfacb43a 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -18,6 +18,7 @@
#include "llvm/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/Support/IRReader.h"
#include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
#include "llvm/CodeGen/LinkAllCodegenComponents.h"
@@ -257,6 +258,15 @@ UseInitArray("use-init-array",
cl::desc("Use .init_array instead of .ctors."),
cl::init(false));
+static cl::opt<std::string> StopAfter("stop-after",
+ cl::desc("Stop compilation after a specific pass"),
+ cl::value_desc("pass-name"),
+ cl::init(""));
+static cl::opt<std::string> StartAfter("start-after",
+ cl::desc("Resume compilation after a specific pass"),
+ cl::value_desc("pass-name"),
+ cl::init(""));
+
// GetFileNameRoot - Helper function to get the basename of a filename.
static inline std::string
GetFileNameRoot(const std::string &InputFilename) {
@@ -353,9 +363,14 @@ int main(int argc, char **argv) {
InitializeAllAsmPrinters();
InitializeAllAsmParsers();
- // Initialize codegen so that the -print-after and -print-before options
- // work.
- initializeCodeGen(*PassRegistry::getPassRegistry());
+ // Initialize codegen and IR passes used by llc so that the -print-after,
+ // -print-before, and -stop-after options work.
+ PassRegistry *Registry = PassRegistry::getPassRegistry();
+ initializeCore(*Registry);
+ initializeCodeGen(*Registry);
+ initializeLoopStrengthReducePass(*Registry);
+ initializeLowerIntrinsicsPass(*Registry);
+ initializeUnreachableBlockElimPass(*Registry);
// Register the target printer for --version.
cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
@@ -498,8 +513,29 @@ int main(int argc, char **argv) {
{
formatted_raw_ostream FOS(Out->os());
+ AnalysisID StartAfterID = 0;
+ AnalysisID StopAfterID = 0;
+ const PassRegistry *PR = PassRegistry::getPassRegistry();
+ if (!StartAfter.empty()) {
+ const PassInfo *PI = PR->getPassInfo(StartAfter);
+ if (!PI) {
+ errs() << argv[0] << ": start-after pass is not registered.\n";
+ return 1;
+ }
+ StartAfterID = PI->getTypeInfo();
+ }
+ if (!StopAfter.empty()) {
+ const PassInfo *PI = PR->getPassInfo(StopAfter);
+ if (!PI) {
+ errs() << argv[0] << ": stop-after pass is not registered.\n";
+ return 1;
+ }
+ StopAfterID = PI->getTypeInfo();
+ }
+
// Ask the target to add backend passes as necessary.
- if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify)) {
+ if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify,
+ StartAfterID, StopAfterID)) {
errs() << argv[0] << ": target does not support generation of this"
<< " file type!\n";
return 1;