summaryrefslogtreecommitdiff
path: root/pcr/reicast-multilib-git/sh-block-graphs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'pcr/reicast-multilib-git/sh-block-graphs.patch')
-rw-r--r--pcr/reicast-multilib-git/sh-block-graphs.patch296
1 files changed, 296 insertions, 0 deletions
diff --git a/pcr/reicast-multilib-git/sh-block-graphs.patch b/pcr/reicast-multilib-git/sh-block-graphs.patch
new file mode 100644
index 000000000..c8e1bcf15
--- /dev/null
+++ b/pcr/reicast-multilib-git/sh-block-graphs.patch
@@ -0,0 +1,296 @@
+diff -Nur a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp
+--- a/core/hw/sh4/dyna/blockmanager.cpp 2015-10-06 21:43:53.030336315 -0300
++++ b/core/hw/sh4/dyna/blockmanager.cpp 2015-10-06 21:58:25.685653822 -0300
+@@ -122,7 +122,11 @@
+ }
+ else
+ {
+- printf("bm_GetBlock(%08X) failed ..\n",dynarec_code);
++ for (iter = blkmap.begin(); iter != blkmap.end(); iter++) {
++ if ((*iter)->contains_code((u8*)dynarec_code))
++ return *iter;
++ }
++ //printf("bm_GetBlock(%p, %p) failed ..\n",dynarec_code, ngen_FailedToFindBlock);
+ return 0;
+ }
+ }
+@@ -158,6 +162,8 @@
+ verify((void*)bm_GetCode(blk->addr)==(void*)ngen_FailedToFindBlock);
+ FPCA(blk->addr)=blk->code;
+
++ verify(bm_GetBlock(blk->addr) == blk);
++
+ #ifdef DYNA_OPROF
+ if (oprofHandle)
+ {
+diff -Nur a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h
+--- a/core/hw/sh4/dyna/blockmanager.h 2015-10-06 21:43:53.030336315 -0300
++++ b/core/hw/sh4/dyna/blockmanager.h 2015-10-06 21:58:25.685653822 -0300
+@@ -71,6 +71,7 @@
+
+ u32 memops;
+ u32 linkedmemops;
++ bool entry_block;
+ };
+
+ struct CachedBlockInfo: RuntimeBlockInfo_Core
+diff -Nur a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp
+--- a/core/hw/sh4/dyna/decoder.cpp 2015-10-06 21:43:53.030336315 -0300
++++ b/core/hw/sh4/dyna/decoder.cpp 2015-10-06 21:58:25.685653822 -0300
+@@ -14,6 +14,7 @@
+ #include "hw/sh4/sh4_core.h"
+ #include "hw/sh4/sh4_mem.h"
+ #include "decoder_opcodes.h"
++#include "../interpr/sh4_opcodes.h"
+
+ #define BLOCK_MAX_SH_OPS_SOFT 500
+ #define BLOCK_MAX_SH_OPS_HARD 511
+@@ -1098,6 +1099,13 @@
+ else
+ blk->guest_cycles+=CPU_RATIO;
+
++ if ((state.cpu.is_delayslot && OpDesc[op]->SetPC()) ||
++ OpDesc[op]->oph == iNotImplemented) {
++ blk->addr = -1;
++ return;
++ }
++
++
+ verify(!(state.cpu.is_delayslot && OpDesc[op]->SetPC()));
+ if (state.ngen.OnlyDynamicEnds || !OpDesc[op]->rec_oph)
+ {
+@@ -1168,6 +1176,8 @@
+ if (settings.dynarec.idleskip)
+ {
+ //Experimental hash-id based idle skip
++ if (blk->addr == 0x8C0B926A)
++ blk->guest_cycles *= 100;
+ if (strstr(idle_hash,blk->hash(false,true)))
+ {
+ //printf("IDLESKIP: %08X reloc match %s\n",blk->addr,blk->hash(false,true));
+diff -Nur a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp
+--- a/core/hw/sh4/dyna/driver.cpp 2015-10-06 21:43:53.030336315 -0300
++++ b/core/hw/sh4/dyna/driver.cpp 2015-10-06 21:58:25.685653822 -0300
+@@ -72,11 +72,24 @@
+ LastAddr=LastAddr_min;
+ memset(emit_GetCCPtr(),0xCC,emit_FreeSpace());
+ }
++
++#include <map>
++#include <algorithm>
++#include <set>
++
++typedef map<u32, RuntimeBlockInfo*> BlockGraph;
++
++vector<BlockGraph*> graphs;
++map<u32, BlockGraph*> blockgraphs;
++
+ void recSh4_ClearCache()
+ {
+ LastAddr=LastAddr_min;
+ bm_Reset();
+
++ graphs.clear();
++ blockgraphs.clear();
++
+ printf("recSh4:Dynarec Cache clear at %08X\n",curr_pc);
+ }
+
+@@ -212,9 +225,145 @@
+ AnalyseBlock(this);
+ }
+
++void merge_graphs(BlockGraph* one, BlockGraph* two) {
++ for (BlockGraph::iterator it = two->begin(); it != two->end(); it++) {
++ blockgraphs[it->second->addr] = one;
++ (*one)[it->second->addr] = it->second;
++ }
++ graphs.erase(find(graphs.begin(), graphs.end(), two));
++}
++
++void discover_graph(u32 bootstrap) {
++ BlockGraph* graph;
++ set<u32> resolved;
++ vector<u32> unresolved;
++
++ if (blockgraphs.count(bootstrap)) {
++ graph = blockgraphs[bootstrap];
++ (*graph)[bootstrap]->entry_block = true;
++ return;
++ } else {
++ graph = new BlockGraph();
++
++ graphs.push_back(graph);
++ }
++
++ unresolved.push_back(bootstrap);
++
++ while (unresolved.size()) {
++ u32 pc = unresolved[unresolved.size()-1];
++ unresolved.pop_back();
++
++ if (resolved.count(pc))
++ continue;
++
++ if (graph->count(pc))
++ continue;
++
++ if (blockgraphs.count(pc)) {
++ verify(blockgraphs[pc] != graph);
++ merge_graphs(blockgraphs[pc], graph);
++ graph = blockgraphs[pc];
++ resolved.clear();
++ continue;
++ }
++
++ resolved.insert(pc);
++ //printf("resolving %08X\n", pc);
++
++ RuntimeBlockInfo* rbi = ngen_AllocateBlock();
++ rbi->Setup(pc,fpscr);
++ rbi->entry_block = pc == bootstrap;
++
++ if (rbi->addr == -1)
++ continue;
++
++ (*graph)[pc] = rbi;
++ blockgraphs[pc] = graph;
++
++ if (rbi->BranchBlock !=-1 && rbi->BlockType != BET_StaticCall)
++ unresolved.push_back(rbi->BranchBlock);
++
++ if (rbi->NextBlock != -1)
++ unresolved.push_back(rbi->NextBlock);
++ }
++
++ int entrypoints = 0;
++
++ for (BlockGraph::iterator it = graph->begin(); it != graph->end(); it++) {
++ entrypoints += it->second->entry_block;
++ }
++
++ //printf("Graph: %d blocks w/ %d entrypoints, %d graphs\n", graph->size(), entrypoints, graphs.size());
++}
++
++void print_graphs() {
++ int top_runs = 0;
++ int total_runs = 0;
++ map<BlockGraph*, u32> graph_runs;
++
++ for (size_t i = 0; i < graphs.size(); i++) {
++ BlockGraph* graph = graphs[i];
++ for (BlockGraph::iterator it = graphs[i]->begin(); it != graphs[i]->end(); it++) {
++
++ RuntimeBlockInfo* natblock = bm_GetBlock(it->first);
++ if (!natblock || natblock->runs == 0)
++ continue;
++
++ if (natblock->runs > top_runs)
++ top_runs = natblock->runs;
++
++ total_runs += natblock->runs;
++
++ graph_runs[graph] += natblock->runs;
++ }
++ }
++
++ int baseline = top_runs / 100;
++
++ printf("<Graphdump\n");
++ for (size_t i = 0; i < graphs.size(); i++) {
++ BlockGraph* graph = graphs[i];
++ if (graph_runs[graph] < baseline)
++ continue;
++ printf("\tGraph: %p\n", graphs[i]);
++
++ int cnt = 0;
++ int cnt2 = 0;
++ for (BlockGraph::iterator it = graphs[i]->begin(); it != graphs[i]->end(); it++) {
++
++ RuntimeBlockInfo* natblock = bm_GetBlock(it->first);
++ if (!natblock || natblock->runs == 0 || natblock->runs < baseline) {
++ if (natblock) {
++ cnt2++;
++ natblock->runs = 0;
++ } else {
++ cnt++;
++ }
++ continue;
++ }
++ printf("\t\tBlock %08X, compiled: %d, entrypoint: %d, type: %d, len: %d, cycles: %d, runs %d, loop %d\n",
++ it->first, natblock != 0, it->second->entry_block, it->second->BlockType, it->second->oplist.size(),
++ it->second->guest_cycles, natblock ? natblock->runs : 0,
++ (it->second->BlockType == BET_Cond_0 || it->second->BlockType == BET_Cond_1) && graph->count(it->second->BranchBlock) );
++
++ if (natblock)
++ natblock->runs = 0;
++ }
++ if (cnt2) {
++ printf("\t\t and %d more not worth mentioning\n", cnt2);
++ }
++ if (cnt) {
++ printf("\t\t and %d more that never run\n", cnt);
++ }
++ }
++ printf("Graphdump>\n");
++}
++
+ DynarecCodeEntryPtr rdv_CompilePC()
+ {
+ u32 pc=next_pc;
++ discover_graph(pc);
+
+ if (emit_FreeSpace()<16*1024 || pc==0x8c0000e0 || pc==0xac010000 || pc==0xac008300)
+ recSh4_ClearCache();
+@@ -232,6 +381,7 @@
+ rbi->staging_runs=do_opts?100:-100;
+ ngen_Compile(rbi,DoCheck(rbi->addr),(pc&0xFFFFFF)==0x08300 || (pc&0xFFFFFF)==0x10000,false,do_opts);
+ verify(rbi->code!=0);
++ verify(rbi->host_code_size!=0);
+
+ bm_AddBlock(rbi);
+
+diff -Nur a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp
+--- a/core/linux-dist/main.cpp 2015-10-06 21:43:53.042336401 -0300
++++ b/core/linux-dist/main.cpp 2015-10-06 21:58:25.685653822 -0300
+@@ -189,6 +189,18 @@
+ #if defined(USE_SDL)
+ input_sdl_handle(port);
+ #endif
++
++ //Whatever happened to these?
++#if FEAT_SHREC != DYNAREC_NONE
++ /*
++ void print_graphs();
++ if ('b' == key) emit_WriteCodeCache();
++ if ('n' == key) bm_Reset();
++ if ('m' == key) bm_Sort();
++ if (',' == key) { emit_WriteCodeCache(); bm_Sort(); }
++ if ('q' == key) print_graphs();
++ */
++#endif
+ }
+
+ void os_DoEvents()
+diff -Nur a/core/rec-x64/rec_x64.cpp b/core/rec-x64/rec_x64.cpp
+--- a/core/rec-x64/rec_x64.cpp 2015-10-06 21:43:53.045336422 -0300
++++ b/core/rec-x64/rec_x64.cpp 2015-10-06 21:58:25.685653822 -0300
+@@ -162,6 +162,10 @@
+
+ sub(dword[rax], block->guest_cycles);
+
++ mov(rax, (size_t)&block->runs);
++ add(dword[rax], 1);
++
++
+ sub(rsp, 0x28);
+
+ for (size_t i = 0; i < block->oplist.size(); i++) {
+@@ -355,6 +359,7 @@
+
+ block->code = (DynarecCodeEntryPtr)getCode();
+
++ block->host_code_size = getSize();
+ emit_Skip(getSize());
+ }
+