mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
Always inline functions
This commit is contained in:
parent
5c468d7591
commit
71c12360c7
@ -4991,6 +4991,17 @@ void RecompilationEngine::ProcessExecutionTrace(const ExecutionTrace & execution
|
|||||||
block_i = m_block_table.find(&key);
|
block_i = m_block_table.find(&key);
|
||||||
if (block_i == m_block_table.end()) {
|
if (block_i == m_block_table.end()) {
|
||||||
block_i = m_block_table.insert(m_block_table.end(), new BlockEntry(key.cfg.start_address, key.cfg.function_address));
|
block_i = m_block_table.insert(m_block_table.end(), new BlockEntry(key.cfg.start_address, key.cfg.function_address));
|
||||||
|
|
||||||
|
// Update the function to block map
|
||||||
|
auto function_to_block_i = m_function_to_blocks.find(execution_trace.function_address);
|
||||||
|
if (function_to_block_i == m_function_to_blocks.end()) {
|
||||||
|
function_to_block_i = m_function_to_blocks.insert(m_function_to_blocks.end(), std::make_pair(execution_trace.function_address, std::vector<BlockEntry *>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto i = std::find(function_to_block_i->second.begin(), function_to_block_i->second.end(), *block_i);
|
||||||
|
if (i == function_to_block_i->second.end()) {
|
||||||
|
function_to_block_i->second.push_back(*block_i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_block_list.push_back(*block_i);
|
tmp_block_list.push_back(*block_i);
|
||||||
@ -5013,7 +5024,7 @@ void RecompilationEngine::ProcessExecutionTrace(const ExecutionTrace & execution
|
|||||||
if (!(*i)->is_compiled) {
|
if (!(*i)->is_compiled) {
|
||||||
(*i)->num_hits++;
|
(*i)->num_hits++;
|
||||||
if ((*i)->num_hits >= 1000) { // TODO: Make this configurable
|
if ((*i)->num_hits >= 1000) { // TODO: Make this configurable
|
||||||
CompileBlock(*(*i), false);
|
CompileBlock(*(*i));
|
||||||
(*i)->is_compiled = true;
|
(*i)->is_compiled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5046,16 +5057,32 @@ void RecompilationEngine::UpdateControlFlowGraph(ControlFlowGraph & cfg, const E
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecompilationEngine::CompileBlock(BlockEntry & block_entry, bool inline_referenced_blocks) {
|
void RecompilationEngine::CompileBlock(BlockEntry & block_entry) {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
Log() << "Compile: " << block_entry.ToString() << "\n";
|
Log() << "Compile: " << block_entry.ToString() << "\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto is_function = block_entry.cfg.start_address == block_entry.cfg.function_address;
|
ControlFlowGraph * cfg;
|
||||||
auto ordinal = AllocateOrdinal(block_entry.cfg.start_address, is_function);
|
ControlFlowGraph temp_cfg(block_entry.cfg.start_address, block_entry.cfg.function_address);
|
||||||
auto executable = m_compiler.Compile(fmt::Format("fn_0x%08X_%u", block_entry.cfg.start_address, block_entry.revision++), block_entry.cfg,
|
if (block_entry.IsFunction()) {
|
||||||
is_function ? false : true /*inline_all*/,
|
// Form a CFG by merging all the blocks in this function
|
||||||
is_function ? true : false /*generate_linkable_exits*/);
|
auto function_to_block_i = m_function_to_blocks.find(block_entry.cfg.function_address);
|
||||||
|
for (auto block_i = function_to_block_i->second.begin(); block_i != function_to_block_i->second.end(); block_i++) {
|
||||||
|
temp_cfg += (*block_i)->cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg = &temp_cfg;
|
||||||
|
} else {
|
||||||
|
cfg = &block_entry.cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
Log() << "CFG: " << cfg->ToString() << "\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto ordinal = AllocateOrdinal(block_entry.cfg.start_address, block_entry.IsFunction());
|
||||||
|
auto executable = m_compiler.Compile(fmt::Format("fn_0x%08X_%u", block_entry.cfg.start_address, block_entry.revision++), *cfg, true,
|
||||||
|
block_entry.IsFunction() ? true : false /*generate_linkable_exits*/);
|
||||||
m_executable_lookup[ordinal] = executable;
|
m_executable_lookup[ordinal] = executable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,6 +182,34 @@ namespace ppu_recompiler_llvm {
|
|||||||
, function_address(function_address) {
|
, function_address(function_address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void operator += (const ControlFlowGraph & other) {
|
||||||
|
for (auto i = other.instruction_addresses.begin(); i != other.instruction_addresses.end(); i++) {
|
||||||
|
instruction_addresses.insert(*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = other.branches.begin(); i != other.branches.end(); i++) {
|
||||||
|
auto j = branches.find(i->first);
|
||||||
|
if (j == branches.end()) {
|
||||||
|
j = branches.insert(branches.begin(), std::make_pair(i->first, std::set<u32>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto k = i->second.begin(); k != i->second.end(); k++) {
|
||||||
|
j->second.insert(*k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = other.calls.begin(); i != other.calls.end(); i++) {
|
||||||
|
auto j = calls.find(i->first);
|
||||||
|
if (j == calls.end()) {
|
||||||
|
j = calls.insert(calls.begin(), std::make_pair(i->first, std::set<u32>()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto k = i->second.begin(); k != i->second.end(); k++) {
|
||||||
|
j->second.insert(*k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string ToString() const {
|
std::string ToString() const {
|
||||||
auto s = fmt::Format("0x%08X (0x%08X):", start_address, function_address);
|
auto s = fmt::Format("0x%08X (0x%08X):", start_address, function_address);
|
||||||
for (auto i = instruction_addresses.begin(); i != instruction_addresses.end(); i++) {
|
for (auto i = instruction_addresses.begin(); i != instruction_addresses.end(); i++) {
|
||||||
@ -240,13 +268,18 @@ namespace ppu_recompiler_llvm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString() const {
|
std::string ToString() const {
|
||||||
return fmt::Format("%s\nNumHits=%u, Revision=%u, IsCompiled=%c", cfg.ToString().c_str(), num_hits, revision, is_compiled ? 'Y' : 'N');
|
return fmt::Format("0x%08X (0x%08X): NumHits=%u, Revision=%u, IsCompiled=%c",
|
||||||
|
cfg.start_address, cfg.function_address, num_hits, revision, is_compiled ? 'Y' : 'N');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator == (const BlockEntry & other) const {
|
bool operator == (const BlockEntry & other) const {
|
||||||
return cfg.start_address == other.cfg.start_address;
|
return cfg.start_address == other.cfg.start_address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsFunction() const {
|
||||||
|
return cfg.function_address == cfg.start_address;
|
||||||
|
}
|
||||||
|
|
||||||
struct hash {
|
struct hash {
|
||||||
size_t operator()(const BlockEntry * e) const {
|
size_t operator()(const BlockEntry * e) const {
|
||||||
return e->cfg.start_address;
|
return e->cfg.start_address;
|
||||||
@ -984,6 +1017,9 @@ namespace ppu_recompiler_llvm {
|
|||||||
/// Block table
|
/// Block table
|
||||||
std::unordered_set<BlockEntry *, BlockEntry::hash, BlockEntry::equal_to> m_block_table;
|
std::unordered_set<BlockEntry *, BlockEntry::hash, BlockEntry::equal_to> m_block_table;
|
||||||
|
|
||||||
|
/// Maps a function to the set of all blocks in the function. Key is the address of the function.
|
||||||
|
std::unordered_map<u32, std::vector<BlockEntry *>> m_function_to_blocks;
|
||||||
|
|
||||||
/// Execution traces that have been already encountered. Data is the list of all blocks that this trace includes.
|
/// Execution traces that have been already encountered. Data is the list of all blocks that this trace includes.
|
||||||
std::unordered_map<ExecutionTrace::Id, std::vector<BlockEntry *>> m_processed_execution_traces;
|
std::unordered_map<ExecutionTrace::Id, std::vector<BlockEntry *>> m_processed_execution_traces;
|
||||||
|
|
||||||
@ -1021,7 +1057,7 @@ namespace ppu_recompiler_llvm {
|
|||||||
void UpdateControlFlowGraph(ControlFlowGraph & cfg, const ExecutionTraceEntry & this_entry, const ExecutionTraceEntry * next_entry);
|
void UpdateControlFlowGraph(ControlFlowGraph & cfg, const ExecutionTraceEntry & this_entry, const ExecutionTraceEntry * next_entry);
|
||||||
|
|
||||||
/// Compile a block
|
/// Compile a block
|
||||||
void CompileBlock(BlockEntry & block_entry, bool inline_referenced_blocks);
|
void CompileBlock(BlockEntry & block_entry);
|
||||||
|
|
||||||
/// Mutex used to prevent multiple creation
|
/// Mutex used to prevent multiple creation
|
||||||
static std::mutex s_mutex;
|
static std::mutex s_mutex;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user