diff options
Diffstat (limited to 'llvm/tools/llvm-mc/Disassembler.cpp')
-rw-r--r-- | llvm/tools/llvm-mc/Disassembler.cpp | 46 |
1 files changed, 32 insertions, 14 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) { |