Utility to dump instruction translation counts.

This commit is contained in:
Ben Vanik 2015-01-11 00:44:17 -08:00
parent b6b27e621a
commit 5827f5f5d8
5 changed files with 37 additions and 23 deletions

View File

@ -122,6 +122,7 @@ int PPCHIRBuilder::Emit(FunctionInfo* symbol_info, uint32_t flags) {
// TraceInvalidInstruction(i);
continue;
}
++i.type->translation_count;
typedef int (*InstrEmitter)(PPCHIRBuilder& f, InstrData& i);
InstrEmitter emit = (InstrEmitter)i.type->emit;

View File

@ -10,14 +10,30 @@
#include <alloy/frontend/ppc/ppc_instr.h>
#include <sstream>
#include <vector>
#include <alloy/frontend/ppc/ppc_instr_tables.h>
#include <alloy/string_buffer.h>
#include <poly/poly.h>
namespace alloy {
namespace frontend {
namespace ppc {
std::vector<InstrType*> all_instrs_;
void DumpAllInstrCounts() {
StringBuffer sb;
sb.Append("Instruction translation counts:\n");
for (auto instr_type : all_instrs_) {
if (instr_type->translation_count) {
sb.Append("%8d : %s\n", instr_type->translation_count, instr_type->name);
}
}
fprintf(stdout, sb.GetString());
fflush(stdout);
}
void InstrOperand::Dump(std::string& out_str) {
if (display) {
out_str += display;
@ -322,48 +338,39 @@ InstrType* GetInstrType(uint32_t code) {
switch (code >> 26) {
case 4:
// Opcode = 4, index = bits 10-0 (10)
slot =
alloy::frontend::ppc::tables::instr_table_4[select_bits(code, 0, 10)];
slot = tables::instr_table_4[select_bits(code, 0, 10)];
break;
case 19:
// Opcode = 19, index = bits 10-1 (10)
slot = alloy::frontend::ppc::tables::instr_table_19[select_bits(code, 1,
10)];
slot = tables::instr_table_19[select_bits(code, 1, 10)];
break;
case 30:
// Opcode = 30, index = bits 4-1 (4)
// Special cased to an uber instruction.
slot =
alloy::frontend::ppc::tables::instr_table_30[select_bits(code, 0, 0)];
slot = tables::instr_table_30[select_bits(code, 0, 0)];
break;
case 31:
// Opcode = 31, index = bits 10-1 (10)
slot = alloy::frontend::ppc::tables::instr_table_31[select_bits(code, 1,
10)];
slot = tables::instr_table_31[select_bits(code, 1, 10)];
break;
case 58:
// Opcode = 58, index = bits 1-0 (2)
slot =
alloy::frontend::ppc::tables::instr_table_58[select_bits(code, 0, 1)];
slot = tables::instr_table_58[select_bits(code, 0, 1)];
break;
case 59:
// Opcode = 59, index = bits 5-1 (5)
slot =
alloy::frontend::ppc::tables::instr_table_59[select_bits(code, 1, 5)];
slot = tables::instr_table_59[select_bits(code, 1, 5)];
break;
case 62:
// Opcode = 62, index = bits 1-0 (2)
slot =
alloy::frontend::ppc::tables::instr_table_62[select_bits(code, 0, 1)];
slot = tables::instr_table_62[select_bits(code, 0, 1)];
break;
case 63:
// Opcode = 63, index = bits 10-1 (10)
slot = alloy::frontend::ppc::tables::instr_table_63[select_bits(code, 1,
10)];
slot = tables::instr_table_63[select_bits(code, 1, 10)];
break;
default:
slot =
alloy::frontend::ppc::tables::instr_table[select_bits(code, 26, 31)];
slot = tables::instr_table[select_bits(code, 26, 31)];
break;
}
if (slot && slot->opcode) {
@ -372,9 +379,8 @@ InstrType* GetInstrType(uint32_t code) {
// Slow lookup via linear scan.
// This is primarily due to laziness. It could be made fast like the others.
for (size_t n = 0;
n < poly::countof(alloy::frontend::ppc::tables::instr_table_scan); n++) {
slot = &(alloy::frontend::ppc::tables::instr_table_scan[n]);
for (size_t n = 0; n < poly::countof(tables::instr_table_scan); n++) {
slot = &(tables::instr_table_scan[n]);
if (slot->opcode == (code & slot->opcode_mask)) {
return slot;
}
@ -389,6 +395,7 @@ int RegisterInstrEmit(uint32_t code, InstrEmitFn emit) {
if (!instr_type) {
return 1;
}
all_instrs_.push_back(instr_type);
assert_null(instr_type->emit);
instr_type->emit = emit;
return 0;

View File

@ -561,10 +561,12 @@ class InstrType {
uint32_t flags; // xe_ppc_instr_flag_e
InstrDisasmFn disasm;
char name[16];
uint32_t translation_count;
InstrEmitFn emit;
};
void DumpAllInstrCounts();
InstrType* GetInstrType(uint32_t code);
int RegisterInstrEmit(uint32_t code, InstrEmitFn emit);

View File

@ -127,7 +127,7 @@ static InstrType** instr_table_prep_63(InstrType* unprep, size_t unprep_count,
#define INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \
{ \
opcode, 0, kXEPPCInstrFormat##format, kXEPPCInstrType##type, 0, \
Disasm_##disasm_fn, #name, \
Disasm_##disasm_fn, #name, 0, \
}
#define FLAG(t) kXEPPCInstrFlag##t
@ -844,7 +844,7 @@ static InstrType** instr_table = instr_table_prep(
#define SCAN_INSTRUCTION(name, opcode, format, type, disasm_fn, descr) \
{ \
opcode, kXEPPCInstrMask##format, kXEPPCInstrFormat##format, \
kXEPPCInstrType##type, 0, Disasm_##disasm_fn, #name, \
kXEPPCInstrType##type, 0, Disasm_##disasm_fn, #name, 0, \
}
#define OP(x) ((((uint32_t)(x)) & 0x3f) << 26)
#define VX128(op, xop) (OP(op) | (((uint32_t)(xop)) & 0x3d0))

View File

@ -124,6 +124,10 @@ int PPCTranslator::Translate(FunctionInfo* symbol_info,
string_buffer_.Reset();
}
if (false) {
alloy::frontend::ppc::DumpAllInstrCounts();
}
// Emit function.
uint32_t emit_flags = 0;
if (debug_info) {