VarAction2: Remove trivially redundant special stores

This commit is contained in:
Jonathan G Rennison
2022-08-23 18:37:28 +01:00
parent d9aa2d6138
commit 4fd8634ff9
2 changed files with 23 additions and 0 deletions

View File

@@ -237,6 +237,8 @@ struct VarAction2OptimiseState {
bool check_expensive_vars = false; bool check_expensive_vars = false;
bool enable_dse = false; bool enable_dse = false;
uint default_variable_version = 0; uint default_variable_version = 0;
uint32 special_register_store_values[16];
uint16 special_register_store_mask = 0;
inline VarAction2GroupVariableTracking *GetVarTracking(DeterministicSpriteGroup *group) inline VarAction2GroupVariableTracking *GetVarTracking(DeterministicSpriteGroup *group)
{ {

View File

@@ -717,6 +717,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
it.second.version++; it.second.version++;
} }
state.default_variable_version++; state.default_variable_version++;
state.special_register_store_mask = 0;
}; };
auto handle_unpredictable_temp_store = [&]() { auto handle_unpredictable_temp_store = [&]() {
reset_store_values(); reset_store_values();
@@ -900,6 +901,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
std::bitset<256> seen_stores; std::bitset<256> seen_stores;
bool seen_unpredictable_store = false; bool seen_unpredictable_store = false;
bool seen_special_store = false; bool seen_special_store = false;
uint16 seen_special_store_mask = 0;
bool seen_perm_store = false; bool seen_perm_store = false;
auto handle_proc_stores = y_combinator([&](auto handle_proc_stores, const SpriteGroup *sg) -> void { auto handle_proc_stores = y_combinator([&](auto handle_proc_stores, const SpriteGroup *sg) -> void {
if (sg == nullptr) return; if (sg == nullptr) return;
@@ -921,6 +923,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
seen_stores.set(adjust.and_mask, true); seen_stores.set(adjust.and_mask, true);
} else { } else {
seen_special_store = true; seen_special_store = true;
if (adjust.and_mask >= 0x100 && adjust.and_mask < 0x110) SetBit(seen_special_store_mask, adjust.and_mask - 0x100);
} }
} else { } else {
/* Unpredictable store */ /* Unpredictable store */
@@ -932,6 +935,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
seen_stores.set(adjust.divmod_val, true); seen_stores.set(adjust.divmod_val, true);
} else { } else {
seen_special_store = true; seen_special_store = true;
if (adjust.divmod_val >= 0x100 && adjust.divmod_val < 0x110) SetBit(seen_special_store_mask, adjust.divmod_val - 0x100);
} }
} }
if (adjust.operation == DSGA_OP_STOP) { if (adjust.operation == DSGA_OP_STOP) {
@@ -991,6 +995,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
} }
} }
} }
state.special_register_store_mask &= ~seen_special_store_mask;
state.seen_procedure_call = true; state.seen_procedure_call = true;
} else if (adjust.operation == DSGA_OP_RST) { } else if (adjust.operation == DSGA_OP_RST) {
@@ -1392,6 +1397,22 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
} }
} }
} else { } else {
if (adjust.and_mask >= 0x100 && adjust.and_mask < 0x110) {
uint idx = adjust.and_mask - 0x100;
if (prev_inference & VA2AIF_HAVE_CONSTANT) {
if (HasBit(state.special_register_store_mask, idx) && state.special_register_store_values[idx] == state.current_constant) {
/* Remove redundant special store of same constant value */
group->adjusts.pop_back();
state.inference = prev_inference;
break;
}
SetBit(state.special_register_store_mask, idx);
state.special_register_store_values[idx] = state.current_constant;
} else {
ClrBit(state.special_register_store_mask, idx);
}
}
/* Store to special register, this can change the result of future variable loads for some variables. /* Store to special register, this can change the result of future variable loads for some variables.
* Assume all variables except temp storage for now. * Assume all variables except temp storage for now.
*/ */