1212// ===----------------------------------------------------------------------===//
1313
1414#include " Disassembler.h"
15+ #include " llvm/ADT/Sequence.h"
1516#include " llvm/ADT/StringExtras.h"
1617#include " llvm/MC/MCAsmInfo.h"
1718#include " llvm/MC/MCContext.h"
2425#include " llvm/MC/TargetRegistry.h"
2526#include " llvm/Support/MemoryBuffer.h"
2627#include " llvm/Support/SourceMgr.h"
28+ #include " llvm/Support/TimeProfiler.h"
2729#include " llvm/Support/raw_ostream.h"
2830#include " llvm/TargetParser/Triple.h"
2931
@@ -32,24 +34,25 @@ using namespace llvm;
3234typedef std::pair<std::vector<unsigned char >, std::vector<const char *>>
3335 ByteArrayTy;
3436
35- static bool PrintInsts (const MCDisassembler &DisAsm, const ByteArrayTy &Bytes,
37+ static bool printInsts (const MCDisassembler &DisAsm, const ByteArrayTy &Bytes,
3638 SourceMgr &SM, MCStreamer &Streamer, bool InAtomicBlock,
37- const MCSubtargetInfo &STI) {
39+ const MCSubtargetInfo &STI, unsigned BenchmarkNumRuns ) {
3840 ArrayRef<uint8_t > Data (Bytes.first );
3941
4042 // Disassemble it to strings.
4143 uint64_t Size;
42- uint64_t Index;
4344
44- for (Index = 0 ; Index < Bytes.first .size (); Index += Size) {
45- MCInst Inst;
45+ for (uint64_t Index = 0 ; Index < Bytes.first .size (); Index += Size) {
46+ auto getInstruction = [&](MCInst &Inst) -> MCDisassembler::DecodeStatus {
47+ if (STI.getTargetTriple ().getArch () == Triple::hexagon)
48+ return DisAsm.getInstructionBundle (Inst, Size, Data.slice (Index), Index,
49+ nulls ());
50+ return DisAsm.getInstruction (Inst, Size, Data.slice (Index), Index,
51+ nulls ());
52+ };
4653
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 ());
54+ MCInst Inst;
55+ MCDisassembler::DecodeStatus S = getInstruction (Inst);
5356 switch (S) {
5457 case MCDisassembler::Fail:
5558 SM.PrintMessage (SMLoc::getFromPointer (Bytes.second [Index]),
@@ -74,12 +77,24 @@ static bool PrintInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes,
7477 Streamer.emitInstruction (Inst, STI);
7578 break ;
7679 }
80+
81+ if (S == MCDisassembler::Success && BenchmarkNumRuns != 0 ) {
82+ // Benchmark mode, collect timing for decoding the instruction several
83+ // times.
84+ MCInst BMInst;
85+ TimeTraceScope timeScope (" getInstruction" );
86+ for (unsigned _ : llvm::seq<unsigned >(BenchmarkNumRuns)) {
87+ BMInst.clear ();
88+ BMInst.setOpcode (0 );
89+ S = getInstruction (BMInst);
90+ }
91+ }
7792 }
7893
7994 return false ;
8095}
8196
82- static bool SkipToToken (StringRef &Str) {
97+ static bool skipToToken (StringRef &Str) {
8398 for (;;) {
8499 if (Str.empty ())
85100 return false ;
@@ -101,7 +116,7 @@ static bool SkipToToken(StringRef &Str) {
101116
102117static bool byteArrayFromString (ByteArrayTy &ByteArray, StringRef &Str,
103118 SourceMgr &SM, bool HexBytes) {
104- while (SkipToToken (Str)) {
119+ while (skipToToken (Str)) {
105120 // Handled by higher level
106121 if (Str[0 ] == ' [' || Str[0 ] == ' ]' )
107122 return false ;
@@ -151,7 +166,7 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
151166 MCSubtargetInfo &STI, MCStreamer &Streamer,
152167 MemoryBuffer &Buffer, SourceMgr &SM,
153168 MCContext &Ctx, const MCTargetOptions &MCOptions,
154- bool HexBytes) {
169+ bool HexBytes, unsigned BenchmarkNumRuns ) {
155170 std::unique_ptr<const MCRegisterInfo> MRI (T.createMCRegInfo (Triple));
156171 if (!MRI) {
157172 errs () << " error: no register info for target " << Triple << " \n " ;
@@ -179,7 +194,7 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
179194 StringRef Str = Buffer.getBuffer ();
180195 bool InAtomicBlock = false ;
181196
182- while (SkipToToken (Str)) {
197+ while (skipToToken (Str)) {
183198 ByteArray.first .clear ();
184199 ByteArray.second .clear ();
185200
@@ -207,8 +222,8 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
207222 ErrorOccurred |= byteArrayFromString (ByteArray, Str, SM, HexBytes);
208223
209224 if (!ByteArray.first .empty ())
210- ErrorOccurred |=
211- PrintInsts (*DisAsm, ByteArray, SM, Streamer, InAtomicBlock, STI);
225+ ErrorOccurred |= printInsts (*DisAsm, ByteArray, SM, Streamer,
226+ InAtomicBlock, STI, BenchmarkNumRuns );
212227 }
213228
214229 if (InAtomicBlock) {
0 commit comments