From 5827f5f5d82b321b6952e8203c2cc2e38bade055 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 11 Jan 2015 00:44:17 -0800 Subject: [PATCH] Utility to dump instruction translation counts. --- src/alloy/frontend/ppc/ppc_hir_builder.cc | 1 + src/alloy/frontend/ppc/ppc_instr.cc | 49 +++++++++++++---------- src/alloy/frontend/ppc/ppc_instr.h | 2 + src/alloy/frontend/ppc/ppc_instr_tables.h | 4 +- src/alloy/frontend/ppc/ppc_translator.cc | 4 ++ 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/alloy/frontend/ppc/ppc_hir_builder.cc b/src/alloy/frontend/ppc/ppc_hir_builder.cc index cdf6f0230..06294a54c 100644 --- a/src/alloy/frontend/ppc/ppc_hir_builder.cc +++ b/src/alloy/frontend/ppc/ppc_hir_builder.cc @@ -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; diff --git a/src/alloy/frontend/ppc/ppc_instr.cc b/src/alloy/frontend/ppc/ppc_instr.cc index c90c46a37..04da51c9a 100644 --- a/src/alloy/frontend/ppc/ppc_instr.cc +++ b/src/alloy/frontend/ppc/ppc_instr.cc @@ -10,14 +10,30 @@ #include #include +#include #include +#include #include namespace alloy { namespace frontend { namespace ppc { +std::vector 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; diff --git a/src/alloy/frontend/ppc/ppc_instr.h b/src/alloy/frontend/ppc/ppc_instr.h index 96575a2c4..709d552c1 100644 --- a/src/alloy/frontend/ppc/ppc_instr.h +++ b/src/alloy/frontend/ppc/ppc_instr.h @@ -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); diff --git a/src/alloy/frontend/ppc/ppc_instr_tables.h b/src/alloy/frontend/ppc/ppc_instr_tables.h index 15819efc2..dec760993 100644 --- a/src/alloy/frontend/ppc/ppc_instr_tables.h +++ b/src/alloy/frontend/ppc/ppc_instr_tables.h @@ -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)) diff --git a/src/alloy/frontend/ppc/ppc_translator.cc b/src/alloy/frontend/ppc/ppc_translator.cc index 008ba8948..1b21c386d 100644 --- a/src/alloy/frontend/ppc/ppc_translator.cc +++ b/src/alloy/frontend/ppc/ppc_translator.cc @@ -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) {