24
24
#include " llvm/MC/TargetRegistry.h"
25
25
#include " llvm/Support/MemoryBuffer.h"
26
26
#include " llvm/Support/SourceMgr.h"
27
+ #include " llvm/Support/TimeProfiler.h"
27
28
#include " llvm/Support/raw_ostream.h"
28
29
#include " llvm/TargetParser/Triple.h"
29
30
@@ -32,24 +33,29 @@ using namespace llvm;
32
33
typedef std::pair<std::vector<unsigned char >, std::vector<const char *>>
33
34
ByteArrayTy;
34
35
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,
36
47
SourceMgr &SM, MCStreamer &Streamer, bool InAtomicBlock,
37
- const MCSubtargetInfo &STI) {
48
+ const MCSubtargetInfo &STI, unsigned NumBenchmarkRuns ) {
38
49
ArrayRef<uint8_t > Data (Bytes.first );
39
50
40
51
// Disassemble it to strings.
41
52
uint64_t Size;
42
- uint64_t Index;
43
53
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) {
46
55
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);
53
59
switch (S) {
54
60
case MCDisassembler::Fail:
55
61
SM.PrintMessage (SMLoc::getFromPointer (Bytes.second [Index]),
@@ -74,6 +80,18 @@ static bool PrintInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes,
74
80
Streamer.emitInstruction (Inst, STI);
75
81
break ;
76
82
}
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
+ }
77
95
}
78
96
79
97
return false ;
@@ -151,7 +169,7 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
151
169
MCSubtargetInfo &STI, MCStreamer &Streamer,
152
170
MemoryBuffer &Buffer, SourceMgr &SM,
153
171
MCContext &Ctx, const MCTargetOptions &MCOptions,
154
- bool HexBytes) {
172
+ bool HexBytes, unsigned NumBenchmarkRuns ) {
155
173
std::unique_ptr<const MCRegisterInfo> MRI (T.createMCRegInfo (Triple));
156
174
if (!MRI) {
157
175
errs () << " error: no register info for target " << Triple << " \n " ;
@@ -207,8 +225,8 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple,
207
225
ErrorOccurred |= byteArrayFromString (ByteArray, Str, SM, HexBytes);
208
226
209
227
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 );
212
230
}
213
231
214
232
if (InAtomicBlock) {
0 commit comments