diff options
Diffstat (limited to 'llvm/tools/llvm-mc')
-rw-r--r-- | llvm/tools/llvm-mc/Disassembler.cpp | 46 | ||||
-rw-r--r-- | llvm/tools/llvm-mc/Disassembler.h | 3 | ||||
-rw-r--r-- | llvm/tools/llvm-mc/llvm-mc.cpp | 37 |
3 files changed, 70 insertions, 16 deletions
diff --git a/llvm/tools/llvm-mc/Disassembler.cpp b/llvm/tools/llvm-mc/Disassembler.cpp index 8672793..2ee4221 100644 --- a/llvm/tools/llvm-mc/Disassembler.cpp +++ b/llvm/tools/llvm-mc/Disassembler.cpp @@ -24,6 +24,7 @@ #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Support/TimeProfiler.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Triple.h" @@ -32,24 +33,29 @@ using namespace llvm; typedef std::pair<std::vector<unsigned char>, std::vector<const char *>> ByteArrayTy; -static bool PrintInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes, +static MCDisassembler::DecodeStatus getInstruction(const MCDisassembler &DisAsm, + const MCSubtargetInfo &STI, + MCInst &Inst, uint64_t &Size, + ArrayRef<uint8_t> Bytes, + uint64_t Address) { + if (STI.getTargetTriple().getArch() == Triple::hexagon) + return DisAsm.getInstructionBundle(Inst, Size, Bytes, Address, nulls()); + return DisAsm.getInstruction(Inst, Size, Bytes, Address, nulls()); +} + +static bool printInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes, SourceMgr &SM, MCStreamer &Streamer, bool InAtomicBlock, - const MCSubtargetInfo &STI) { + const MCSubtargetInfo &STI, unsigned NumBenchmarkRuns) { ArrayRef<uint8_t> Data(Bytes.first); // Disassemble it to strings. uint64_t Size; - uint64_t Index; - for (Index = 0; Index < Bytes.first.size(); Index += Size) { - MCInst Inst; + for (uint64_t Index = 0; Index < Bytes.first.size(); Index += Size) { - MCDisassembler::DecodeStatus S; - if (STI.getTargetTriple().getArch() == Triple::hexagon) - S = DisAsm.getInstructionBundle(Inst, Size, Data.slice(Index), Index, - nulls()); - else - S = DisAsm.getInstruction(Inst, Size, Data.slice(Index), Index, nulls()); + MCInst Inst; + MCDisassembler::DecodeStatus S = + getInstruction(DisAsm, STI, Inst, Size, Data.slice(Index), Index); switch (S) { case MCDisassembler::Fail: SM.PrintMessage(SMLoc::getFromPointer(Bytes.second[Index]), @@ -74,6 +80,18 @@ static bool PrintInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes, Streamer.emitInstruction(Inst, STI); break; } + + if (S == MCDisassembler::Success && NumBenchmarkRuns != 0) { + // Benchmark mode, collect timing for decoding the instruction several + // times. + MCInst BMInst; + TimeTraceScope timeScope("getInstruction"); + for (unsigned I = 0; I < NumBenchmarkRuns; ++I) { + BMInst.clear(); + BMInst.setOpcode(0); + S = getInstruction(DisAsm, STI, BMInst, Size, Data.slice(Index), Index); + } + } } return false; @@ -151,7 +169,7 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple, MCSubtargetInfo &STI, MCStreamer &Streamer, MemoryBuffer &Buffer, SourceMgr &SM, MCContext &Ctx, const MCTargetOptions &MCOptions, - bool HexBytes) { + bool HexBytes, unsigned NumBenchmarkRuns) { std::unique_ptr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple)); if (!MRI) { errs() << "error: no register info for target " << Triple << "\n"; @@ -207,8 +225,8 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple, ErrorOccurred |= byteArrayFromString(ByteArray, Str, SM, HexBytes); if (!ByteArray.first.empty()) - ErrorOccurred |= - PrintInsts(*DisAsm, ByteArray, SM, Streamer, InAtomicBlock, STI); + ErrorOccurred |= printInsts(*DisAsm, ByteArray, SM, Streamer, + InAtomicBlock, STI, NumBenchmarkRuns); } if (InAtomicBlock) { diff --git a/llvm/tools/llvm-mc/Disassembler.h b/llvm/tools/llvm-mc/Disassembler.h index 5efffca..5ee47d5 100644 --- a/llvm/tools/llvm-mc/Disassembler.h +++ b/llvm/tools/llvm-mc/Disassembler.h @@ -32,7 +32,8 @@ public: static int disassemble(const Target &T, const std::string &Triple, MCSubtargetInfo &STI, MCStreamer &Streamer, MemoryBuffer &Buffer, SourceMgr &SM, MCContext &Ctx, - const MCTargetOptions &MCOptions, bool HexBytes); + const MCTargetOptions &MCOptions, bool HexBytes, + unsigned NumBenchmarkRuns); }; } // namespace llvm diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp index da89af7..f69f7c7 100644 --- a/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/llvm/tools/llvm-mc/llvm-mc.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "Disassembler.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/DWARFCFIChecker/DWARFCFIFunctionFrameAnalyzer.h" #include "llvm/DWARFCFIChecker/DWARFCFIFunctionFrameStreamer.h" #include "llvm/MC/MCAsmBackend.h" @@ -37,6 +38,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Support/TimeProfiler.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/WithColor.h" #include "llvm/TargetParser/Host.h" @@ -240,6 +242,23 @@ static cl::opt<ActionType> Action( "Colored disassembly of strings of hex bytes")), cl::cat(MCCategory)); +static cl::opt<unsigned> + NumBenchmarkRuns("runs", cl::desc("Number of runs for benchmarking"), + cl::cat(MCCategory)); + +static cl::opt<bool> TimeTrace("time-trace", cl::desc("Record time trace")); + +static cl::opt<unsigned> TimeTraceGranularity( + "time-trace-granularity", + cl::desc( + "Minimum time granularity (in microseconds) traced by time profiler"), + cl::init(500), cl::Hidden); + +static cl::opt<std::string> + TimeTraceFile("time-trace-file", + cl::desc("Specify time trace file destination"), + cl::value_desc("filename")); + static const Target *GetTarget(const char *ProgName) { // Figure out the target triple. if (TripleName.empty()) @@ -371,6 +390,20 @@ int main(int argc, char **argv) { cl::HideUnrelatedOptions({&MCCategory, &getColorCategory()}); cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); + + if (TimeTrace) + timeTraceProfilerInitialize(TimeTraceGranularity, argv[0]); + + auto TimeTraceScopeExit = make_scope_exit([]() { + if (!TimeTrace) + return; + if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) { + logAllUnhandledErrors(std::move(E), errs()); + return; + } + timeTraceProfilerCleanup(); + }); + MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags(); MCOptions.CompressDebugSections = CompressDebugSections.getValue(); MCOptions.ShowMCInst = ShowInst; @@ -620,7 +653,8 @@ int main(int argc, char **argv) { } if (disassemble) Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, *Buffer, - SrcMgr, Ctx, MCOptions, HexBytes); + SrcMgr, Ctx, MCOptions, HexBytes, + NumBenchmarkRuns); // Keep output if no errors. if (Res == 0) { @@ -628,5 +662,6 @@ int main(int argc, char **argv) { if (DwoOut) DwoOut->keep(); } + return Res; } |