diff options
-rw-r--r-- | tools/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tools/LLVMBuild.txt | 2 | ||||
-rw-r--r-- | tools/Makefile | 4 | ||||
-rw-r--r-- | tools/pnacl-benchmark/CMakeLists.txt | 6 | ||||
-rw-r--r-- | tools/pnacl-benchmark/LLVMBuild.txt | 22 | ||||
-rw-r--r-- | tools/pnacl-benchmark/Makefile | 16 | ||||
-rw-r--r-- | tools/pnacl-benchmark/pnacl-benchmark.cpp | 177 |
7 files changed, 225 insertions, 3 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 8bc805111e..82dd51e758 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -15,6 +15,7 @@ add_subdirectory(llvm-mc) add_subdirectory(llc) add_subdirectory(pnacl-llc) +add_subdirectory(pnacl-benchmark) add_subdirectory(llvm-ranlib) add_subdirectory(llvm-ar) add_subdirectory(llvm-nm) diff --git a/tools/LLVMBuild.txt b/tools/LLVMBuild.txt index d7160f774d..07c567d43c 100644 --- a/tools/LLVMBuild.txt +++ b/tools/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = bugpoint llc pnacl-llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-mc llvm-nm llvm-objdump llvm-prof llvm-ranlib llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup pnacl-abicheck pnacl-bcanalyzer pnacl-freeze pnacl-thaw +subdirectories = bugpoint llc pnacl-llc pnacl-benchmark lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-mc llvm-nm llvm-objdump llvm-prof llvm-ranlib llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup pnacl-abicheck pnacl-bcanalyzer pnacl-freeze pnacl-thaw [component_0] type = Group diff --git a/tools/Makefile b/tools/Makefile index 4d42b778be..b5221475e4 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -33,10 +33,10 @@ PARALLEL_DIRS := opt llvm-as llvm-dis \ lli llvm-extract llvm-mc \ bugpoint llvm-bcanalyzer \ llvm-diff macho-dump llvm-objdump llvm-readobj \ - llvm-rtdyld llvm-dwarfdump llvm-cov \ + llvm-rtdyld llvm-dwarfdump llvm-cov \ llvm-size llvm-stress llvm-mcmarkup pso-stub \ llvm-symbolizer pnacl-abicheck pnacl-bcanalyzer pnacl-freeze \ - pnacl-thaw obj2yaml yaml2obj + pnacl-benchmark pnacl-thaw obj2yaml yaml2obj # If Intel JIT Events support is configured, build an extra tool to test it. ifeq ($(USE_INTEL_JITEVENTS), 1) diff --git a/tools/pnacl-benchmark/CMakeLists.txt b/tools/pnacl-benchmark/CMakeLists.txt new file mode 100644 index 0000000000..f152286070 --- /dev/null +++ b/tools/pnacl-benchmark/CMakeLists.txt @@ -0,0 +1,6 @@ +set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} bitreader naclbitreader + irreader asmparser naclanalysis nacltransforms) + +add_llvm_tool(pnacl-benchmark + pnacl-benchmark.cpp + ) diff --git a/tools/pnacl-benchmark/LLVMBuild.txt b/tools/pnacl-benchmark/LLVMBuild.txt new file mode 100644 index 0000000000..c00c7a15f8 --- /dev/null +++ b/tools/pnacl-benchmark/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./tools/pnacl-benchmark/LLVMBuild.txt --------------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Tool +name = pnacl-benchmark +parent = Tools +required_libraries = AsmParser BitReader NaClBitReader IRReader all-targets NaClAnalysis NaClTransforms diff --git a/tools/pnacl-benchmark/Makefile b/tools/pnacl-benchmark/Makefile new file mode 100644 index 0000000000..da3deb45e6 --- /dev/null +++ b/tools/pnacl-benchmark/Makefile @@ -0,0 +1,16 @@ +#===- tools/pnacl-benchmark/Makefile -----------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL := ../.. +TOOLNAME := pnacl-benchmark +LINK_COMPONENTS := all-targets bitreader naclbitreader irreader \ + asmparser naclanalysis nacltransforms + +include $(LEVEL)/Makefile.common + diff --git a/tools/pnacl-benchmark/pnacl-benchmark.cpp b/tools/pnacl-benchmark/pnacl-benchmark.cpp new file mode 100644 index 0000000000..10a448d810 --- /dev/null +++ b/tools/pnacl-benchmark/pnacl-benchmark.cpp @@ -0,0 +1,177 @@ +//===-- pnacl-benchmark.cpp -----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// pnacl-benchmark: various benchmarking tools for the PNaCl LLVM toolchain. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" +#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" +#include "llvm/Bitcode/NaCl/NaClBitstreamReader.h" +#include "llvm/Bitcode/NaCl/NaClLLVMBitCodes.h" +#include "llvm/Bitcode/NaCl/NaClReaderWriter.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/system_error.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/Timer.h" +#include <memory> +#include <vector> + +using namespace llvm; + + +static cl::opt<std::string> +InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); + +static cl::opt<unsigned> +NumRuns("num-runs", cl::desc("Number of runs"), cl::init(1)); + +/// Used in a lexical block to measure and report the block's execution time. +/// +/// \param N block name +/// \param InputSize optional size of input operated upon. If given, the +/// throughput will be reported as well in MB/sec. +class TimingOperationBlock { +public: + TimingOperationBlock(StringRef N, size_t InputSize=0) + : InputSize(InputSize) { + outs() << "Timing: " << N << "... "; + TStart = TimeRecord::getCurrentTime(true); + } + + ~TimingOperationBlock() { + TimeRecord TEnd = TimeRecord::getCurrentTime(false); + double elapsed = TEnd.getWallTime() - TStart.getWallTime(); + outs() << format("%.3lf", elapsed) << " sec"; + + if (InputSize != 0) { + double MBPerSec = (InputSize / elapsed) / 1000000.0; + outs() << format(" [%.3lf MB/sec]", MBPerSec); + } + outs() << "\n"; + } +private: + TimeRecord TStart; + size_t InputSize; +}; + +/// A do-nothing bitcode parser. +class DummyBitcodeParser : public NaClBitcodeParser { +public: + explicit DummyBitcodeParser(NaClBitstreamCursor &Cursor) + : NaClBitcodeParser(Cursor) { + } +}; + +void BenchmarkIRParsing() { + outs() << "Benchmarking IR parsing...\n"; + OwningPtr<MemoryBuffer> FileBuf; + error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), FileBuf); + if (ec) { + report_fatal_error("Could not open input file: " + ec.message()); + } + + size_t BufSize = FileBuf->getBufferSize(); + const uint8_t *BufPtr = + reinterpret_cast<const uint8_t*>(FileBuf->getBufferStart()); + const uint8_t *EndBufPtr = + reinterpret_cast<const uint8_t*>(FileBuf->getBufferEnd()); + + // Since MemoryBuffer may use mmap, make sure to first touch all bytes in the + // input buffer to make sure it's actually in memory. + volatile uint8_t *Slot = new uint8_t; + for (const uint8_t *S = BufPtr; S != EndBufPtr; ++S) { + *Slot = *S; + } + + delete Slot; + outs() << "Read bitcode into buffer. Size=" << BufSize << "\n"; + + // Trivial copy into a new buffer with a cascading XOR that simulates + // "touching" every byte in the buffer in a simple way. + { + TimingOperationBlock T("Simple XOR copy", BufSize); + volatile uint8_t *OutBuf = new uint8_t[BufSize]; + OutBuf[0] = 1; + size_t N = 1; + // Run over the input buffer from start to end-1; run over the output buffer + // from 1 to end. + for (const uint8_t *S = BufPtr; S != EndBufPtr - 1; ++S, ++N) { + OutBuf[N] = OutBuf[N - 1] ^ *S; + } + delete[] OutBuf; + } + + // Bitcode parsing without any additional operations. This is the minimum + // required to actually extract information from PNaCl bitcode. + { + TimingOperationBlock T("Bitcode block parsing", BufSize); + NaClBitcodeHeader Header; + + if (Header.Read(BufPtr, EndBufPtr)) { + report_fatal_error("Invalid PNaCl bitcode header"); + } + + if (!Header.IsSupported()) { + errs() << "Warning: " << Header.Unsupported() << "\n"; + } + + if (!Header.IsReadable()) { + report_fatal_error("Bitcode file is not readable"); + } + + NaClBitstreamReader StreamFile(BufPtr, EndBufPtr); + NaClBitstreamCursor Stream(StreamFile); + StreamFile.CollectBlockInfoNames(); + DummyBitcodeParser Parser(Stream); + while (!Stream.AtEndOfStream()) { + if (Parser.Parse()) { + report_fatal_error("Parsing failed"); + } + } + } + + // Actual LLVM IR parsing and formation from the bitcode + { + TimingOperationBlock T("LLVM IR parsing", BufSize); + SMDiagnostic Err; + Module *M = NaClParseIRFile(InputFilename, PNaClFormat, + Err, getGlobalContext()); + + if (!M) { + report_fatal_error("Unable to NaClParseIRFile"); + } + } +} + +int main(int argc, char **argv) { + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + cl::ParseCommandLineOptions(argc, argv, "pnacl-benchmark\n"); + + for (unsigned i = 0; i < NumRuns; i++) { + BenchmarkIRParsing(); + } + + return 0; +} |