aco/value_numbering: use can_eliminate() function to avoid unnecessary hashmap lookups

No fossil-db changes.

Reviewed-by: Tony Wasserka <tony.wasserka@gmx.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9195>
This commit is contained in:
Daniel Schürmann 2020-12-22 11:59:26 +01:00
parent fbf791e70c
commit 690ac7409a
1 changed files with 68 additions and 32 deletions

View File

@ -226,8 +226,7 @@ struct InstrPred {
SMEM_instruction& bS = b->smem();
/* isel shouldn't be creating situations where this assertion fails */
assert(aS.prevent_overflow == bS.prevent_overflow);
return aS.sync.can_reorder() && bS.sync.can_reorder() &&
aS.sync == bS.sync && aS.glc == bS.glc && aS.dlc == bS.dlc &&
return aS.sync == bS.sync && aS.glc == bS.glc && aS.dlc == bS.dlc &&
aS.nv == bS.nv && aS.disable_wqm == bS.disable_wqm &&
aS.prevent_overflow == bS.prevent_overflow;
}
@ -259,11 +258,22 @@ struct InstrPred {
aR.reduce_op == bR.reduce_op &&
aR.cluster_size == bR.cluster_size;
}
case Format::DS: {
assert(a->opcode == aco_opcode::ds_bpermute_b32 ||
a->opcode == aco_opcode::ds_permute_b32 ||
a->opcode == aco_opcode::ds_swizzle_b32);
DS_instruction& aD = a->ds();
DS_instruction& bD = b->ds();
return aD.sync == bD.sync &&
aD.pass_flags == bD.pass_flags &&
aD.gds == bD.gds &&
aD.offset0 == bD.offset0 &&
aD.offset1 == bD.offset1;
}
case Format::MTBUF: {
MTBUF_instruction& aM = a->mtbuf();
MTBUF_instruction& bM = b->mtbuf();
return aM.sync.can_reorder() && bM.sync.can_reorder() &&
aM.sync == bM.sync &&
return aM.sync == bM.sync &&
aM.dfmt == bM.dfmt &&
aM.nfmt == bM.nfmt &&
aM.offset == bM.offset &&
@ -278,8 +288,7 @@ struct InstrPred {
case Format::MUBUF: {
MUBUF_instruction& aM = a->mubuf();
MUBUF_instruction& bM = b->mubuf();
return aM.sync.can_reorder() && bM.sync.can_reorder() &&
aM.sync == bM.sync &&
return aM.sync == bM.sync &&
aM.offset == bM.offset &&
aM.offen == bM.offen &&
aM.idxen == bM.idxen &&
@ -290,34 +299,10 @@ struct InstrPred {
aM.lds == bM.lds &&
aM.disable_wqm == bM.disable_wqm;
}
/* we want to optimize these in NIR and don't hassle with load-store dependencies */
case Format::FLAT:
case Format::GLOBAL:
case Format::SCRATCH:
case Format::EXP:
case Format::SOPP:
case Format::PSEUDO_BRANCH:
case Format::PSEUDO_BARRIER:
return false;
case Format::DS: {
if (a->opcode != aco_opcode::ds_bpermute_b32 &&
a->opcode != aco_opcode::ds_permute_b32 &&
a->opcode != aco_opcode::ds_swizzle_b32)
return false;
DS_instruction& aD = a->ds();
DS_instruction& bD = b->ds();
return aD.sync.can_reorder() && bD.sync.can_reorder() &&
aD.sync == bD.sync &&
aD.pass_flags == bD.pass_flags &&
aD.gds == bD.gds &&
aD.offset0 == bD.offset0 &&
aD.offset1 == bD.offset1;
}
case Format::MIMG: {
MIMG_instruction& aM = a->mimg();
MIMG_instruction& bM = b->mimg();
return aM.sync.can_reorder() && bM.sync.can_reorder() &&
aM.sync == bM.sync &&
return aM.sync == bM.sync &&
aM.dmask == bM.dmask &&
aM.unrm == bM.unrm &&
aM.glc == bM.glc &&
@ -330,6 +315,14 @@ struct InstrPred {
aM.d16 == bM.d16 &&
aM.disable_wqm == bM.disable_wqm;
}
case Format::FLAT:
case Format::GLOBAL:
case Format::SCRATCH:
case Format::EXP:
case Format::SOPP:
case Format::PSEUDO_BRANCH:
case Format::PSEUDO_BARRIER:
assert(false);
default:
return true;
}
@ -372,6 +365,49 @@ bool dominates(vn_ctx& ctx, uint32_t parent, uint32_t child)
return parent == child;
}
/** Returns whether this instruction can safely be removed
* and replaced by an equal expression.
* This is in particular true for ALU instructions and
* read-only memory instructions.
*
* Note that expr_set must not be used with instructions
* which cannot be eliminated.
*/
bool can_eliminate(aco_ptr<Instruction>& instr)
{
switch (instr->format) {
case Format::FLAT:
case Format::GLOBAL:
case Format::SCRATCH:
case Format::EXP:
case Format::SOPP:
case Format::PSEUDO_BRANCH:
case Format::PSEUDO_BARRIER:
return false;
case Format::DS:
return instr->opcode == aco_opcode::ds_bpermute_b32 ||
instr->opcode == aco_opcode::ds_permute_b32 ||
instr->opcode == aco_opcode::ds_swizzle_b32;
case Format::SMEM:
case Format::MUBUF:
case Format::MIMG:
case Format::MTBUF:
if (!get_sync_info(instr.get()).can_reorder())
return false;
break;
default:
break;
}
if (instr->definitions.empty() ||
instr->opcode == aco_opcode::p_phi ||
instr->opcode == aco_opcode::p_linear_phi ||
instr->definitions[0].isNoCSE())
return false;
return true;
}
void process_block(vn_ctx& ctx, Block& block)
{
std::vector<aco_ptr<Instruction>> new_instructions;
@ -391,7 +427,7 @@ void process_block(vn_ctx& ctx, Block& block)
instr->opcode == aco_opcode::p_demote_to_helper)
ctx.exec_id++;
if (instr->definitions.empty() || is_phi(instr) || instr->definitions[0].isNoCSE()) {
if (!can_eliminate(instr)) {
new_instructions.emplace_back(std::move(instr));
continue;
}