From bdf7eed045999d6b64ac383b91915849c9dec557 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Mon, 2 Aug 2021 15:44:47 +0100 Subject: [PATCH] aco/nops: create handle_raw_hazard_instr helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rhys Perry Reviewed-by: Daniel Schürmann Part-of: --- src/amd/compiler/aco_insert_NOPs.cpp | 52 +++++++++++++++++----------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/amd/compiler/aco_insert_NOPs.cpp b/src/amd/compiler/aco_insert_NOPs.cpp index 2dc2a8d60ad..dac9452421a 100644 --- a/src/amd/compiler/aco_insert_NOPs.cpp +++ b/src/amd/compiler/aco_insert_NOPs.cpp @@ -197,34 +197,44 @@ regs_intersect(PhysReg a_reg, unsigned a_size, PhysReg b_reg, unsigned b_size) return a_reg > b_reg ? (a_reg - b_reg < b_size) : (b_reg - a_reg < a_size); } +template +bool +handle_raw_hazard_instr(aco_ptr& pred, PhysReg reg, int* nops_needed, uint32_t* mask) +{ + unsigned mask_size = util_last_bit(*mask); + + uint32_t writemask = 0; + for (Definition& def : pred->definitions) { + if (regs_intersect(reg, mask_size, def.physReg(), def.size())) { + unsigned start = def.physReg() > reg ? def.physReg() - reg : 0; + unsigned end = MIN2(mask_size, start + def.size()); + writemask |= u_bit_consecutive(start, end - start); + } + } + + bool is_hazard = writemask != 0 && ((pred->isVALU() && Valu) || (pred->isVINTRP() && Vintrp) || + (pred->isSALU() && Salu)); + if (is_hazard) + return true; + + *mask &= ~writemask; + *nops_needed = MAX2(*nops_needed - get_wait_states(pred), 0); + + if (*mask == 0) + *nops_needed = 0; + + return *nops_needed == 0; +} + template int handle_raw_hazard_internal(Program* program, Block* block, int nops_needed, PhysReg reg, uint32_t mask) { for (int pred_idx = block->instructions.size() - 1; pred_idx >= 0; pred_idx--) { - aco_ptr& pred = block->instructions[pred_idx]; - - unsigned mask_size = util_last_bit(mask); - uint32_t writemask = 0; - for (Definition& def : pred->definitions) { - if (regs_intersect(reg, mask_size, def.physReg(), def.size())) { - unsigned start = def.physReg() > reg ? def.physReg() - reg : 0; - unsigned end = MIN2(mask_size, start + def.size()); - writemask |= u_bit_consecutive(start, end - start); - } - } - - bool is_hazard = writemask != 0 && ((pred->isVALU() && Valu) || - (pred->isVINTRP() && Vintrp) || (pred->isSALU() && Salu)); - if (is_hazard) + if (handle_raw_hazard_instr(block->instructions[pred_idx], reg, + &nops_needed, &mask)) return nops_needed; - - mask &= ~writemask; - nops_needed -= get_wait_states(pred); - - if (nops_needed <= 0 || mask == 0) - return 0; } int res = 0;