Index: llvm/trunk/tools/llvm-exegesis/lib/Analysis.h =================================================================== --- llvm/trunk/tools/llvm-exegesis/lib/Analysis.h +++ llvm/trunk/tools/llvm-exegesis/lib/Analysis.h @@ -33,10 +33,11 @@ const InstructionBenchmarkClustering &Clustering); // Prints a csv of instructions for each cluster. - llvm::Error printClusters(llvm::raw_ostream &OS) const; - + struct PrintClusters {}; // Find potential errors in the scheduling information given measurements. - llvm::Error printSchedClassInconsistencies(llvm::raw_ostream &OS) const; + struct PrintSchedClassInconsistencies {}; + + template llvm::Error run(llvm::raw_ostream &OS) const; private: void printInstructionRow(bool PrintSchedClass, size_t PointId, Index: llvm/trunk/tools/llvm-exegesis/lib/Analysis.cpp =================================================================== --- llvm/trunk/tools/llvm-exegesis/lib/Analysis.cpp +++ llvm/trunk/tools/llvm-exegesis/lib/Analysis.cpp @@ -91,7 +91,9 @@ MnemonicToOpcode_.emplace(InstrInfo_->getName(I), I); } -llvm::Error Analysis::printClusters(llvm::raw_ostream &OS) const { +template <> +llvm::Error +Analysis::run(llvm::raw_ostream &OS) const { if (Clustering_.getPoints().empty()) return llvm::Error::success(); @@ -133,8 +135,9 @@ return PointsPerSchedClass; } -llvm::Error -Analysis::printSchedClassInconsistencies(llvm::raw_ostream &OS) const { +template <> +llvm::Error Analysis::run( + llvm::raw_ostream &OS) const { // All the points in a scheduling class should be in the same cluster. // Print any scheduling class for which this is not the case. for (const auto &SchedClassAndPoints : makePointsPerSchedClass()) { @@ -167,4 +170,9 @@ return llvm::Error::success(); } +template llvm::Error +Analysis::run(llvm::raw_ostream &OS) const; +template llvm::Error Analysis::run( + llvm::raw_ostream &OS) const; + } // namespace exegesis Index: llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp =================================================================== --- llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp +++ llvm/trunk/tools/llvm-exegesis/llvm-exegesis.cpp @@ -70,9 +70,12 @@ llvm::cl::desc("dbscan epsilon for analysis clustering"), llvm::cl::init(0.1)); -static llvm::cl::opt AnalysisClustersFile("analysis-clusters-file", - llvm::cl::desc(""), - llvm::cl::init("-")); +static llvm::cl::opt + AnalysisClustersOutputFile("analysis-clusters-output-file", + llvm::cl::desc(""), llvm::cl::init("-")); +static llvm::cl::opt + AnalysisInconsistenciesOutputFile("analysis-inconsistencies-output-file", + llvm::cl::desc(""), llvm::cl::init("-")); namespace exegesis { @@ -125,7 +128,27 @@ exegesis::pfm::pfmTerminate(); } -void analysisMain() { +// Prints the results of running analysis pass `Pass` to file `OutputFilename` +// if OutputFilename is non-empty. +template +static void maybeRunAnalysis(const Analysis &Analyzer, const std::string &Name, + const std::string &OutputFilename) { + if (OutputFilename.empty()) + return; + if (OutputFilename != "-") { + llvm::errs() << "Printing " << Name << " results to file '" + << OutputFilename << "'\n"; + } + std::error_code ErrorCode; + llvm::raw_fd_ostream ClustersOS(OutputFilename, ErrorCode, + llvm::sys::fs::F_RW); + if (ErrorCode) + llvm::report_fatal_error("cannot open out file: " + OutputFilename); + if (auto Err = Analyzer.run(ClustersOS)) + llvm::report_fatal_error(std::move(Err)); +} + +static void analysisMain() { // Read benchmarks. const std::vector Points = InstructionBenchmark::readYamlsOrDie(BenchmarkFile); @@ -152,17 +175,11 @@ const Analysis Analyzer(*TheTarget, Clustering); - std::error_code ErrorCode; - llvm::raw_fd_ostream ClustersOS(AnalysisClustersFile, ErrorCode, - llvm::sys::fs::F_RW); - if (ErrorCode) - llvm::report_fatal_error("cannot open out file: " + AnalysisClustersFile); - - if (auto Err = Analyzer.printClusters(ClustersOS)) - llvm::report_fatal_error(std::move(Err)); - - if (auto Err = Analyzer.printSchedClassInconsistencies(llvm::outs())) - llvm::report_fatal_error(std::move(Err)); + maybeRunAnalysis(Analyzer, "analysis clusters", + AnalysisClustersOutputFile); + maybeRunAnalysis( + Analyzer, "sched class consistency analysis", + AnalysisInconsistenciesOutputFile); } } // namespace exegesis