--- /dev/null
+# 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:
+...
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>
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";
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()) {