Index: docs/CommandGuide/llvm-exegesis.rst =================================================================== --- docs/CommandGuide/llvm-exegesis.rst +++ docs/CommandGuide/llvm-exegesis.rst @@ -247,10 +247,16 @@ If set, ignore instructions that do not have a sched class (class idx = 0). - .. option:: -mcpu= +.. option:: -mcpu= - If set, measure the cpu characteristics using the counters for this CPU. This - is useful when creating new sched models (the host CPU is unknown to LLVM). + If set, measure the cpu characteristics using the counters for this CPU. This + is useful when creating new sched models (the host CPU is unknown to LLVM). + +.. option:: --dump-object-to-disk=true + + By default, llvm-exegesis will dump the generated code to a temporary file to + enable code inspection. You may disable it to speed up the execution and save + disk space. EXIT STATUS ----------- Index: tools/llvm-exegesis/lib/BenchmarkRunner.h =================================================================== --- tools/llvm-exegesis/lib/BenchmarkRunner.h +++ tools/llvm-exegesis/lib/BenchmarkRunner.h @@ -45,7 +45,8 @@ virtual ~BenchmarkRunner(); InstructionBenchmark runConfiguration(const BenchmarkCode &Configuration, - unsigned NumRepetitions) const; + unsigned NumRepetitions, + bool DumpObjectToDisk) const; // Scratch space to run instructions that touch memory. struct ScratchSpace { @@ -85,7 +86,6 @@ writeObjectFile(const BenchmarkCode &Configuration, llvm::ArrayRef Code) const; - const std::unique_ptr Scratch; }; Index: tools/llvm-exegesis/lib/BenchmarkRunner.cpp =================================================================== --- tools/llvm-exegesis/lib/BenchmarkRunner.cpp +++ tools/llvm-exegesis/lib/BenchmarkRunner.cpp @@ -66,8 +66,9 @@ CounterName = CounterName.trim(); pfm::PerfEvent PerfEvent(CounterName); if (!PerfEvent.valid()) - llvm::report_fatal_error( - llvm::Twine("invalid perf event '").concat(CounterName).concat("'")); + llvm::report_fatal_error(llvm::Twine("invalid perf event '") + .concat(CounterName) + .concat("'")); pfm::Counter Counter(PerfEvent); Scratch->clear(); { @@ -96,7 +97,8 @@ InstructionBenchmark BenchmarkRunner::runConfiguration(const BenchmarkCode &BC, - unsigned NumRepetitions) const { + unsigned NumRepetitions, + bool DumpObjectToDisk) const { InstructionBenchmark InstrBenchmark; InstrBenchmark.Mode = Mode; InstrBenchmark.CpuName = State.getTargetMachine().getTargetCPU(); @@ -127,17 +129,28 @@ InstrBenchmark.AssembledSnippet.assign(FnBytes.begin(), FnBytes.end()); } - // Assemble NumRepetitions instructions repetitions of the snippet for - // measurements. - auto ObjectFilePath = writeObjectFile( - BC, GenerateInstructions(BC, InstrBenchmark.NumRepetitions)); - if (llvm::Error E = ObjectFilePath.takeError()) { - InstrBenchmark.Error = llvm::toString(std::move(E)); - return InstrBenchmark; + const auto Code = GenerateInstructions(BC, InstrBenchmark.NumRepetitions); + llvm::object::OwningBinary ObjectFile; + if (DumpObjectToDisk) { + // Assemble NumRepetitions instructions repetitions of the snippet for + // measurements. + auto ObjectFilePath = writeObjectFile(BC, Code); + if (llvm::Error E = ObjectFilePath.takeError()) { + InstrBenchmark.Error = llvm::toString(std::move(E)); + return InstrBenchmark; + } + llvm::outs() << "Check generated assembly with: /usr/bin/objdump -d " + << *ObjectFilePath << "\n"; + ObjectFile = getObjectFromFile(*ObjectFilePath); + } else { + llvm::SmallString<0> Buffer; + llvm::raw_svector_ostream OS(Buffer); + assembleToStream(State.getExegesisTarget(), State.createTargetMachine(), + BC.LiveIns, BC.RegisterInitialValues, Code, OS); + ObjectFile = getObjectFromBuffer(OS.str()); } - llvm::outs() << "Check generated assembly with: /usr/bin/objdump -d " - << *ObjectFilePath << "\n"; - const FunctionExecutorImpl Executor(State, getObjectFromFile(*ObjectFilePath), + + const FunctionExecutorImpl Executor(State, std::move(ObjectFile), Scratch.get()); auto Measurements = runMeasurements(Executor); if (llvm::Error E = Measurements.takeError()) { Index: tools/llvm-exegesis/llvm-exegesis.cpp =================================================================== --- tools/llvm-exegesis/llvm-exegesis.cpp +++ tools/llvm-exegesis/llvm-exegesis.cpp @@ -137,6 +137,12 @@ cl::desc("cpu name to use for pfm counters, leave empty to autodetect"), cl::cat(Options), cl::init("")); +static cl::opt + DumpObjectToDisk("dump-object-to-disk", + cl::desc("dumps the generated benchmark object to disk " + "and prints a message to access it"), + cl::cat(BenchmarkOptions), cl::init(true)); + static ExitOnError ExitOnErr; #ifdef LLVM_EXEGESIS_INITIALIZE_NATIVE_TARGET @@ -406,7 +412,7 @@ for (const BenchmarkCode &Conf : Configurations) { InstructionBenchmark Result = - Runner->runConfiguration(Conf, NumRepetitions); + Runner->runConfiguration(Conf, NumRepetitions, DumpObjectToDisk); ExitOnErr(Result.writeYaml(State, BenchmarkFile)); } exegesis::pfm::pfmTerminate();