VarAction2: Re-order commutative skip on zero operation sequences
Such that less expensive variables can be tested first
This commit is contained in:
@@ -33,6 +33,7 @@ enum NewGRFOptimiserFlags {
|
|||||||
NGOF_NO_OPT_VARACT2_GROUP_PRUNE = 2,
|
NGOF_NO_OPT_VARACT2_GROUP_PRUNE = 2,
|
||||||
NGOF_NO_OPT_VARACT2_EXPENSIVE_VARS = 3,
|
NGOF_NO_OPT_VARACT2_EXPENSIVE_VARS = 3,
|
||||||
NGOF_NO_OPT_VARACT2_SIMPLIFY_STORES = 4,
|
NGOF_NO_OPT_VARACT2_SIMPLIFY_STORES = 4,
|
||||||
|
NGOF_NO_OPT_VARACT2_ADJUST_ORDERING = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool HasGrfOptimiserFlag(NewGRFOptimiserFlags flag)
|
inline bool HasGrfOptimiserFlag(NewGRFOptimiserFlags flag)
|
||||||
|
@@ -6650,6 +6650,55 @@ static void OptimiseVarAction2DeterministicSpriteGroupSimplifyStores(Determinist
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void OptimiseVarAction2DeterministicSpriteGroupAdjustOrdering(DeterministicSpriteGroup *group)
|
||||||
|
{
|
||||||
|
if (HasGrfOptimiserFlag(NGOF_NO_OPT_VARACT2_ADJUST_ORDERING)) return;
|
||||||
|
|
||||||
|
auto acceptable_variable = [](uint16 variable) -> bool {
|
||||||
|
return variable != 0x7E && variable != 0x7B;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto get_variable_expense = [&](uint16 variable) -> int {
|
||||||
|
if (variable == 0x1A) return -15;
|
||||||
|
if (IsVariableVeryCheap(variable, group->feature)) return -10;
|
||||||
|
if (variable == 0x7D || variable == 0x7C) return -5;
|
||||||
|
if (IsExpensiveVariable(variable, group->feature, group->var_scope)) return 10;
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i + 1 < group->adjusts.size(); i++) {
|
||||||
|
DeterministicSpriteGroupAdjust &adjust = group->adjusts[i];
|
||||||
|
|
||||||
|
if (adjust.operation == DSGA_OP_RST && acceptable_variable(adjust.variable)) {
|
||||||
|
DeterministicSpriteGroupAdjustOperation operation = group->adjusts[i + 1].operation;
|
||||||
|
const size_t start = i;
|
||||||
|
size_t end = i;
|
||||||
|
if (IsEvalAdjustWithZeroLastValueAlwaysZero(operation) && IsEvalAdjustOperationCommutative(operation)) {
|
||||||
|
for (size_t j = start + 1; j < group->adjusts.size(); j++) {
|
||||||
|
DeterministicSpriteGroupAdjust &next = group->adjusts[j];
|
||||||
|
if (next.operation == operation && acceptable_variable(next.variable) && (next.adjust_flags & DSGAF_SKIP_ON_ZERO)) {
|
||||||
|
end = j;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (end != start) {
|
||||||
|
adjust.operation = operation;
|
||||||
|
adjust.adjust_flags |= DSGAF_SKIP_ON_ZERO;
|
||||||
|
|
||||||
|
/* Sort so that the least expensive comes first */
|
||||||
|
std::stable_sort(group->adjusts.begin() + start, group->adjusts.begin() + end + 1, [&](const DeterministicSpriteGroupAdjust &a, const DeterministicSpriteGroupAdjust &b) -> bool {
|
||||||
|
return get_variable_expense(a.variable) < get_variable_expense(b.variable);
|
||||||
|
});
|
||||||
|
|
||||||
|
adjust.operation = DSGA_OP_RST;
|
||||||
|
adjust.adjust_flags &= ~DSGAF_SKIP_ON_ZERO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void OptimiseVarAction2DeterministicSpriteGroup(VarAction2OptimiseState &state, const GrfSpecFeature feature, const byte varsize, DeterministicSpriteGroup *group)
|
static void OptimiseVarAction2DeterministicSpriteGroup(VarAction2OptimiseState &state, const GrfSpecFeature feature, const byte varsize, DeterministicSpriteGroup *group)
|
||||||
{
|
{
|
||||||
if (unlikely(HasGrfOptimiserFlag(NGOF_NO_OPT_VARACT2))) return;
|
if (unlikely(HasGrfOptimiserFlag(NGOF_NO_OPT_VARACT2))) return;
|
||||||
@@ -6770,10 +6819,11 @@ static void OptimiseVarAction2DeterministicSpriteGroup(VarAction2OptimiseState &
|
|||||||
if (dse_candidate) {
|
if (dse_candidate) {
|
||||||
_cur.dead_store_elimination_candidates.push_back(group);
|
_cur.dead_store_elimination_candidates.push_back(group);
|
||||||
group->dsg_flags |= DSGF_VAR_TRACKING_PENDING;
|
group->dsg_flags |= DSGF_VAR_TRACKING_PENDING;
|
||||||
|
} else {
|
||||||
|
OptimiseVarAction2DeterministicSpriteGroupSimplifyStores(group);
|
||||||
|
OptimiseVarAction2DeterministicSpriteGroupAdjustOrdering(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dse_candidate) OptimiseVarAction2DeterministicSpriteGroupSimplifyStores(group);
|
|
||||||
|
|
||||||
if (state.check_expensive_vars && !HasGrfOptimiserFlag(NGOF_NO_OPT_VARACT2_EXPENSIVE_VARS)) {
|
if (state.check_expensive_vars && !HasGrfOptimiserFlag(NGOF_NO_OPT_VARACT2_EXPENSIVE_VARS)) {
|
||||||
if (dse_candidate) {
|
if (dse_candidate) {
|
||||||
_cur.pending_expensive_var_checks.push_back(group);
|
_cur.pending_expensive_var_checks.push_back(group);
|
||||||
@@ -7077,6 +7127,7 @@ static void HandleVarAction2OptimisationPasses()
|
|||||||
}
|
}
|
||||||
|
|
||||||
OptimiseVarAction2DeterministicSpriteGroupSimplifyStores(group);
|
OptimiseVarAction2DeterministicSpriteGroupSimplifyStores(group);
|
||||||
|
OptimiseVarAction2DeterministicSpriteGroupAdjustOrdering(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DeterministicSpriteGroup *group : _cur.pending_expensive_var_checks) {
|
for (DeterministicSpriteGroup *group : _cur.pending_expensive_var_checks) {
|
||||||
|
Reference in New Issue
Block a user