VarAction2: Add helper functions for constant comparison adjust types

This commit is contained in:
Jonathan G Rennison
2022-06-08 19:40:36 +01:00
parent 249a20e47a
commit caebff85f5
2 changed files with 34 additions and 16 deletions

View File

@@ -5963,7 +5963,7 @@ static void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSp
} else if (adjust.operation == DSGA_OP_RST) { } else if (adjust.operation == DSGA_OP_RST) {
state.inference = VA2AIF_SINGLE_LOAD; state.inference = VA2AIF_SINGLE_LOAD;
} }
if (adjust.type == DSGA_TYPE_EQ || adjust.type == DSGA_TYPE_NEQ) { if (IsConstantComparisonAdjustType(adjust.type)) {
if (adjust.operation == DSGA_OP_RST) { if (adjust.operation == DSGA_OP_RST) {
state.inference |= VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO; state.inference |= VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO;
} else if (adjust.operation == DSGA_OP_OR || adjust.operation == DSGA_OP_XOR || adjust.operation == DSGA_OP_AND) { } else if (adjust.operation == DSGA_OP_OR || adjust.operation == DSGA_OP_XOR || adjust.operation == DSGA_OP_AND) {
@@ -6146,20 +6146,20 @@ static void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSp
state.inference = VA2AIF_PREV_TERNARY; state.inference = VA2AIF_PREV_TERNARY;
break; break;
} }
if (prev.operation == DSGA_OP_RST && (prev.type == DSGA_TYPE_EQ || prev.type == DSGA_TYPE_NEQ)) { if (prev.operation == DSGA_OP_RST && IsConstantComparisonAdjustType(prev.type)) {
prev.type = (prev.type == DSGA_TYPE_EQ) ? DSGA_TYPE_NEQ : DSGA_TYPE_EQ; prev.type = InvertConstantComparisonAdjustType(prev.type);
group->adjusts.pop_back(); group->adjusts.pop_back();
state.inference = VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO | VA2AIF_SINGLE_LOAD; state.inference = VA2AIF_SIGNED_NON_NEGATIVE | VA2AIF_ONE_OR_ZERO | VA2AIF_SINGLE_LOAD;
break; break;
} }
if (prev.operation == DSGA_OP_OR && (prev.type == DSGA_TYPE_EQ || prev.type == DSGA_TYPE_NEQ || (prev.type == DSGA_TYPE_NONE && (prev.adjust_flags & DSGAF_SKIP_ON_LSB_SET))) && group->adjusts.size() >= 3) { if (prev.operation == DSGA_OP_OR && (IsConstantComparisonAdjustType(prev.type) || (prev.type == DSGA_TYPE_NONE && (prev.adjust_flags & DSGAF_SKIP_ON_LSB_SET))) && group->adjusts.size() >= 3) {
DeterministicSpriteGroupAdjust &prev2 = group->adjusts[group->adjusts.size() - 3]; DeterministicSpriteGroupAdjust &prev2 = group->adjusts[group->adjusts.size() - 3];
bool found = false; bool found = false;
if (IsEvalAdjustOperationRelationalComparison(prev2.operation)) { if (IsEvalAdjustOperationRelationalComparison(prev2.operation)) {
prev2.operation = InvertEvalAdjustRelationalComparisonOperation(prev2.operation); prev2.operation = InvertEvalAdjustRelationalComparisonOperation(prev2.operation);
found = true; found = true;
} else if (prev2.operation == DSGA_OP_RST && (prev2.type == DSGA_TYPE_EQ || prev2.type == DSGA_TYPE_NEQ) ) { } else if (prev2.operation == DSGA_OP_RST && IsConstantComparisonAdjustType(prev2.type)) {
prev2.type = (prev2.type == DSGA_TYPE_EQ) ? DSGA_TYPE_NEQ : DSGA_TYPE_EQ; prev2.type = InvertConstantComparisonAdjustType(prev2.type);
found = true; found = true;
} }
if (found) { if (found) {
@@ -6167,7 +6167,7 @@ static void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSp
prev.type = DSGA_TYPE_EQ; prev.type = DSGA_TYPE_EQ;
prev.add_val = 0; prev.add_val = 0;
} else { } else {
prev.type = (prev.type == DSGA_TYPE_EQ) ? DSGA_TYPE_NEQ : DSGA_TYPE_EQ; prev.type = InvertConstantComparisonAdjustType(prev.type);
} }
prev.operation = DSGA_OP_AND; prev.operation = DSGA_OP_AND;
prev.adjust_flags = DSGAF_SKIP_ON_ZERO; prev.adjust_flags = DSGAF_SKIP_ON_ZERO;
@@ -6264,10 +6264,10 @@ static void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSp
if (prev_inference & VA2AIF_SINGLE_LOAD) { if (prev_inference & VA2AIF_SINGLE_LOAD) {
bool invert = false; bool invert = false;
const DeterministicSpriteGroupAdjust *prev_load = get_prev_single_load(&invert); const DeterministicSpriteGroupAdjust *prev_load = get_prev_single_load(&invert);
if (prev_load != nullptr && (!invert || prev_load->type == DSGA_TYPE_EQ || prev_load->type == DSGA_TYPE_NEQ)) { if (prev_load != nullptr && (!invert || IsConstantComparisonAdjustType(prev_load->type))) {
store.inference |= VA2AIF_SINGLE_LOAD; store.inference |= VA2AIF_SINGLE_LOAD;
store.var_source.type = prev_load->type; store.var_source.type = prev_load->type;
if (invert) store.var_source.type = (store.var_source.type == DSGA_TYPE_EQ) ? DSGA_TYPE_NEQ : DSGA_TYPE_EQ; if (invert) store.var_source.type = InvertConstantComparisonAdjustType(store.var_source.type);
store.var_source.variable = prev_load->variable; store.var_source.variable = prev_load->variable;
store.var_source.shift_num = prev_load->shift_num; store.var_source.shift_num = prev_load->shift_num;
store.var_source.parameter = prev_load->parameter; store.var_source.parameter = prev_load->parameter;
@@ -6593,7 +6593,7 @@ static void OptimiseVarAction2DeterministicSpriteGroupSimplifyStores(Determinist
DeterministicSpriteGroupAdjust &adjust = group->adjusts[i]; DeterministicSpriteGroupAdjust &adjust = group->adjusts[i];
if ((adjust.type == DSGA_TYPE_NONE || adjust.type == DSGA_TYPE_EQ || adjust.type == DSGA_TYPE_NEQ) && adjust.operation == DSGA_OP_RST && adjust.variable != 0x7E) { if ((adjust.type == DSGA_TYPE_NONE || IsConstantComparisonAdjustType(adjust.type)) && adjust.operation == DSGA_OP_RST && adjust.variable != 0x7E) {
src_adjust = (int)i; src_adjust = (int)i;
is_constant = (adjust.variable == 0x1A); is_constant = (adjust.variable == 0x1A);
continue; continue;
@@ -6832,7 +6832,7 @@ static std::bitset<256> HandleVarAction2DeadStoreElimination(DeterministicSprite
return false; return false;
} }
} }
if (target.type == DSGA_TYPE_NONE && target.shift_num == 0 && (target.and_mask == 0xFFFFFFFF || ((var_src_type == DSGA_TYPE_EQ || var_src_type == DSGA_TYPE_NEQ) && (target.and_mask & 1)))) { if (target.type == DSGA_TYPE_NONE && target.shift_num == 0 && (target.and_mask == 0xFFFFFFFF || (IsConstantComparisonAdjustType(var_src_type) && (target.and_mask & 1)))) {
target.type = var_src_type; target.type = var_src_type;
target.variable = var_src->variable; target.variable = var_src->variable;
target.shift_num = var_src->shift_num; target.shift_num = var_src->shift_num;
@@ -6841,11 +6841,11 @@ static std::bitset<256> HandleVarAction2DeadStoreElimination(DeterministicSprite
target.add_val = var_src->add_val; target.add_val = var_src->add_val;
target.divmod_val = var_src->divmod_val; target.divmod_val = var_src->divmod_val;
return true; return true;
} else if ((target.type == DSGA_TYPE_EQ || target.type == DSGA_TYPE_NEQ) && target.shift_num == 0 && (target.and_mask & 1) && target.add_val == 0 && } else if (IsConstantComparisonAdjustType(target.type) && target.shift_num == 0 && (target.and_mask & 1) && target.add_val == 0 &&
(var_src_type == DSGA_TYPE_EQ || var_src_type == DSGA_TYPE_NEQ)) { IsConstantComparisonAdjustType(var_src_type)) {
/* DSGA_TYPE_EQ/NEQ on target are OK if add_val is 0 because this is a boolean invert/convert of the incoming DSGA_TYPE_EQ/NEQ */ /* DSGA_TYPE_EQ/NEQ on target are OK if add_val is 0 because this is a boolean invert/convert of the incoming DSGA_TYPE_EQ/NEQ */
if (target.type == DSGA_TYPE_EQ) { if (target.type == DSGA_TYPE_EQ) {
target.type = (var_src_type == DSGA_TYPE_EQ) ? DSGA_TYPE_NEQ : DSGA_TYPE_EQ; target.type = InvertConstantComparisonAdjustType(var_src_type);
} else { } else {
target.type = var_src_type; target.type = var_src_type;
} }
@@ -6966,8 +6966,8 @@ static std::bitset<256> HandleVarAction2DeadStoreElimination(DeterministicSprite
if (IsEvalAdjustOperationRelationalComparison(prev.operation)) { if (IsEvalAdjustOperationRelationalComparison(prev.operation)) {
prev.operation = InvertEvalAdjustRelationalComparisonOperation(prev.operation); prev.operation = InvertEvalAdjustRelationalComparisonOperation(prev.operation);
erase_adjust(i + 1); erase_adjust(i + 1);
} else if (prev.operation == DSGA_OP_RST && (prev.type == DSGA_TYPE_EQ || prev.type == DSGA_TYPE_NEQ)) { } else if (prev.operation == DSGA_OP_RST && IsConstantComparisonAdjustType(prev.type)) {
prev.type = (prev.type == DSGA_TYPE_EQ) ? DSGA_TYPE_NEQ : DSGA_TYPE_EQ; prev.type = InvertConstantComparisonAdjustType(prev.type);
erase_adjust(i + 1); erase_adjust(i + 1);
} }
} }

View File

@@ -389,6 +389,24 @@ inline bool IsEvalAdjustWithZeroLastValueAlwaysZero(DeterministicSpriteGroupAdju
} }
} }
inline bool IsConstantComparisonAdjustType(DeterministicSpriteGroupAdjustType adjust_type)
{
switch (adjust_type) {
case DSGA_TYPE_EQ:
case DSGA_TYPE_NEQ:
return true;
default:
return false;
}
}
inline DeterministicSpriteGroupAdjustType InvertConstantComparisonAdjustType(DeterministicSpriteGroupAdjustType adjust_type)
{
assert(IsConstantComparisonAdjustType(adjust_type));
return (adjust_type == DSGA_TYPE_EQ) ? DSGA_TYPE_NEQ : DSGA_TYPE_EQ;
}
struct DeterministicSpriteGroupAdjust { struct DeterministicSpriteGroupAdjust {
DeterministicSpriteGroupAdjustOperation operation; DeterministicSpriteGroupAdjustOperation operation;
DeterministicSpriteGroupAdjustType type; DeterministicSpriteGroupAdjustType type;