mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 03:00:11 +01:00
Merge branch 'remove-mkvec' into 'main'
pan/bi: add pass to remove uneeded MKVEC post register allocation See merge request mesa/mesa!39020
This commit is contained in:
commit
3607a10966
4 changed files with 186 additions and 1 deletions
181
src/panfrost/compiler/bifrost/bi_opt_remove_mkvec.c
Normal file
181
src/panfrost/compiler/bifrost/bi_opt_remove_mkvec.c
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright (C) 2025 Google LLC.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Authors (Google):
|
||||
* Romaric Jodin <rjodin@google.com>
|
||||
*/
|
||||
|
||||
#include "util/hash_table.h"
|
||||
#include "compiler.h"
|
||||
|
||||
#define MULTIPLE_USES ((bi_instr *)(uintptr_t)1)
|
||||
#define INVALID_INSTR MULTIPLE_USES
|
||||
#define MAX_REG (64)
|
||||
|
||||
struct mkvec_state {
|
||||
bi_instr *writers[2];
|
||||
};
|
||||
|
||||
static bool
|
||||
is_valid(bi_instr *I)
|
||||
{
|
||||
return I != NULL && I != INVALID_INSTR;
|
||||
}
|
||||
|
||||
static enum bi_swizzle
|
||||
bi_compose_half_swizzle(enum bi_swizzle inner, enum bi_swizzle outer)
|
||||
{
|
||||
if (inner == BI_SWIZZLE_H10) {
|
||||
switch (outer) {
|
||||
case BI_SWIZZLE_H00:
|
||||
return BI_SWIZZLE_H11;
|
||||
case BI_SWIZZLE_H11:
|
||||
return BI_SWIZZLE_H00;
|
||||
default:
|
||||
UNREACHABLE(
|
||||
"Outer non-replicate swizzle should have been filtered out earlier ");
|
||||
}
|
||||
}
|
||||
return inner;
|
||||
}
|
||||
|
||||
static void
|
||||
update_mkvec_state(bi_instr *I, bi_index idx, bi_instr *mkvec,
|
||||
struct hash_table *mkvec_states)
|
||||
{
|
||||
if (!is_valid(mkvec) || I->nr_dests != 1)
|
||||
return;
|
||||
struct hash_entry *entry = _mesa_hash_table_search(mkvec_states, mkvec);
|
||||
struct mkvec_state *state = entry ? entry->data : NULL;
|
||||
if (!state)
|
||||
return;
|
||||
bi_foreach_src(mkvec, s) {
|
||||
bi_foreach_src(I, I_source) {
|
||||
if (bi_is_equiv(I->src[I_source], mkvec->dest[0])) {
|
||||
state->writers[s] = INVALID_INSTR;
|
||||
}
|
||||
}
|
||||
if (state->writers[s] == NULL && bi_is_value_equiv(idx, mkvec->src[s]))
|
||||
state->writers[s] = I;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_dest(bi_instr *I, bi_index idx, bi_instr **reg_to_mkvec,
|
||||
struct hash_table *mkvec_states)
|
||||
{
|
||||
if (idx.type != BI_INDEX_REGISTER)
|
||||
return;
|
||||
unsigned reg = idx.value;
|
||||
assert(reg < MAX_REG);
|
||||
update_mkvec_state(I, idx, reg_to_mkvec[reg], mkvec_states);
|
||||
reg_to_mkvec[reg] = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_src(bi_instr *mkvec, bi_index idx, bi_instr **reg_to_mkvec)
|
||||
{
|
||||
unsigned reg = idx.value;
|
||||
if (idx.type != BI_INDEX_REGISTER)
|
||||
return;
|
||||
assert(reg < MAX_REG);
|
||||
if (reg_to_mkvec[reg] == NULL) {
|
||||
reg_to_mkvec[reg] = mkvec;
|
||||
} else {
|
||||
reg_to_mkvec[reg] = MULTIPLE_USES;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_instr(bi_instr *I, bi_instr **reg_to_mkvec,
|
||||
struct hash_table *mkvec_states)
|
||||
{
|
||||
bi_foreach_dest(I, d) {
|
||||
handle_dest(I, I->dest[d], reg_to_mkvec, mkvec_states);
|
||||
}
|
||||
|
||||
switch (I->op) {
|
||||
case BI_OPCODE_MKVEC_V2I16:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
bi_foreach_src(I, s) {
|
||||
if (!bi_swizzle_replicates_16(I->src[s].swizzle)) {
|
||||
return;
|
||||
}
|
||||
handle_src(I, I->src[s], reg_to_mkvec);
|
||||
}
|
||||
|
||||
assert(_mesa_hash_table_search(mkvec_states, I) == NULL);
|
||||
struct mkvec_state *state = rzalloc(mkvec_states, struct mkvec_state);
|
||||
_mesa_hash_table_insert(mkvec_states, I, state);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_mkvec(bi_instr *mkvec, struct mkvec_state *state)
|
||||
{
|
||||
switch (mkvec->op) {
|
||||
case BI_OPCODE_MKVEC_V2I16: {
|
||||
if (!is_valid(state->writers[0]) || !is_valid(state->writers[1]))
|
||||
return;
|
||||
for (unsigned i = 0; i < 2; ++i) {
|
||||
bi_foreach_src(state->writers[i], s) {
|
||||
state->writers[i]->src[s].swizzle = bi_compose_half_swizzle(
|
||||
state->writers[i]->src[s].swizzle, mkvec->src[i].swizzle);
|
||||
}
|
||||
state->writers[i]->dest[0] = bi_half(mkvec->dest[0], i == 1);
|
||||
}
|
||||
bi_remove_instruction(mkvec);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bi_opt_remove_mkvec(bi_context *ctx)
|
||||
{
|
||||
bi_postra_liveness(ctx);
|
||||
|
||||
bi_foreach_block(ctx, block) {
|
||||
struct hash_table *mkvec_states = _mesa_pointer_hash_table_create(NULL);
|
||||
bi_instr *reg_to_mkvec[MAX_REG] = {NULL};
|
||||
|
||||
for (unsigned i = 0; i < MAX_REG; ++i) {
|
||||
if ((block->reg_live_out >> i) & 1)
|
||||
reg_to_mkvec[i] = MULTIPLE_USES;
|
||||
}
|
||||
|
||||
bi_foreach_instr_in_block_rev(block, I) {
|
||||
handle_instr(I, reg_to_mkvec, mkvec_states);
|
||||
}
|
||||
|
||||
hash_table_foreach(mkvec_states, entry)
|
||||
{
|
||||
remove_mkvec((bi_instr *)entry->key,
|
||||
(struct mkvec_state *)entry->data);
|
||||
}
|
||||
_mesa_hash_table_destroy(mkvec_states, NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -6747,8 +6747,10 @@ bi_compile_variant_nir(nir_shader *nir,
|
|||
|
||||
bi_register_allocate(ctx);
|
||||
|
||||
if (likely(optimize))
|
||||
if (likely(optimize)) {
|
||||
bi_opt_post_ra(ctx);
|
||||
bi_opt_remove_mkvec(ctx);
|
||||
}
|
||||
|
||||
if (bifrost_debug & BIFROST_DBG_SHADERS && !skip_internal)
|
||||
bi_print_shader(ctx, stdout);
|
||||
|
|
|
|||
|
|
@ -1444,6 +1444,7 @@ void bi_opt_dce_post_ra(bi_context *ctx);
|
|||
void bi_opt_message_preload(bi_context *ctx);
|
||||
void bi_opt_push_ubo(bi_context *ctx);
|
||||
void bi_opt_reorder_push(bi_context *ctx);
|
||||
void bi_opt_remove_mkvec(bi_context *ctx);
|
||||
void bi_lower_swizzle(bi_context *ctx);
|
||||
void bi_lower_fau(bi_context *ctx);
|
||||
void bi_assign_scoreboard(bi_context *ctx);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ libpanfrost_bifrost_files = files(
|
|||
'bi_opt_push_ubo.c',
|
||||
'bi_opt_mod_props.c',
|
||||
'bi_opt_dual_tex.c',
|
||||
'bi_opt_remove_mkvec.c',
|
||||
'bi_iterator_schedule.c',
|
||||
'bi_pressure_schedule.c',
|
||||
'bi_ra.c',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue