Add support for report execution times

-Added command line option -report-times to enable or disable the output. The
same option can be used to specify the output directory.
-Write timing data to a unique file in disk using json format.

llvm-svn: 183142
This commit is contained in:
Ariel J. Bernal 2013-06-03 18:44:31 +00:00
parent 143672c7e5
commit ea7cef0869
1 changed files with 78 additions and 1 deletions

View File

@ -24,7 +24,10 @@
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/Timer.h"
namespace cl = llvm::cl;
using namespace clang::tooling;
@ -50,6 +53,12 @@ static cl::opt<bool>
SummaryMode("summary", cl::desc("Print transform summary"),
cl::init(false));
const char NoTiming[] = "no_timing";
static cl::opt<std::string> TimingDirectoryName(
"report-times", cl::desc("Capture performance data and output to specified "
"directory. Default ./migrate_perf"),
cl::init(NoTiming), cl::ValueOptional, cl::value_desc("directory name"));
// TODO: Remove cl::Hidden when functionality for acknowledging include/exclude
// options are implemented in the tool.
static cl::opt<std::string>
@ -78,6 +87,60 @@ class EndSyntaxArgumentsAdjuster : public ArgumentsAdjuster {
}
};
struct ExecutionTime {
std::string TimerId;
float Time;
ExecutionTime(const std::string &TimerId, float Time)
: TimerId(TimerId), Time(Time) {}
};
// Save execution times to a json formatted file.
void reportExecutionTimes(
const llvm::StringRef DirectoryName,
const std::map<std::string, std::vector<ExecutionTime> > &TimingResults) {
// Create directory path if it doesn't exist
llvm::sys::Path P(DirectoryName);
P.createDirectoryOnDisk(true);
// Get PID and current time.
llvm::sys::self_process *SP = llvm::sys::process::get_self();
unsigned Pid = SP->get_id();
llvm::TimeRecord T = llvm::TimeRecord::getCurrentTime();
std::string FileName;
llvm::raw_string_ostream SS(FileName);
SS << P.str() << "/" << static_cast<int>(T.getWallTime()) << Pid << ".json";
std::string ErrorInfo;
llvm::raw_fd_ostream FileStream(SS.str().c_str(), ErrorInfo);
FileStream << "{\n";
FileStream << " \"Sources\" : [\n";
for (std::map<std::string, std::vector<ExecutionTime> >::const_iterator
I = TimingResults.begin(),
E = TimingResults.end();
I != E; ++I) {
FileStream << " {\n";
FileStream << " \"Source \" : \"" << I->first << "\",\n";
FileStream << " \"Data\" : [\n";
for (std::vector<ExecutionTime>::const_iterator IE = I->second.begin(),
EE = I->second.end();
IE != EE; ++IE) {
FileStream << " {\n";
FileStream << " \"TimerId\" : \"" << (*IE).TimerId << "\",\n";
FileStream << " \"Time\" : " << llvm::format("%6.2f", (*IE).Time)
<< "\n";
FileStream << " },\n";
}
FileStream << " ]\n";
FileStream << " },\n";
}
FileStream << " ]\n";
FileStream << "}";
}
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
Transforms TransformManager;
@ -99,7 +162,12 @@ int main(int argc, const char **argv) {
// This causes options to be parsed.
CommonOptionsParser OptionsParser(argc, argv);
TransformManager.createSelectedTransforms(/*EnableTiming=*/false);
// Since ExecutionTimeDirectoryName could be an empty string we compare
// against the default value when the command line option is not specified.
bool EnableTiming = (TimingDirectoryName != NoTiming);
std::map<std::string, std::vector<ExecutionTime> > TimingResults;
TransformManager.createSelectedTransforms(EnableTiming);
if (TransformManager.begin() == TransformManager.end()) {
llvm::errs() << "No selected transforms\n";
@ -167,5 +235,14 @@ int main(int argc, const char **argv) {
FileStream << I->second;
}
// Report execution times.
if (EnableTiming && TimingResults.size() > 0) {
std::string DirectoryName = TimingDirectoryName;
// Use default directory name.
if (DirectoryName == "")
DirectoryName = "./migrate_perf";
reportExecutionTimes(DirectoryName, TimingResults);
}
return 0;
}