diff options
Diffstat (limited to 'pcr/reicast-multilib-git/sh-block-graphs.patch')
-rw-r--r-- | pcr/reicast-multilib-git/sh-block-graphs.patch | 296 |
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()); + } + |