shader_ir: Use std::array with pair instead of unordered_map
Given the overall size of the maps are very small, we can use arrays of pairs here instead of always heap allocating a new map every time the functions are called. Given the small size of the maps, the difference in container lookups are negligible, especially given the entries are already sorted.
This commit is contained in:
parent
012d7f5233
commit
382717172e
|
@ -2,8 +2,9 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -271,21 +272,24 @@ Node ShaderIR::GetSaturatedHalfFloat(Node value, bool saturate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) {
|
Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) {
|
||||||
const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
|
static constexpr std::array comparison_table{
|
||||||
{PredCondition::LessThan, OperationCode::LogicalFLessThan},
|
std::pair{PredCondition::LessThan, OperationCode::LogicalFLessThan},
|
||||||
{PredCondition::Equal, OperationCode::LogicalFEqual},
|
std::pair{PredCondition::Equal, OperationCode::LogicalFEqual},
|
||||||
{PredCondition::LessEqual, OperationCode::LogicalFLessEqual},
|
std::pair{PredCondition::LessEqual, OperationCode::LogicalFLessEqual},
|
||||||
{PredCondition::GreaterThan, OperationCode::LogicalFGreaterThan},
|
std::pair{PredCondition::GreaterThan, OperationCode::LogicalFGreaterThan},
|
||||||
{PredCondition::NotEqual, OperationCode::LogicalFNotEqual},
|
std::pair{PredCondition::NotEqual, OperationCode::LogicalFNotEqual},
|
||||||
{PredCondition::GreaterEqual, OperationCode::LogicalFGreaterEqual},
|
std::pair{PredCondition::GreaterEqual, OperationCode::LogicalFGreaterEqual},
|
||||||
{PredCondition::LessThanWithNan, OperationCode::LogicalFLessThan},
|
std::pair{PredCondition::LessThanWithNan, OperationCode::LogicalFLessThan},
|
||||||
{PredCondition::NotEqualWithNan, OperationCode::LogicalFNotEqual},
|
std::pair{PredCondition::NotEqualWithNan, OperationCode::LogicalFNotEqual},
|
||||||
{PredCondition::LessEqualWithNan, OperationCode::LogicalFLessEqual},
|
std::pair{PredCondition::LessEqualWithNan, OperationCode::LogicalFLessEqual},
|
||||||
{PredCondition::GreaterThanWithNan, OperationCode::LogicalFGreaterThan},
|
std::pair{PredCondition::GreaterThanWithNan, OperationCode::LogicalFGreaterThan},
|
||||||
{PredCondition::GreaterEqualWithNan, OperationCode::LogicalFGreaterEqual}};
|
std::pair{PredCondition::GreaterEqualWithNan, OperationCode::LogicalFGreaterEqual},
|
||||||
|
};
|
||||||
|
|
||||||
const auto comparison{PredicateComparisonTable.find(condition)};
|
const auto comparison =
|
||||||
UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
|
std::find_if(comparison_table.cbegin(), comparison_table.cend(),
|
||||||
|
[condition](const auto entry) { return condition == entry.first; });
|
||||||
|
UNIMPLEMENTED_IF_MSG(comparison == comparison_table.cend(),
|
||||||
"Unknown predicate comparison operation");
|
"Unknown predicate comparison operation");
|
||||||
|
|
||||||
Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b);
|
Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b);
|
||||||
|
@ -306,21 +310,24 @@ Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, N
|
||||||
|
|
||||||
Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_signed, Node op_a,
|
Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_signed, Node op_a,
|
||||||
Node op_b) {
|
Node op_b) {
|
||||||
const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
|
static constexpr std::array comparison_table{
|
||||||
{PredCondition::LessThan, OperationCode::LogicalILessThan},
|
std::pair{PredCondition::LessThan, OperationCode::LogicalILessThan},
|
||||||
{PredCondition::Equal, OperationCode::LogicalIEqual},
|
std::pair{PredCondition::Equal, OperationCode::LogicalIEqual},
|
||||||
{PredCondition::LessEqual, OperationCode::LogicalILessEqual},
|
std::pair{PredCondition::LessEqual, OperationCode::LogicalILessEqual},
|
||||||
{PredCondition::GreaterThan, OperationCode::LogicalIGreaterThan},
|
std::pair{PredCondition::GreaterThan, OperationCode::LogicalIGreaterThan},
|
||||||
{PredCondition::NotEqual, OperationCode::LogicalINotEqual},
|
std::pair{PredCondition::NotEqual, OperationCode::LogicalINotEqual},
|
||||||
{PredCondition::GreaterEqual, OperationCode::LogicalIGreaterEqual},
|
std::pair{PredCondition::GreaterEqual, OperationCode::LogicalIGreaterEqual},
|
||||||
{PredCondition::LessThanWithNan, OperationCode::LogicalILessThan},
|
std::pair{PredCondition::LessThanWithNan, OperationCode::LogicalILessThan},
|
||||||
{PredCondition::NotEqualWithNan, OperationCode::LogicalINotEqual},
|
std::pair{PredCondition::NotEqualWithNan, OperationCode::LogicalINotEqual},
|
||||||
{PredCondition::LessEqualWithNan, OperationCode::LogicalILessEqual},
|
std::pair{PredCondition::LessEqualWithNan, OperationCode::LogicalILessEqual},
|
||||||
{PredCondition::GreaterThanWithNan, OperationCode::LogicalIGreaterThan},
|
std::pair{PredCondition::GreaterThanWithNan, OperationCode::LogicalIGreaterThan},
|
||||||
{PredCondition::GreaterEqualWithNan, OperationCode::LogicalIGreaterEqual}};
|
std::pair{PredCondition::GreaterEqualWithNan, OperationCode::LogicalIGreaterEqual},
|
||||||
|
};
|
||||||
|
|
||||||
const auto comparison{PredicateComparisonTable.find(condition)};
|
const auto comparison =
|
||||||
UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
|
std::find_if(comparison_table.cbegin(), comparison_table.cend(),
|
||||||
|
[condition](const auto entry) { return condition == entry.first; });
|
||||||
|
UNIMPLEMENTED_IF_MSG(comparison == comparison_table.cend(),
|
||||||
"Unknown predicate comparison operation");
|
"Unknown predicate comparison operation");
|
||||||
|
|
||||||
Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, std::move(op_a),
|
Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, std::move(op_a),
|
||||||
|
@ -337,36 +344,43 @@ Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_si
|
||||||
|
|
||||||
Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition, Node op_a,
|
Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition, Node op_a,
|
||||||
Node op_b) {
|
Node op_b) {
|
||||||
const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
|
static constexpr std::array comparison_table{
|
||||||
{PredCondition::LessThan, OperationCode::Logical2HLessThan},
|
std::pair{PredCondition::LessThan, OperationCode::Logical2HLessThan},
|
||||||
{PredCondition::Equal, OperationCode::Logical2HEqual},
|
std::pair{PredCondition::Equal, OperationCode::Logical2HEqual},
|
||||||
{PredCondition::LessEqual, OperationCode::Logical2HLessEqual},
|
std::pair{PredCondition::LessEqual, OperationCode::Logical2HLessEqual},
|
||||||
{PredCondition::GreaterThan, OperationCode::Logical2HGreaterThan},
|
std::pair{PredCondition::GreaterThan, OperationCode::Logical2HGreaterThan},
|
||||||
{PredCondition::NotEqual, OperationCode::Logical2HNotEqual},
|
std::pair{PredCondition::NotEqual, OperationCode::Logical2HNotEqual},
|
||||||
{PredCondition::GreaterEqual, OperationCode::Logical2HGreaterEqual},
|
std::pair{PredCondition::GreaterEqual, OperationCode::Logical2HGreaterEqual},
|
||||||
{PredCondition::LessThanWithNan, OperationCode::Logical2HLessThanWithNan},
|
std::pair{PredCondition::LessThanWithNan, OperationCode::Logical2HLessThanWithNan},
|
||||||
{PredCondition::NotEqualWithNan, OperationCode::Logical2HNotEqualWithNan},
|
std::pair{PredCondition::NotEqualWithNan, OperationCode::Logical2HNotEqualWithNan},
|
||||||
{PredCondition::LessEqualWithNan, OperationCode::Logical2HLessEqualWithNan},
|
std::pair{PredCondition::LessEqualWithNan, OperationCode::Logical2HLessEqualWithNan},
|
||||||
{PredCondition::GreaterThanWithNan, OperationCode::Logical2HGreaterThanWithNan},
|
std::pair{PredCondition::GreaterThanWithNan, OperationCode::Logical2HGreaterThanWithNan},
|
||||||
{PredCondition::GreaterEqualWithNan, OperationCode::Logical2HGreaterEqualWithNan}};
|
std::pair{PredCondition::GreaterEqualWithNan, OperationCode::Logical2HGreaterEqualWithNan},
|
||||||
|
};
|
||||||
|
|
||||||
const auto comparison{PredicateComparisonTable.find(condition)};
|
const auto comparison =
|
||||||
UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
|
std::find_if(comparison_table.cbegin(), comparison_table.cend(),
|
||||||
|
[condition](const auto entry) { return condition == entry.first; });
|
||||||
|
UNIMPLEMENTED_IF_MSG(comparison == comparison_table.cend(),
|
||||||
"Unknown predicate comparison operation");
|
"Unknown predicate comparison operation");
|
||||||
|
|
||||||
return Operation(comparison->second, NO_PRECISE, std::move(op_a), std::move(op_b));
|
return Operation(comparison->second, NO_PRECISE, std::move(op_a), std::move(op_b));
|
||||||
}
|
}
|
||||||
|
|
||||||
OperationCode ShaderIR::GetPredicateCombiner(PredOperation operation) {
|
OperationCode ShaderIR::GetPredicateCombiner(PredOperation operation) {
|
||||||
const std::unordered_map<PredOperation, OperationCode> PredicateOperationTable = {
|
static constexpr std::array operation_table{
|
||||||
{PredOperation::And, OperationCode::LogicalAnd},
|
OperationCode::LogicalAnd,
|
||||||
{PredOperation::Or, OperationCode::LogicalOr},
|
OperationCode::LogicalOr,
|
||||||
{PredOperation::Xor, OperationCode::LogicalXor},
|
OperationCode::LogicalXor,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto op = PredicateOperationTable.find(operation);
|
const auto index = static_cast<std::size_t>(operation);
|
||||||
UNIMPLEMENTED_IF_MSG(op == PredicateOperationTable.end(), "Unknown predicate operation");
|
if (index >= operation_table.size()) {
|
||||||
return op->second;
|
UNIMPLEMENTED_MSG("Unknown predicate operation.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return operation_table[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
Node ShaderIR::GetConditionCode(Tegra::Shader::ConditionCode cc) const {
|
Node ShaderIR::GetConditionCode(Tegra::Shader::ConditionCode cc) const {
|
||||||
|
|
Reference in New Issue