--trace_functions and --trace_function_coverage
This commit is contained in:
@@ -97,11 +97,10 @@ bool PPCFrontend::DeclareFunction(FunctionInfo* symbol_info) {
|
||||
|
||||
bool PPCFrontend::DefineFunction(FunctionInfo* symbol_info,
|
||||
uint32_t debug_info_flags,
|
||||
uint32_t trace_flags,
|
||||
Function** out_function) {
|
||||
PPCTranslator* translator = translator_pool_.Allocate(this);
|
||||
bool result = translator->Translate(symbol_info, debug_info_flags,
|
||||
trace_flags, out_function);
|
||||
bool result =
|
||||
translator->Translate(symbol_info, debug_info_flags, out_function);
|
||||
translator_pool_.Release(translator);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class PPCFrontend {
|
||||
|
||||
bool DeclareFunction(FunctionInfo* symbol_info);
|
||||
bool DefineFunction(FunctionInfo* symbol_info, uint32_t debug_info_flags,
|
||||
uint32_t trace_flags, Function** out_function);
|
||||
Function** out_function);
|
||||
|
||||
private:
|
||||
Processor* processor_;
|
||||
|
||||
@@ -53,6 +53,10 @@ bool PPCScanner::Scan(FunctionInfo* symbol_info, DebugInfo* debug_info) {
|
||||
|
||||
LOGPPC("Analyzing function %.8X...", symbol_info->address());
|
||||
|
||||
// For debug info, only if needed.
|
||||
uint32_t address_reference_count = 0;
|
||||
uint32_t instruction_result_count = 0;
|
||||
|
||||
uint32_t start_address = static_cast<uint32_t>(symbol_info->address());
|
||||
uint32_t end_address = static_cast<uint32_t>(symbol_info->end_address());
|
||||
uint32_t address = start_address;
|
||||
@@ -78,6 +82,10 @@ bool PPCScanner::Scan(FunctionInfo* symbol_info, DebugInfo* debug_info) {
|
||||
// This lookup is *expensive* and should be avoided when scanning.
|
||||
i.type = GetInstrType(i.code);
|
||||
|
||||
// TODO(benvanik): switch on instruction metadata.
|
||||
++address_reference_count;
|
||||
++instruction_result_count;
|
||||
|
||||
// Check if the function starts with a mfspr lr, as that's a good indication
|
||||
// of whether or not this is a normal function with a prolog/epilog.
|
||||
// Some valid leaf functions won't have this, but most will.
|
||||
@@ -274,6 +282,11 @@ bool PPCScanner::Scan(FunctionInfo* symbol_info, DebugInfo* debug_info) {
|
||||
// - if present, flag function as needing a stack
|
||||
// - record prolog/epilog lengths/stack size/etc
|
||||
|
||||
if (debug_info) {
|
||||
debug_info->set_address_reference_count(address_reference_count);
|
||||
debug_info->set_instruction_result_count(instruction_result_count);
|
||||
}
|
||||
|
||||
LOGPPC("Finished analyzing %.8X", start_address);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "xenia/cpu/frontend/ppc_instr.h"
|
||||
#include "xenia/cpu/frontend/ppc_scanner.h"
|
||||
#include "xenia/cpu/processor.h"
|
||||
#include "xenia/debug/debugger.h"
|
||||
#include "xenia/profiling.h"
|
||||
|
||||
namespace xe {
|
||||
@@ -87,7 +88,7 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
|
||||
PPCTranslator::~PPCTranslator() = default;
|
||||
|
||||
bool PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||
uint32_t debug_info_flags, uint32_t trace_flags,
|
||||
uint32_t debug_info_flags,
|
||||
Function** out_function) {
|
||||
SCOPE_profile_cpu_f("cpu");
|
||||
|
||||
@@ -99,7 +100,19 @@ bool PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||
|
||||
// NOTE: we only want to do this when required, as it's expensive to build.
|
||||
if (FLAGS_always_disasm) {
|
||||
debug_info_flags |= DEBUG_INFO_ALL_DISASM;
|
||||
debug_info_flags |= DebugInfoFlags::kDebugInfoAllDisasm;
|
||||
}
|
||||
if (FLAGS_trace_functions) {
|
||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctions;
|
||||
}
|
||||
if (FLAGS_trace_function_coverage) {
|
||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionCoverage;
|
||||
}
|
||||
if (FLAGS_trace_function_references) {
|
||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionReferences;
|
||||
}
|
||||
if (FLAGS_trace_function_data) {
|
||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionData;
|
||||
}
|
||||
std::unique_ptr<DebugInfo> debug_info;
|
||||
if (debug_info_flags) {
|
||||
@@ -111,8 +124,25 @@ bool PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Setup trace data, if needed.
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoTraceFunctions) {
|
||||
// Base trace data.
|
||||
size_t trace_data_size = debug::FunctionTraceData::SizeOfHeader();
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoTraceFunctionCoverage) {
|
||||
// Additional space for instruction coverage counts.
|
||||
trace_data_size += debug::FunctionTraceData::SizeOfInstructionCounts(
|
||||
symbol_info->address(), symbol_info->end_address());
|
||||
}
|
||||
uint8_t* trace_data =
|
||||
frontend_->processor()->debugger()->AllocateTraceFunctionData(
|
||||
trace_data_size);
|
||||
debug_info->trace_data().Reset(trace_data, trace_data_size,
|
||||
symbol_info->address(),
|
||||
symbol_info->end_address());
|
||||
}
|
||||
|
||||
// Stash source.
|
||||
if (debug_info_flags & DEBUG_INFO_SOURCE_DISASM) {
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoDisasmSource) {
|
||||
DumpSource(symbol_info, &string_buffer_);
|
||||
debug_info->set_source_disasm(string_buffer_.ToString());
|
||||
string_buffer_.Reset();
|
||||
@@ -132,7 +162,7 @@ bool PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||
}
|
||||
|
||||
// Stash raw HIR.
|
||||
if (debug_info_flags & DEBUG_INFO_RAW_HIR_DISASM) {
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoDisasmRawHir) {
|
||||
builder_->Dump(&string_buffer_);
|
||||
debug_info->set_raw_hir_disasm(string_buffer_.ToString());
|
||||
string_buffer_.Reset();
|
||||
@@ -144,7 +174,7 @@ bool PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||
}
|
||||
|
||||
// Stash optimized HIR.
|
||||
if (debug_info_flags & DEBUG_INFO_HIR_DISASM) {
|
||||
if (debug_info_flags & DebugInfoFlags::kDebugInfoDisasmHir) {
|
||||
builder_->Dump(&string_buffer_);
|
||||
debug_info->set_hir_disasm(string_buffer_.ToString());
|
||||
string_buffer_.Reset();
|
||||
@@ -152,7 +182,7 @@ bool PPCTranslator::Translate(FunctionInfo* symbol_info,
|
||||
|
||||
// Assemble to backend machine code.
|
||||
if (!assembler_->Assemble(symbol_info, builder_.get(), debug_info_flags,
|
||||
std::move(debug_info), trace_flags, out_function)) {
|
||||
std::move(debug_info), out_function)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class PPCTranslator {
|
||||
~PPCTranslator();
|
||||
|
||||
bool Translate(FunctionInfo* symbol_info, uint32_t debug_info_flags,
|
||||
uint32_t trace_flags, Function** out_function);
|
||||
Function** out_function);
|
||||
|
||||
private:
|
||||
void DumpSource(FunctionInfo* symbol_info, StringBuffer* string_buffer);
|
||||
|
||||
Reference in New Issue
Block a user