Mesa (main): ir3: Retire the cp postsched pass now that we do RA in SSA.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Jul 4 22:53:14 UTC 2022
Module: Mesa
Branch: main
Commit: 01988667fd2ba1c5aef46af9b3f4263ad3ec4715
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=01988667fd2ba1c5aef46af9b3f4263ad3ec4715
Author: Emma Anholt <emma at anholt.net>
Date: Thu Jun 30 11:50:11 2022 -0700
ir3: Retire the cp postsched pass now that we do RA in SSA.
Before, we needed CP post-sched to copy-propagate references to NIR
registers produced by out-of-ssa. Now that we're in SSA, this pass ends
up not doing anything useful, and actually gets in the way by occasionally
creating a cycle in the DAG.
The entire shader-db impact is:
instructions HURT: shaders/closed/steam/tropico-5/78.shader_test FRAG: 238 -> 242 (1.68%)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17320>
---
src/freedreno/ir3/ir3.h | 1 -
src/freedreno/ir3/ir3_compiler_nir.c | 6 -
src/freedreno/ir3/ir3_cp_postsched.c | 233 -----------------------------------
src/freedreno/ir3/meson.build | 1 -
4 files changed, 241 deletions(-)
diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h
index 2d94c3a7d2b..22cea029494 100644
--- a/src/freedreno/ir3/ir3.h
+++ b/src/freedreno/ir3/ir3.h
@@ -1843,7 +1843,6 @@ bool ir3_cf(struct ir3 *ir);
/* copy-propagate: */
bool ir3_cp(struct ir3 *ir, struct ir3_shader_variant *so);
-bool ir3_cp_postsched(struct ir3 *ir);
/* common subexpression elimination: */
bool ir3_cse(struct ir3 *ir);
diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c
index f451cc91321..7ac829a49ce 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -4822,12 +4822,6 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
ir3_debug_print(ir, "AFTER: ir3_sched");
- if (IR3_PASS(ir, ir3_cp_postsched)) {
- /* cleanup the result of removing unneeded mov's: */
- while (IR3_PASS(ir, ir3_dce, so)) {
- }
- }
-
/* Pre-assign VS inputs on a6xx+ binning pass shader, to align
* with draw pass VS, so binning and draw pass can both use the
* same VBO state.
diff --git a/src/freedreno/ir3/ir3_cp_postsched.c b/src/freedreno/ir3/ir3_cp_postsched.c
deleted file mode 100644
index dca18367f63..00000000000
--- a/src/freedreno/ir3/ir3_cp_postsched.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright © 2020 Google, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "util/ralloc.h"
-#include "util/u_dynarray.h"
-
-#include "ir3.h"
-
-/**
- * A bit more extra cleanup after sched pass. In particular, prior to
- * instruction scheduling, we can't easily eliminate unneeded mov's
- * from "arrays", because we don't yet know if there is an intervening
- * array-write scheduled before the use of the array-read.
- *
- * NOTE array is equivalent to nir "registers".. ie. it can be length of
- * one. It is basically anything that is not SSA.
- */
-
-/**
- * Check if any instruction before `use` and after `src` writes to the
- * specified array. If `offset` is negative, it is a relative (a0.x)
- * access and we care about all writes to the array (as we don't know
- * which array element is read). Otherwise in the case of non-relative
- * access, we only have to care about the write to the specified (>= 0)
- * offset. In this case, we update `def` to point to the last write in
- * between `use` and `src` to the same array, so that `use` points to
- * the correct array write.
- */
-static bool
-has_conflicting_write(struct ir3_instruction *src, struct ir3_instruction *use,
- struct ir3_register **def, unsigned id, int offset)
-{
- assert(src->block == use->block);
- bool last_write = true;
-
- /* NOTE that since src and use are in the same block, src by
- * definition appears in the block's instr_list before use:
- */
- foreach_instr_rev (instr, &use->node) {
- if (instr == src)
- break;
-
- foreach_dst (dst, instr) {
- /* if we are looking at a RELATIV read, we can't move
- * it past an a0.x write:
- */
- if (dst->num == regid(REG_A0, 0))
- return true;
-
- if (!is_dest_gpr(dst))
- continue;
-
- if (!(dst->flags & IR3_REG_ARRAY))
- continue;
-
- if (dst->array.id != id)
- continue;
-
- /*
- * At this point, we have narrowed down an instruction
- * that writes to the same array.. check if it the write
- * is to an array element that we care about:
- */
-
- /* is write to an unknown array element? */
- if (dst->flags & IR3_REG_RELATIV)
- return true;
-
- /* is read from an unknown array element? */
- if (offset < 0)
- return true;
-
- /* is write to same array element? */
- if (dst->array.offset == offset)
- return true;
-
- if (last_write)
- *def = dst;
-
- last_write = false;
- }
- }
-
- return false;
-}
-
-/* Can we fold the mov src into use without invalid flags? */
-static bool
-valid_flags(struct ir3_instruction *use, struct ir3_instruction *mov)
-{
- struct ir3_register *src = mov->srcs[0];
-
- foreach_src_n (reg, n, use) {
- if (ssa(reg) != mov)
- continue;
-
- if (!ir3_valid_flags(use, n, reg->flags | src->flags))
- return false;
- }
-
- return true;
-}
-
-static bool
-instr_cp_postsched(struct ir3_instruction *mov)
-{
- struct ir3_register *src = mov->srcs[0];
-
- /* only consider mov's from "arrays", other cases we have
- * already considered already:
- */
- if (!(src->flags & IR3_REG_ARRAY))
- return false;
-
- int offset = (src->flags & IR3_REG_RELATIV) ? -1 : src->array.offset;
-
- /* Once we move the array read directly into the consuming
- * instruction(s), we will also need to update instructions
- * that had a false-dep on the original mov to have deps
- * on the consuming instructions:
- */
- struct util_dynarray newdeps;
- util_dynarray_init(&newdeps, mov->uses);
-
- foreach_ssa_use (use, mov) {
- if (use->block != mov->block)
- continue;
-
- if (is_meta(use))
- continue;
-
- if (is_subgroup_cond_mov_macro(use))
- continue;
-
- struct ir3_register *def = src->def;
- if (has_conflicting_write(mov, use, &def, src->array.id, offset))
- continue;
-
- if (conflicts(mov->address, use->address))
- continue;
-
- if (!valid_flags(use, mov))
- continue;
-
- /* Ok, we've established that it is safe to remove this copy: */
-
- bool removed = false;
- foreach_src_n (reg, n, use) {
- if (ssa(reg) != mov)
- continue;
-
- use->srcs[n] = ir3_reg_clone(mov->block->shader, src);
-
- /* preserve (abs)/etc modifiers: */
- use->srcs[n]->flags |= reg->flags;
-
- /* If we're sinking the array read past any writes, make
- * sure to update it to point to the new previous write:
- */
- use->srcs[n]->def = def;
-
- removed = true;
- }
-
- /* the use could have been only a false-dep, only add to the newdeps
- * array and update the address if we've actually updated a real src
- * reg for the use:
- */
- if (removed) {
- if (src->flags & IR3_REG_RELATIV)
- ir3_instr_set_address(use, mov->address->def->instr);
-
- util_dynarray_append(&newdeps, struct ir3_instruction *, use);
-
- /* Remove the use from the src instruction: */
- _mesa_set_remove_key(mov->uses, use);
- }
- }
-
- /* Once we have the complete set of instruction(s) that are are now
- * directly reading from the array, update any false-dep uses to
- * now depend on these instructions. The only remaining uses at
- * this point should be false-deps:
- */
- foreach_ssa_use (use, mov) {
- util_dynarray_foreach (&newdeps, struct ir3_instruction *, instrp) {
- struct ir3_instruction *newdep = *instrp;
- ir3_instr_add_dep(use, newdep);
- }
- }
-
- return util_dynarray_num_elements(&newdeps, struct ir3_instruction **) > 0;
-}
-
-bool
-ir3_cp_postsched(struct ir3 *ir)
-{
- void *mem_ctx = ralloc_context(NULL);
- bool progress = false;
-
- ir3_find_ssa_uses(ir, mem_ctx, false);
-
- foreach_block (block, &ir->block_list) {
- foreach_instr_safe (instr, &block->instr_list) {
- if (is_same_type_mov(instr))
- progress |= instr_cp_postsched(instr);
- }
- }
-
- ralloc_free(mem_ctx);
-
- return progress;
-}
diff --git a/src/freedreno/ir3/meson.build b/src/freedreno/ir3/meson.build
index 031f0220da9..7dc641bbe83 100644
--- a/src/freedreno/ir3/meson.build
+++ b/src/freedreno/ir3/meson.build
@@ -76,7 +76,6 @@ libfreedreno_ir3_files = files(
'ir3_context.h',
'ir3_cf.c',
'ir3_cp.c',
- 'ir3_cp_postsched.c',
'ir3_cse.c',
'ir3_dce.c',
'ir3_delay.c',
More information about the mesa-commit
mailing list