VarAction2: Detect ops on previous constants which become loads

pull/393/head
Jonathan G Rennison 2 years ago
parent 1fec7d6ddb
commit a5f5be2dff

@ -5657,6 +5657,23 @@ static void OptimiseVarAction2Adjust(VarAction2OptimiseState &state, const GrfSp
} else if ((prev_inference & VA2AIF_HAVE_CONSTANT) && adjust.variable == 0x1A && IsEvalAdjustUsableForConstantPropagation(adjust.operation)) {
/* Reduce constant operation on previous constant */
replace_with_constant_load(EvaluateDeterministicSpriteGroupAdjust(group->size, adjust, nullptr, state.current_constant, UINT_MAX));
} else if ((prev_inference & VA2AIF_HAVE_CONSTANT) && IsEvalAdjustOperationOnConstantEffectiveLoad(adjust.operation, state.current_constant)) {
/* Convert operation to a load */
DeterministicSpriteGroupAdjust current = group->adjusts.back();
group->adjusts.pop_back();
while (!group->adjusts.empty()) {
const DeterministicSpriteGroupAdjust &prev = group->adjusts.back();
if (prev.variable != 0x7E && !IsEvalAdjustWithSideEffects(prev.operation)) {
/* Delete useless operation */
group->adjusts.pop_back();
} else {
break;
}
}
current.operation = group->adjusts.size() == 1 ? DSGA_OP_ADD : DSGA_OP_RST;
group->adjusts.push_back(current);
OptimiseVarAction2Adjust(state, feature, varsize, group, group->adjusts.back());
return;
} else if (adjust.variable == 0x7E || adjust.type != DSGA_TYPE_NONE) {
/* Procedure call or complex adjustment */
if (adjust.operation == DSGA_OP_STO) handle_unpredictable_temp_store();

@ -265,6 +265,22 @@ inline bool IsEvalAdjustOperationCommutative(DeterministicSpriteGroupAdjustOpera
}
}
inline bool IsEvalAdjustOperationOnConstantEffectiveLoad(DeterministicSpriteGroupAdjustOperation op, uint32 constant)
{
switch (op) {
case DSGA_OP_ADD:
case DSGA_OP_OR:
case DSGA_OP_XOR:
return constant == 0;
case DSGA_OP_MUL:
return constant == 1;
default:
return false;
}
}
struct DeterministicSpriteGroupAdjust {
DeterministicSpriteGroupAdjustOperation operation;
DeterministicSpriteGroupAdjustType type;

Loading…
Cancel
Save