Index: docs/MIRLangRef.rst =================================================================== --- docs/MIRLangRef.rst +++ docs/MIRLangRef.rst @@ -60,6 +60,11 @@ ``llc -stop-after=machine-cp bug-trigger.ll > test.mir`` +If the same pass is run multiple times, a run index can be included +after the name with a comma. + + ``llc -stop-after=dead-mi-elimination,1 bug-trigger.ll > test.mir`` + After generating the input MIR file, you'll have to add a run line that uses the ``-run-pass`` option to it. In order to test the post register allocation pseudo instruction expansion pass on X86-64, a run line like the one shown Index: include/llvm/CodeGen/TargetPassConfig.h =================================================================== --- include/llvm/CodeGen/TargetPassConfig.h +++ include/llvm/CodeGen/TargetPassConfig.h @@ -90,6 +90,19 @@ AnalysisID StartAfter = nullptr; AnalysisID StopBefore = nullptr; AnalysisID StopAfter = nullptr; + + unsigned StartBeforeInstanceNum = 0; + unsigned StartBeforeCount = 0; + + unsigned StartAfterInstanceNum = 0; + unsigned StartAfterCount = 0; + + unsigned StopBeforeInstanceNum = 0; + unsigned StopBeforeCount = 0; + + unsigned StopAfterInstanceNum = 0; + unsigned StopAfterCount = 0; + bool Started = true; bool Stopped = false; bool AddingMachinePasses = false; Index: lib/CodeGen/TargetPassConfig.cpp =================================================================== --- lib/CodeGen/TargetPassConfig.cpp +++ lib/CodeGen/TargetPassConfig.cpp @@ -345,11 +345,39 @@ return PI ? PI->getTypeInfo() : nullptr; } +static std::pair +getPassNameAndInstanceNum(StringRef PassName) { + StringRef Name, InstanceNumStr; + std::tie(Name, InstanceNumStr) = PassName.split(','); + + unsigned InstanceNum = 0; + if (!InstanceNumStr.empty() && InstanceNumStr.getAsInteger(10, InstanceNum)) + report_fatal_error("invalid pass instance specifier " + PassName); + + return std::make_pair(Name, InstanceNum); +} + void TargetPassConfig::setStartStopPasses() { - StartBefore = getPassIDFromName(StartBeforeOpt); - StartAfter = getPassIDFromName(StartAfterOpt); - StopBefore = getPassIDFromName(StopBeforeOpt); - StopAfter = getPassIDFromName(StopAfterOpt); + StringRef StartBeforeName; + std::tie(StartBeforeName, StartBeforeInstanceNum) = + getPassNameAndInstanceNum(StartBeforeOpt); + + StringRef StartAfterName; + std::tie(StartAfterName, StartAfterInstanceNum) = + getPassNameAndInstanceNum(StartAfterOpt); + + StringRef StopBeforeName; + std::tie(StopBeforeName, StopBeforeInstanceNum) + = getPassNameAndInstanceNum(StopBeforeOpt); + + StringRef StopAfterName; + std::tie(StopAfterName, StopAfterInstanceNum) + = getPassNameAndInstanceNum(StopAfterOpt); + + StartBefore = getPassIDFromName(StartBeforeName); + StartAfter = getPassIDFromName(StartAfterName); + StopBefore = getPassIDFromName(StopBeforeName); + StopAfter = getPassIDFromName(StopAfterName); if (StartBefore && StartAfter) report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") + Twine(StartAfterOptName) + Twine(" specified!")); @@ -493,9 +521,9 @@ // and shouldn't reference it. AnalysisID PassID = P->getPassID(); - if (StartBefore == PassID) + if (StartBefore == PassID && StartBeforeCount++ == StartBeforeInstanceNum) Started = true; - if (StopBefore == PassID) + if (StopBefore == PassID && StopBeforeCount++ == StopBeforeInstanceNum) Stopped = true; if (Started && !Stopped) { std::string Banner; @@ -518,9 +546,11 @@ } else { delete P; } - if (StopAfter == PassID) + + if (StopAfter == PassID && StopAfterCount++ == StopAfterInstanceNum) Stopped = true; - if (StartAfter == PassID) + + if (StartAfter == PassID && StartAfterCount++ == StartAfterInstanceNum) Started = true; if (Stopped && !Started) report_fatal_error("Cannot stop compilation after pass that is not run"); Index: test/CodeGen/Generic/llc-start-stop-instance-errors.ll =================================================================== --- /dev/null +++ test/CodeGen/Generic/llc-start-stop-instance-errors.ll @@ -0,0 +1,4 @@ +; RUN: not llc -debug-pass=Structure -stop-after=dead-mi-elimination,arst %s -o /dev/null 2>&1 \ +; RUN: | FileCheck -check-prefix=NOT-NUM %s + +; NOT-NUM: LLVM ERROR: invalid pass instance specifier dead-mi-elimination,arst Index: test/CodeGen/Generic/llc-start-stop-instance.ll =================================================================== --- /dev/null +++ test/CodeGen/Generic/llc-start-stop-instance.ll @@ -0,0 +1,50 @@ +; RUN: llc -debug-pass=Structure -stop-after=dead-mi-elimination,1 %s -o /dev/null 2>&1 \ +; RUN: | FileCheck -check-prefix=STOP-AFTER-DEAD1 %s + +; RUN: llc -debug-pass=Structure -stop-after=dead-mi-elimination,0 %s -o /dev/null 2>&1 \ +; RUN: | FileCheck -check-prefix=STOP-AFTER-DEAD0 %s + + +; RUN: llc -debug-pass=Structure -stop-before=dead-mi-elimination,1 %s -o /dev/null 2>&1 \ +; RUN: | FileCheck -check-prefix=STOP-BEFORE-DEAD1 %s + + +; RUN: llc -debug-pass=Structure -start-before=dead-mi-elimination,1 %s -o /dev/null 2>&1 \ +; RUN: | FileCheck -check-prefix=START-BEFORE-DEAD1 %s + +; RUN: llc -debug-pass=Structure -start-after=dead-mi-elimination,1 %s -o /dev/null 2>&1 \ +; RUN: | FileCheck -check-prefix=START-AFTER-DEAD1 %s + + + +; STOP-AFTER-DEAD1: -dead-mi-elimination +; STOP-AFTER-DEAD1-SAME: -dead-mi-elimination + +; STOP-AFTER-DEAD1: Remove dead machine instructions +; STOP-AFTER-DEAD1: Remove dead machine instructions + + + +; STOP-AFTER-DEAD0: -dead-mi-elimination + +; STOP-AFTER-DEAD0-NOT: Remove dead machine instructions +; STOP-AFTER-DEAD0: Remove dead machine instructions +; STOP-AFTER-DEAD0-NOT: Remove dead machine instructions + + + +; STOP-BEFORE-DEAD1: -dead-mi-elimination +; STOP-BEFORE-DEAD1: Remove dead machine instructions +; STOP-BEFORE-DEAD1-NOT: Remove dead machine instructions + + + +; START-BEFORE-DEAD1: -dead-mi-elimination +; START-BEFORE-DEAD1-NOT: Remove dead machine instructions +; START-BEFORE-DEAD1: Remove dead machine instructions +; START-BEFORE-DEAD1-NOT: Remove dead machine instructions + + + +; START-AFTER-DEAD1-NOT: -dead-mi-elimination +; START-AFTER-DEAD1-NOT: Remove dead machine instructions