]> granicus.if.org Git - llvm/commitdiff
[llc] Add support for several run-pass options.
authorQuentin Colombet <qcolombet@apple.com>
Fri, 10 Jun 2016 00:52:10 +0000 (00:52 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Fri, 10 Jun 2016 00:52:10 +0000 (00:52 +0000)
Previously we could run only one machine pass with the run-pass option.
With that patch, we can now specify several passes with several run-pass
options (or just one option with a list of comma separated passes) and
llc will build the related pipeline.
This is great to test the interaction of two passes that are not
necessarily next to each other in the pipeline, or play with pass
ordering.
Now, we should be at parity with opt for the flexibility of running
passes.

Note: I also moved the run pass option from CommandFlags.h to llc.cpp
because, really, this is needed only there!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@272356 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/CommandFlags.h
test/CodeGen/MIR/Generic/multiRunPass.mir [new file with mode: 0644]
tools/llc/llc.cpp

index defc219ce94169bf8c176cd030072ff04039b339..6376c06768b3a753f0edda3a733beeb66f71d848 100644 (file)
@@ -230,10 +230,6 @@ cl::opt<std::string> StartAfter("start-after",
                           cl::value_desc("pass-name"),
                           cl::init(""));
 
-cl::opt<std::string>
-    RunPass("run-pass", cl::desc("Run compiler only for one specific pass"),
-            cl::value_desc("pass-name"), cl::init(""));
-
 cl::opt<bool> DataSections("data-sections",
                            cl::desc("Emit data into separate sections"),
                            cl::init(false));
diff --git a/test/CodeGen/MIR/Generic/multiRunPass.mir b/test/CodeGen/MIR/Generic/multiRunPass.mir
new file mode 100644 (file)
index 0000000..885b275
--- /dev/null
@@ -0,0 +1,20 @@
+# RUN: llc -run-pass expand-isel-pseudos  -run-pass peephole-opts -debug-pass=Arguments -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=PSEUDO_PEEPHOLE
+# RUN: llc -run-pass expand-isel-pseudos,peephole-opts -debug-pass=Arguments -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=PSEUDO_PEEPHOLE
+# RUN: llc -run-pass peephole-opts -run-pass expand-isel-pseudos -debug-pass=Arguments -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=PEEPHOLE_PSEUDO
+# RUN: llc -run-pass peephole-opts,expand-isel-pseudos -debug-pass=Arguments -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=PEEPHOLE_PSEUDO
+# REQUIRES: asserts
+
+# This test ensures that the command line accepts
+# several run passes on the same command line and
+# actually create the proper pipeline for it.
+# PSEUDO_PEEPHOLE: -expand-isel-pseudos -peephole-opts
+# PEEPHOLE_PSEUDO: -peephole-opts -expand-isel-pseudos
+
+# Make sure there are no other passes happening after what we asked.
+# CHECK-NEXT: --- |
+---
+# CHECK: name: foo
+name: foo
+body: |
+  bb.0:
+...
index 981a6c34de1eb566c85088c7d89525c779a6a482..51ce3c0f2bf10173c8b1b9b8d94bf457806b2b95 100644 (file)
@@ -118,6 +118,28 @@ static cl::opt<bool> ExitOnError(
     cl::desc("Exit as soon as an error is encountered."),
     cl::init(false), cl::Hidden);
 
+namespace {
+static ManagedStatic<std::vector<std::string>> RunPassNames;
+
+struct RunPassOption {
+  void operator=(const std::string &Val) const {
+    if (Val.empty())
+      return;
+    SmallVector<StringRef, 8> PassNames;
+    StringRef(Val).split(PassNames, ',', -1, false);
+    for (auto PassName : PassNames)
+      RunPassNames->push_back(PassName);
+  }
+};
+}
+
+static RunPassOption RunPassOpt;
+
+static cl::opt<RunPassOption, true, cl::parser<std::string>> RunPass(
+    "run-pass",
+    cl::desc("Run compiler only for specified passes (comma separated list)"),
+    cl::value_desc("pass-name"), cl::ZeroOrMore, cl::location(RunPassOpt));
+
 static int compileModule(char **, LLVMContext &);
 
 static std::unique_ptr<tool_output_file>
@@ -379,7 +401,7 @@ static int compileModule(char **argv, LLVMContext &Context) {
     AnalysisID StartAfterID = nullptr;
     AnalysisID StopAfterID = nullptr;
     const PassRegistry *PR = PassRegistry::getPassRegistry();
-    if (!RunPass.empty()) {
+    if (!RunPassNames->empty()) {
       if (!StartAfter.empty() || !StopAfter.empty()) {
         errs() << argv[0] << ": start-after and/or stop-after passes are "
                              "redundant when run-pass is specified.\n";
@@ -389,33 +411,34 @@ static int compileModule(char **argv, LLVMContext &Context) {
         errs() << argv[0] << ": run-pass needs a .mir input.\n";
         return 1;
       }
-      const PassInfo *PI = PR->getPassInfo(RunPass);
-      if (!PI) {
-        errs() << argv[0] << ": run-pass pass is not registered.\n";
-        return 1;
-      }
-      LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine&>(*Target);
-      TargetPassConfig *TPC = LLVMTM.createPassConfig(PM);
-      PM.add(TPC);
-      LLVMTM.addMachineModuleInfo(PM);
-      LLVMTM.addMachineFunctionAnalysis(PM, MIR.get());
-      TPC->printAndVerify("");
-
-      Pass *P;
-      if (PI->getTargetMachineCtor())
-        P = PI->getTargetMachineCtor()(Target.get());
-      else if (PI->getNormalCtor())
-        P = PI->getNormalCtor()();
-      else {
-        errs() << argv[0] << ": cannot create pass: "
-               << PI->getPassName() << "\n";
-        return 1;
+      for (std::string &RunPassName : *RunPassNames) {
+        const PassInfo *PI = PR->getPassInfo(RunPassName);
+        if (!PI) {
+          errs() << argv[0] << ": run-pass " << RunPassName << " is not registered.\n";
+          return 1;
+        }
+        LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine&>(*Target);
+        TargetPassConfig *TPC = LLVMTM.createPassConfig(PM);
+        PM.add(TPC);
+        LLVMTM.addMachineModuleInfo(PM);
+        LLVMTM.addMachineFunctionAnalysis(PM, MIR.get());
+        TPC->printAndVerify("");
+
+        Pass *P;
+        if (PI->getTargetMachineCtor())
+          P = PI->getTargetMachineCtor()(Target.get());
+        else if (PI->getNormalCtor())
+          P = PI->getNormalCtor()();
+        else {
+          errs() << argv[0] << ": cannot create pass: "
+                 << PI->getPassName() << "\n";
+          return 1;
+        }
+        std::string Banner
+          = std::string("After ") + std::string(P->getPassName());
+        PM.add(P);
+        TPC->printAndVerify(Banner);
       }
-      std::string Banner
-        = std::string("After ") + std::string(P->getPassName());
-      PM.add(P);
-      TPC->printAndVerify(Banner);
-
       PM.add(createPrintMIRPass(errs()));
     } else {
       if (!StartAfter.empty()) {