VarAction2: Remove trivially redundant special stores
This commit is contained in:
@@ -237,6 +237,8 @@ struct VarAction2OptimiseState {
|
||||
bool check_expensive_vars = false;
|
||||
bool enable_dse = false;
|
||||
uint default_variable_version = 0;
|
||||
uint32 special_register_store_values[16];
|
||||
uint16 special_register_store_mask = 0;
|
||||
|
||||
inline VarAction2GroupVariableTracking *GetVarTracking(DeterministicSpriteGroup *group)
|
||||
{
|
||||
|
@@ -717,6 +717,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
|
||||
it.second.version++;
|
||||
}
|
||||
state.default_variable_version++;
|
||||
state.special_register_store_mask = 0;
|
||||
};
|
||||
auto handle_unpredictable_temp_store = [&]() {
|
||||
reset_store_values();
|
||||
@@ -900,6 +901,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
|
||||
std::bitset<256> seen_stores;
|
||||
bool seen_unpredictable_store = false;
|
||||
bool seen_special_store = false;
|
||||
uint16 seen_special_store_mask = 0;
|
||||
bool seen_perm_store = false;
|
||||
auto handle_proc_stores = y_combinator([&](auto handle_proc_stores, const SpriteGroup *sg) -> void {
|
||||
if (sg == nullptr) return;
|
||||
@@ -921,6 +923,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
|
||||
seen_stores.set(adjust.and_mask, true);
|
||||
} else {
|
||||
seen_special_store = true;
|
||||
if (adjust.and_mask >= 0x100 && adjust.and_mask < 0x110) SetBit(seen_special_store_mask, adjust.and_mask - 0x100);
|
||||
}
|
||||
} else {
|
||||
/* Unpredictable store */
|
||||
@@ -932,6 +935,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
|
||||
seen_stores.set(adjust.divmod_val, true);
|
||||
} else {
|
||||
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) {
|
||||
@@ -991,6 +995,7 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
|
||||
}
|
||||
}
|
||||
}
|
||||
state.special_register_store_mask &= ~seen_special_store_mask;
|
||||
|
||||
state.seen_procedure_call = true;
|
||||
} else if (adjust.operation == DSGA_OP_RST) {
|
||||
@@ -1392,6 +1397,22 @@ void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSpecFeatu
|
||||
}
|
||||
}
|
||||
} 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.
|
||||
* Assume all variables except temp storage for now.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user