Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 32 additions & 14 deletions llvm/tools/llvm-mc/Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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]),
Expand All @@ -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;
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -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) {
Expand Down
3 changes: 2 additions & 1 deletion llvm/tools/llvm-mc/Disassembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ class Disassembler {
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
Expand Down
38 changes: 37 additions & 1 deletion llvm/tools/llvm-mc/llvm-mc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -240,6 +242,24 @@ static cl::opt<ActionType> Action(
"Colored disassembly of strings of hex bytes")),
cl::cat(MCCategory));

static cl::opt<unsigned>
NumBenchmarkRuns("num-benchmark-runs",
cl::desc("Number of runs for decoder 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())
Expand Down Expand Up @@ -371,6 +391,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;
Expand Down Expand Up @@ -620,13 +654,15 @@ 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) {
Out->keep();
if (DwoOut)
DwoOut->keep();
}

return Res;
}