//===-- Core/PerfSupport.cpp - Perf measurement helpers -------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// /// /// \file /// \brief This file provides implementations for performance measuring helpers. /// //===----------------------------------------------------------------------===// #include "PerfSupport.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" void collectSourcePerfData(const Transform &T, SourcePerfData &Data) { for (Transform::TimingVec::const_iterator I = T.timing_begin(), E = T.timing_end(); I != E; ++I) { SourcePerfData::iterator DataI = Data.insert( SourcePerfData::value_type(I->first, std::vector())).first; DataI->second .push_back(PerfItem(T.getName(), I->second.getProcessTime() * 1000.0)); } } void writePerfDataJSON( const llvm::StringRef DirectoryName, const SourcePerfData &TimingResults) { // Create directory path if it doesn't exist llvm::sys::fs::create_directories(DirectoryName); // Get PID and current time. // FIXME: id_type on Windows is NOT a process id despite the function name. // Need to call GetProcessId() providing it what get_id() returns. For now // disabling PID-based file names until this is fixed properly. //llvm::sys::self_process *SP = llvm::sys::process::get_self(); //id_type Pid = SP->get_id(); unsigned Pid = 0; llvm::TimeRecord T = llvm::TimeRecord::getCurrentTime(); std::string FileName; llvm::raw_string_ostream SS(FileName); SS << DirectoryName << "/" << static_cast(T.getWallTime()) << "_" << Pid << ".json"; std::error_code EC; llvm::raw_fd_ostream FileStream(SS.str(), EC, llvm::sys::fs::F_Text); FileStream << "{\n"; FileStream << " \"Sources\" : [\n"; for (SourcePerfData::const_iterator I = TimingResults.begin(), E = TimingResults.end(); I != E; ++I) { // Terminate the last source with a comma before continuing to the next one. if (I != TimingResults.begin()) FileStream << ",\n"; FileStream << " {\n"; FileStream << " \"Source \" : \"" << I->first << "\",\n"; FileStream << " \"Data\" : [\n"; for (std::vector::const_iterator IE = I->second.begin(), EE = I->second.end(); IE != EE; ++IE) { // Terminate the last perf item with a comma before continuing to the next // one. if (IE != I->second.begin()) FileStream << ",\n"; FileStream << " {\n"; FileStream << " \"TimerId\" : \"" << IE->Label << "\",\n"; FileStream << " \"Time\" : " << llvm::format("%.2f", IE->Duration) << "\n"; FileStream << " }"; } FileStream << "\n ]\n"; FileStream << " }"; } FileStream << "\n ]\n"; FileStream << "}"; } void dumpPerfData(const SourcePerfData &Data) { for (SourcePerfData::const_iterator I = Data.begin(), E = Data.end(); I != E; ++I) { llvm::errs() << I->first << ":\n"; for (std::vector::const_iterator VecI = I->second.begin(), VecE = I->second.end(); VecI != VecE; ++VecI) { llvm::errs() << " " << VecI->Label << ": " << llvm::format("%.1f", VecI->Duration) << "ms\n"; } } }