brw/copy: Prepare copy_propagation for load_reg
The changes to try_copy_propagate will be removed later in the series. v2: Fix up some comments to note that offset != 0 is allowed only when stride == 0. Apply same offset=0 restriction in try_copy_propagate_def too. Allow copy propagation if the source is either a def or UNIFORM. Don't copy prop a load_reg through a non-def value. Reviewed-by: Caio Oliveira <caio.oliveira@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31497>
This commit is contained in:
@@ -660,13 +660,25 @@ instruction_requires_packed_data(brw_inst *inst)
|
||||
}
|
||||
|
||||
static bool
|
||||
try_copy_propagate(brw_shader &s, brw_inst *inst,
|
||||
try_copy_propagate(brw_shader &s, const brw_def_analysis &defs, brw_inst *inst,
|
||||
acp_entry *entry, int arg,
|
||||
uint8_t max_polygons)
|
||||
{
|
||||
if (inst->src[arg].file != VGRF)
|
||||
return false;
|
||||
|
||||
/* Do not copy propage a load_reg value to a different block through a
|
||||
* non-def. This can occur when `entry` is the loop counter, and `inst` is
|
||||
* a use of the loop counter outside the loop. If the use outside the loop
|
||||
* is replaced with the def from the load_reg, def analysis will later
|
||||
* determine that the load_reg does not produce a def.
|
||||
*/
|
||||
const brw_inst *const def = defs.get(entry->src);
|
||||
if (def != NULL && def->opcode == SHADER_OPCODE_LOAD_REG &&
|
||||
def->block != inst->block) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct intel_device_info *devinfo = s.devinfo;
|
||||
|
||||
assert(entry->src.file == VGRF || entry->src.file == UNIFORM ||
|
||||
@@ -758,6 +770,16 @@ try_copy_propagate(brw_shader &s, brw_inst *inst,
|
||||
if (instruction_requires_packed_data(inst) && entry_stride != 1)
|
||||
return false;
|
||||
|
||||
/* load_reg loads a whole VGRF into a def. It is not allowed for the source
|
||||
* to have a stride or a non-zero offset (unless stride == 0). It is
|
||||
* allowed for the source to to be uniform.
|
||||
*/
|
||||
if (inst->opcode == SHADER_OPCODE_LOAD_REG &&
|
||||
!is_uniform(entry->src) &&
|
||||
(entry->src.offset != 0 || entry_stride > 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const brw_reg_type dst_type = (has_source_modifiers &&
|
||||
entry->dst.type != inst->src[arg].type) ?
|
||||
entry->dst.type : inst->dst.type;
|
||||
@@ -1379,6 +1401,7 @@ opt_copy_propagation_local(brw_shader &s, linear_ctx *lin_ctx,
|
||||
uint8_t max_polygons)
|
||||
{
|
||||
const struct intel_device_info *devinfo = s.devinfo;
|
||||
const brw_def_analysis &defs = s.def_analysis.require();
|
||||
bool progress = false;
|
||||
|
||||
foreach_inst_in_block(brw_inst, inst, block) {
|
||||
@@ -1397,7 +1420,7 @@ opt_copy_propagation_local(brw_shader &s, linear_ctx *lin_ctx,
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (try_copy_propagate(s, inst, *iter, i, max_polygons)) {
|
||||
if (try_copy_propagate(s, defs, inst, *iter, i, max_polygons)) {
|
||||
progress = true;
|
||||
break;
|
||||
}
|
||||
@@ -1638,6 +1661,16 @@ try_copy_propagate_def(brw_shader &s,
|
||||
if (instruction_requires_packed_data(inst) && entry_stride != 1)
|
||||
return false;
|
||||
|
||||
/* load_reg loads a whole VGRF into a def. It is not allowed for the source
|
||||
* to have a stride or a non-zero offset (unless stride == 0). It is
|
||||
* allowed for the source to to be uniform.
|
||||
*/
|
||||
if (inst->opcode == SHADER_OPCODE_LOAD_REG &&
|
||||
!is_uniform(val) &&
|
||||
(val.offset != 0 || entry_stride > 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const brw_reg_type dst_type = (has_source_modifiers &&
|
||||
def->dst.type != inst->src[arg].type) ?
|
||||
def->dst.type : inst->dst.type;
|
||||
@@ -1845,6 +1878,21 @@ find_value_for_offset(brw_inst *def, const brw_reg &src, unsigned src_size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SHADER_OPCODE_LOAD_REG: {
|
||||
val = def->src[0];
|
||||
|
||||
unsigned rel_offset = src.offset - def->dst.offset;
|
||||
|
||||
if (val.stride == 0)
|
||||
rel_offset %= brw_type_size_bytes(def->dst.type);
|
||||
|
||||
if (val.file == IMM)
|
||||
val = extract_imm(val, src.type, rel_offset);
|
||||
else
|
||||
val = byte_offset(def->src[0], rel_offset);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1890,6 +1938,15 @@ brw_opt_copy_propagation_defs(brw_shader &s)
|
||||
}
|
||||
}
|
||||
|
||||
/* Only propagate through a load_reg if the source is a def or a
|
||||
* UNIFORM (since these are also always invariant). The destination
|
||||
* of a load_reg is always a def (by definition).
|
||||
*/
|
||||
if (def->opcode == SHADER_OPCODE_LOAD_REG &&
|
||||
(defs.get(def->src[0]) == NULL && def->src[0].file != UNIFORM)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
brw_reg val =
|
||||
find_value_for_offset(def, inst->src[i], inst->size_read(s.devinfo, i));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user