forked from OSchip/llvm-project
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:
parent
143672c7e5
commit
ea7cef0869
|
@ -24,7 +24,10 @@
|
||||||
#include "clang/Frontend/FrontendActions.h"
|
#include "clang/Frontend/FrontendActions.h"
|
||||||
#include "clang/Tooling/CommonOptionsParser.h"
|
#include "clang/Tooling/CommonOptionsParser.h"
|
||||||
#include "clang/Tooling/Tooling.h"
|
#include "clang/Tooling/Tooling.h"
|
||||||
|
#include "llvm/Support/Format.h"
|
||||||
|
#include "llvm/Support/Process.h"
|
||||||
#include "llvm/Support/Signals.h"
|
#include "llvm/Support/Signals.h"
|
||||||
|
#include "llvm/Support/Timer.h"
|
||||||
|
|
||||||
namespace cl = llvm::cl;
|
namespace cl = llvm::cl;
|
||||||
using namespace clang::tooling;
|
using namespace clang::tooling;
|
||||||
|
@ -50,6 +53,12 @@ static cl::opt<bool>
|
||||||
SummaryMode("summary", cl::desc("Print transform summary"),
|
SummaryMode("summary", cl::desc("Print transform summary"),
|
||||||
cl::init(false));
|
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
|
// TODO: Remove cl::Hidden when functionality for acknowledging include/exclude
|
||||||
// options are implemented in the tool.
|
// options are implemented in the tool.
|
||||||
static cl::opt<std::string>
|
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) {
|
int main(int argc, const char **argv) {
|
||||||
llvm::sys::PrintStackTraceOnErrorSignal();
|
llvm::sys::PrintStackTraceOnErrorSignal();
|
||||||
Transforms TransformManager;
|
Transforms TransformManager;
|
||||||
|
@ -99,7 +162,12 @@ int main(int argc, const char **argv) {
|
||||||
// This causes options to be parsed.
|
// This causes options to be parsed.
|
||||||
CommonOptionsParser OptionsParser(argc, argv);
|
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()) {
|
if (TransformManager.begin() == TransformManager.end()) {
|
||||||
llvm::errs() << "No selected transforms\n";
|
llvm::errs() << "No selected transforms\n";
|
||||||
|
@ -167,5 +235,14 @@ int main(int argc, const char **argv) {
|
||||||
FileStream << I->second;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue