2424#include " llvm/MC/TargetRegistry.h"
2525#include " llvm/Support/MemoryBuffer.h"
2626#include " llvm/Support/SourceMgr.h"
27+ #include " llvm/Support/TimeProfiler.h"
2728#include " llvm/Support/raw_ostream.h"
2829#include " llvm/TargetParser/Triple.h"
2930
@@ -32,24 +33,29 @@ using namespace llvm;
3233typedef std::pair<std::vector<unsigned char >, std::vector<const char *>>
3334 ByteArrayTy;
3435
35- static bool PrintInsts (const MCDisassembler &DisAsm, const ByteArrayTy &Bytes,
36+ static MCDisassembler::DecodeStatus getInstruction (const MCDisassembler &DisAsm,
37+ const MCSubtargetInfo &STI,
38+ MCInst &Inst, uint64_t &Size,
39+ ArrayRef<uint8_t > Bytes,
40+ uint64_t Address) {
41+ if (STI.getTargetTriple ().getArch () == Triple::hexagon)
42+ return DisAsm.getInstructionBundle (Inst, Size, Bytes, Address, nulls ());
43+ return DisAsm.getInstruction (Inst, Size, Bytes, Address, nulls ());
44+ }
45+
46+ static bool printInsts (const MCDisassembler &DisAsm, const ByteArrayTy &Bytes,
3647 SourceMgr &SM, MCStreamer &Streamer, bool InAtomicBlock,
37- const MCSubtargetInfo &STI) {
48+ const MCSubtargetInfo &STI, unsigned NumBenchmarkRuns ) {
3849 ArrayRef<uint8_t > Data (Bytes.first );
3950
4051 // Disassemble it to strings.
4152 uint64_t Size;
42- uint64_t Index;
4353
44- for (Index = 0 ; Index < Bytes.first .size (); Index += Size) {
45- MCInst Inst;
54+ for (uint64_t Index = 0 ; Index < Bytes.first .size (); Index += Size) {
4655
47- MCDisassembler::DecodeStatus S;
48- if (STI.getTargetTriple ().getArch () == Triple::hexagon)
49- S = DisAsm.getInstructionBundle (Inst, Size, Data.slice (Index), Index,
50- nulls ());
51- else
52- S = DisAsm.getInstruction (Inst, Size, Data.slice (Index), Index, nulls ());
56+ MCInst Inst;
57+ MCDisassembler::DecodeStatus S =
58+ getInstruction (DisAsm, STI, Inst, Size, Data.slice (Index), Index);
5359 switch (S) {
5460 case MCDisassembler::Fail:
5561 SM.PrintMessage (SMLoc::getFromPointer (Bytes.second [Index]),
@@ -74,6 +80,18 @@ static bool PrintInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes,
7480 Streamer.emitInstruction (Inst, STI);
7581 break ;
7682 }
83+
84+ if (S == MCDisassembler::Success && NumBenchmarkRuns != 0 ) {
85+ // Benchmark mode, collect timing for decoding the instruction several
86+ // times.
87+ MCInst BMInst;
88+ TimeTraceScope timeScope (" getInstruction" );
89+ for (unsigned I = 0 ; I < NumBenchmarkRuns; ++I) {
90+ BMInst.clear ();
91+ BMInst.setOpcode (0 );
92+ S = getInstruction (DisAsm, STI, BMInst, Size, Data.slice (Index), Index);
93+ }
94+ }
7795 }
7896
7997 return false ;
@@ -151,7 +169,7 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
151169 MCSubtargetInfo &STI, MCStreamer &Streamer,
152170 MemoryBuffer &Buffer, SourceMgr &SM,
153171 MCContext &Ctx, const MCTargetOptions &MCOptions,
154- bool HexBytes) {
172+ bool HexBytes, unsigned NumBenchmarkRuns ) {
155173 std::unique_ptr<const MCRegisterInfo> MRI (T.createMCRegInfo (Triple));
156174 if (!MRI) {
157175 errs () << " error: no register info for target " << Triple << " \n " ;
@@ -207,8 +225,8 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
207225 ErrorOccurred |= byteArrayFromString (ByteArray, Str, SM, HexBytes);
208226
209227 if (!ByteArray.first .empty ())
210- ErrorOccurred |=
211- PrintInsts (*DisAsm, ByteArray, SM, Streamer, InAtomicBlock, STI);
228+ ErrorOccurred |= printInsts (*DisAsm, ByteArray, SM, Streamer,
229+ InAtomicBlock, STI, NumBenchmarkRuns );
212230 }
213231
214232 if (InAtomicBlock) {
0 commit comments