llvm.org GIT mirror llvm / 30a507a
Extend TargetPassConfig to allow running only a subset of the normal passes. This is still a work in progress but I believe it is currently good enough to fix PR13122 "Need unit test driver for codegen IR passes". For example, you can run llc with -stop-after=loop-reduce to have it dump out the IR after running LSR. Serializing machine-level IR is not yet supported but we have some patches in progress for that. The plan is to serialize the IR to a YAML file, containing separate sections for the LLVM IR, machine-level IR, and whatever other info is needed. Chad suggested that we stash the stop-after pass in the YAML file and use that instead of the start-after option to figure out where to restart the compilation. I think that's a great idea, but since it's not implemented yet I put the -start-after option into this patch for testing purposes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159570 91177308-0d34-0410-b5e6-96231b3b80d8 Bob Wilson 8 years ago
9 changed file(s) with 118 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
5454
5555 private:
5656 PassManagerBase *PM;
57 AnalysisID StartAfter;
58 AnalysisID StopAfter;
59 bool Started;
60 bool Stopped;
5761
5862 protected:
5963 TargetMachine *TM;
9094 void setInitialized() { Initialized = true; }
9195
9296 CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); }
97
98 /// setStartStopPasses - Set the StartAfter and StopAfter passes to allow
99 /// running only a portion of the normal code-gen pass sequence. If the
100 /// Start pass ID is zero, then compilation will begin at the normal point;
101 /// otherwise, clear the Started flag to indicate that passes should not be
102 /// added until the starting pass is seen. If the Stop pass ID is zero,
103 /// then compilation will continue to the end.
104 void setStartStopPasses(AnalysisID Start, AnalysisID Stop) {
105 StartAfter = Start;
106 StopAfter = Stop;
107 Started = (StartAfter == 0);
108 }
93109
94110 void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
95111
237253 /// Return the pass that was added, or zero if no pass was added.
238254 AnalysisID addPass(AnalysisID PassID);
239255
240 /// Add a pass to the PassManager.
256 /// Add a pass to the PassManager if that pass is supposed to be run, as
257 /// determined by the StartAfter and StopAfter options.
241258 void addPass(Pass *P);
242259
243260 /// addMachinePasses helper to create the target-selected or overriden
1313 #ifndef LLVM_TARGET_TARGETMACHINE_H
1414 #define LLVM_TARGET_TARGETMACHINE_H
1515
16 #include "llvm/Pass.h"
1617 #include "llvm/Support/CodeGen.h"
1718 #include "llvm/Target/TargetOptions.h"
1819 #include "llvm/ADT/StringRef.h"
246247 virtual bool addPassesToEmitFile(PassManagerBase &,
247248 formatted_raw_ostream &,
248249 CodeGenFileType,
249 bool /*DisableVerify*/ = true) {
250 bool /*DisableVerify*/ = true,
251 AnalysisID StartAfter = 0,
252 AnalysisID StopAfter = 0) {
250253 return true;
251254 }
252255
296299 virtual bool addPassesToEmitFile(PassManagerBase &PM,
297300 formatted_raw_ostream &Out,
298301 CodeGenFileType FileType,
299 bool DisableVerify = true);
302 bool DisableVerify = true,
303 AnalysisID StartAfter = 0,
304 AnalysisID StopAfter = 0);
300305
301306 /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
302307 /// get machine code emitted. This uses a JITCodeEmitter object to handle
1212
1313 #include "llvm/Transforms/Scalar.h"
1414 #include "llvm/PassManager.h"
15 #include "llvm/Assembly/PrintModulePass.h"
1516 #include "llvm/CodeGen/AsmPrinter.h"
1617 #include "llvm/CodeGen/Passes.h"
1718 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
8081 /// addPassesToX helper drives creation and initialization of TargetPassConfig.
8182 static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,
8283 PassManagerBase &PM,
83 bool DisableVerify) {
84 bool DisableVerify,
85 AnalysisID StartAfter,
86 AnalysisID StopAfter) {
8487 // Targets may override createPassConfig to provide a target-specific sublass.
8588 TargetPassConfig *PassConfig = TM->createPassConfig(PM);
89 PassConfig->setStartStopPasses(StartAfter, StopAfter);
8690
8791 // Set PassConfig options provided by TargetMachine.
8892 PassConfig->setDisableVerify(DisableVerify);
126130 bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
127131 formatted_raw_ostream &Out,
128132 CodeGenFileType FileType,
129 bool DisableVerify) {
133 bool DisableVerify,
134 AnalysisID StartAfter,
135 AnalysisID StopAfter) {
130136 // Add common CodeGen passes.
131 MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify);
137 MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify,
138 StartAfter, StopAfter);
132139 if (!Context)
133140 return true;
141
142 if (StopAfter) {
143 // FIXME: The intent is that this should eventually write out a YAML file,
144 // containing the LLVM IR, the machine-level IR (when stopping after a
145 // machine-level pass), and whatever other information is needed to
146 // deserialize the code and resume compilation. For now, just write the
147 // LLVM IR.
148 PM.add(createPrintModulePass(&Out));
149 return false;
150 }
134151
135152 if (hasMCSaveTempLabels())
136153 Context->setAllowTemporaryLabels(false);
215232 JITCodeEmitter &JCE,
216233 bool DisableVerify) {
217234 // Add common CodeGen passes.
218 MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify);
235 MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify, 0, 0);
219236 if (!Context)
220237 return true;
221238
235252 raw_ostream &Out,
236253 bool DisableVerify) {
237254 // Add common CodeGen passes.
238 Ctx = addPassesToGenerateCode(this, PM, DisableVerify);
255 Ctx = addPassesToGenerateCode(this, PM, DisableVerify, 0, 0);
239256 if (!Ctx)
240257 return true;
241258
212212 // Out of line constructor provides default values for pass options and
213213 // registers all common codegen passes.
214214 TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm)
215 : ImmutablePass(ID), PM(&pm), TM(tm), Impl(0), Initialized(false),
215 : ImmutablePass(ID), PM(&pm), StartAfter(0), StopAfter(0),
216 Started(true), Stopped(false), TM(tm), Impl(0), Initialized(false),
216217 DisableVerify(false),
217218 EnableTailMerge(true) {
218219
270271 return I->second;
271272 }
272273
273 /// Add a pass to the PassManager.
274 /// Add a pass to the PassManager if that pass is supposed to be run. If the
275 /// Started/Stopped flags indicate either that the compilation should start at
276 /// a later pass or that it should stop after an earlier pass, then do not add
277 /// the pass. Finally, compare the current pass against the StartAfter
278 /// and StopAfter options and change the Started/Stopped flags accordingly.
274279 void TargetPassConfig::addPass(Pass *P) {
275280 assert(!Initialized && "PassConfig is immutable");
276281
277 PM->add(P);
282 if (Started && !Stopped)
283 PM->add(P);
284 if (StopAfter == P->getPassID())
285 Stopped = true;
286 if (StartAfter == P->getPassID())
287 Started = true;
288 if (Stopped && !Started)
289 report_fatal_error("Cannot stop compilation after pass that is not run");
278290 }
279291
280292 /// Add a CodeGen pass at this point in the pipeline after checking for target
21002100 bool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
21012101 formatted_raw_ostream &o,
21022102 CodeGenFileType FileType,
2103 bool DisableVerify) {
2103 bool DisableVerify,
2104 AnalysisID StartAfter,
2105 AnalysisID StopAfter) {
21042106 if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
21052107 PM.add(new CppWriter(o));
21062108 return false;
3030 virtual bool addPassesToEmitFile(PassManagerBase &PM,
3131 formatted_raw_ostream &Out,
3232 CodeGenFileType FileType,
33 bool DisableVerify);
33 bool DisableVerify,
34 AnalysisID StartAfter,
35 AnalysisID StopAfter);
3436
3537 virtual const TargetData *getTargetData() const { return 0; }
3638 };
4747 // bool DisableVerify, MCContext *&OutCtx);
4848
4949 public:
50 //virtual bool addPassesToEmitFile(PassManagerBase &PM,
51 // formatted_raw_ostream &Out,
52 // CodeGenFileType FileType,
53 // CodeGenOpt::Level OptLevel,
54 // bool DisableVerify = true) ;
55
5650 NVPTXTargetMachine(const Target &T, StringRef TT, StringRef CPU,
5751 StringRef FS, const TargetOptions &Options,
5852 Reloc::Model RM, CodeModel::Model CM,
0 ; RUN: llc < %s -debug-pass=Structure -stop-after=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=STOP
1 ; RUN: llc < %s -debug-pass=Structure -start-after=loop-reduce -o /dev/null 2>&1 | FileCheck %s -check-prefix=START
2
3 ; STOP: -loop-reduce -print-module
4 ; STOP: Loop Strength Reduction
5 ; STOP-NEXT: Machine Function Analysis
6
7 ; START: -machine-branch-prob -gc-lowering
8 ; START: FunctionPass Manager
9 ; START-NEXT: Lower Garbage Collection Instructions
1717 #include "llvm/PassManager.h"
1818 #include "llvm/Pass.h"
1919 #include "llvm/ADT/Triple.h"
20 #include "llvm/Assembly/PrintModulePass.h"
2021 #include "llvm/Support/IRReader.h"
2122 #include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
2223 #include "llvm/CodeGen/LinkAllCodegenComponents.h"
255256 UseInitArray("use-init-array",
256257 cl::desc("Use .init_array instead of .ctors."),
257258 cl::init(false));
259
260 static cl::opt StopAfter("stop-after",
261 cl::desc("Stop compilation after a specific pass"),
262 cl::value_desc("pass-name"),
263 cl::init(""));
264 static cl::opt StartAfter("start-after",
265 cl::desc("Resume compilation after a specific pass"),
266 cl::value_desc("pass-name"),
267 cl::init(""));
258268
259269 // GetFileNameRoot - Helper function to get the basename of a filename.
260270 static inline std::string
352362 InitializeAllAsmPrinters();
353363 InitializeAllAsmParsers();
354364
355 // Initialize codegen so that the -print-after and -print-before options
356 // work.
357 initializeCodeGen(*PassRegistry::getPassRegistry());
365 // Initialize codegen and IR passes used by llc so that the -print-after,
366 // -print-before, and -stop-after options work.
367 PassRegistry *Registry = PassRegistry::getPassRegistry();
368 initializeCore(*Registry);
369 initializeCodeGen(*Registry);
370 initializeLoopStrengthReducePass(*Registry);
371 initializeLowerIntrinsicsPass(*Registry);
372 initializeUnreachableBlockElimPass(*Registry);
358373
359374 // Register the target printer for --version.
360375 cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
497512 {
498513 formatted_raw_ostream FOS(Out->os());
499514
515 AnalysisID StartAfterID = 0;
516 AnalysisID StopAfterID = 0;
517 const PassRegistry *PR = PassRegistry::getPassRegistry();
518 if (!StartAfter.empty()) {
519 const PassInfo *PI = PR->getPassInfo(StartAfter);
520 if (!PI) {
521 errs() << argv[0] << ": start-after pass is not registered.\n";
522 return 1;
523 }
524 StartAfterID = PI->getTypeInfo();
525 }
526 if (!StopAfter.empty()) {
527 const PassInfo *PI = PR->getPassInfo(StopAfter);
528 if (!PI) {
529 errs() << argv[0] << ": stop-after pass is not registered.\n";
530 return 1;
531 }
532 StopAfterID = PI->getTypeInfo();
533 }
534
500535 // Ask the target to add backend passes as necessary.
501 if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify)) {
536 if (Target.addPassesToEmitFile(PM, FOS, FileType, NoVerify,
537 StartAfterID, StopAfterID)) {
502538 errs() << argv[0] << ": target does not support generation of this"
503539 << " file type!\n";
504540 return 1;