mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-01 15:02:40 +00:00
Num executions
This commit is contained in:
parent
418f7daa57
commit
da65ae3bcb
@ -875,6 +875,8 @@ set(SHADER_RECOMPILER src/shader_recompiler/exception.h
|
||||
src/shader_recompiler/ir/ir_emitter.cpp
|
||||
src/shader_recompiler/ir/ir_emitter.h
|
||||
src/shader_recompiler/ir/microinstruction.cpp
|
||||
src/shader_recompiler/ir/num_executions.cpp
|
||||
src/shader_recompiler/ir/num_executions.cpp
|
||||
src/shader_recompiler/ir/opcodes.cpp
|
||||
src/shader_recompiler/ir/opcodes.h
|
||||
src/shader_recompiler/ir/opcodes.inc
|
||||
|
@ -23,7 +23,7 @@ static void Invoke(ImmValueList& inst_values, const std::array<ImmValueList, siz
|
||||
}
|
||||
|
||||
template <auto func>
|
||||
static void Invoke(Inst* inst, ImmValueList& inst_values, ComputeImmValuesCache& cache) {
|
||||
static void Invoke(Inst* inst, ImmValueList& inst_values, Cache& cache) {
|
||||
using Traits = Common::FuncTraits<decltype(func)>;
|
||||
constexpr size_t num_args = Traits::NUM_ARGS - 1;
|
||||
ASSERT(inst->NumArgs() >= num_args);
|
||||
@ -34,8 +34,7 @@ static void Invoke(Inst* inst, ImmValueList& inst_values, ComputeImmValuesCache&
|
||||
Invoke<func>(inst_values, args, std::make_index_sequence<num_args>{});
|
||||
}
|
||||
|
||||
static void DoInstructionOperation(Inst* inst, ImmValueList& inst_values,
|
||||
ComputeImmValuesCache& cache) {
|
||||
static void DoInstructionOperation(Inst* inst, ImmValueList& inst_values, Cache& cache) {
|
||||
switch (inst->GetOpcode()) {
|
||||
#define OPCODE(name, result_type, ...) \
|
||||
case Opcode::name: \
|
||||
@ -64,7 +63,7 @@ static bool IsSelectInst(Inst* inst) {
|
||||
}
|
||||
}
|
||||
|
||||
void Compute(const Value& value, ImmValueList& values, ComputeImmValuesCache& cache) {
|
||||
void Compute(const Value& value, ImmValueList& values, Cache& cache) {
|
||||
Value resolved = value.Resolve();
|
||||
if (ImmValue::IsSupportedValue(resolved)) {
|
||||
values.insert(ImmValue(resolved));
|
||||
|
@ -15,8 +15,8 @@
|
||||
namespace Shader::IR::ComputeValue {
|
||||
|
||||
using ImmValueList = std::unordered_set<ImmValue>;
|
||||
using ComputeImmValuesCache = boost::container::flat_map<Inst*, ImmValueList>;
|
||||
using Cache = boost::container::flat_map<Inst*, ImmValueList>;
|
||||
|
||||
void Compute(const Value& value, ImmValueList& values, ComputeImmValuesCache& cache);
|
||||
void Compute(const Value& value, ImmValueList& values, Cache& cache);
|
||||
|
||||
} // namespace Shader::IR::ComputeValue
|
61
src/shader_recompiler/ir/num_executions.cpp
Normal file
61
src/shader_recompiler/ir/num_executions.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/cartesian_invoke.h"
|
||||
#include "shader_recompiler/ir/basic_block.h"
|
||||
#include "shader_recompiler/ir/compute_value/compute.h"
|
||||
#include "shader_recompiler/ir/num_executions.h"
|
||||
|
||||
namespace Shader::IR {
|
||||
|
||||
static bool Is64BitCondition(const Inst* inst) {
|
||||
switch (inst->GetOpcode()) {
|
||||
case Opcode::SLessThan64:
|
||||
case Opcode::ULessThan64:
|
||||
case Opcode::IEqual64:
|
||||
case Opcode::INotEqual64:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static u64 GetDistance32(const ComputeValue::ImmValue& a, const ComputeValue::ImmValue& b) {
|
||||
return a.U32() < b.U32() ? b.U32() - a.U32() : a.U32() - b.U32();
|
||||
}
|
||||
|
||||
static u64 GetDistance64(const ComputeValue::ImmValue& a, const ComputeValue::ImmValue& b) {
|
||||
return a.U64() < b.U64() ? b.U64() - a.U64() : a.U64() - b.U64();
|
||||
}
|
||||
|
||||
u64 GetNumExecutions(const Inst* inst) {
|
||||
u64 num_executions = 1;
|
||||
const auto* cond_data = &inst->GetParent()->CondData();
|
||||
while (cond_data->asl_node) {
|
||||
if (cond_data->asl_node->type == AbstractSyntaxNode::Type::Loop) {
|
||||
ComputeValue::ImmValueList cond_arg0, cond_arg1;
|
||||
ComputeValue::Cache cache;
|
||||
Block* cont_block = cond_data->asl_node->data.loop.continue_block;
|
||||
Inst* cond_inst = cont_block->back().Arg(0).InstRecursive();
|
||||
ASSERT(cond_inst);
|
||||
ComputeValue::Compute(cond_inst->Arg(0), cond_arg0, cache);
|
||||
ComputeValue::Compute(cond_inst->Arg(1), cond_arg1, cache);
|
||||
std::unordered_set<u64> distances;
|
||||
if (Is64BitCondition(cond_inst)) {
|
||||
Common::CartesianInvoke(GetDistance64,
|
||||
std::insert_iterator(distances, distances.end()), cond_arg0,
|
||||
cond_arg1);
|
||||
} else {
|
||||
Common::CartesianInvoke(GetDistance32,
|
||||
std::insert_iterator(distances, distances.end()), cond_arg0,
|
||||
cond_arg1);
|
||||
}
|
||||
num_executions *=
|
||||
std::max<u64>(1, *std::max_element(distances.begin(), distances.end()));
|
||||
}
|
||||
cond_data = cond_data->parent;
|
||||
}
|
||||
return num_executions;
|
||||
}
|
||||
|
||||
} // namespace Shader::IR
|
16
src/shader_recompiler/ir/num_executions.h
Normal file
16
src/shader_recompiler/ir/num_executions.h
Normal file
@ -0,0 +1,16 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
#include "shader_recompiler/ir/type.h"
|
||||
|
||||
// Get the number of times an instruction will be executed.
|
||||
// 0 if it cannot be determined statically.
|
||||
|
||||
namespace Shader::IR {
|
||||
|
||||
u64 GetNumExecutions(const Inst* inst);
|
||||
|
||||
} // namespace Shader::IR
|
Loading…
Reference in New Issue
Block a user