summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2015-04-03 11:07:47 -0700
committerJason Ekstrand <jason.ekstrand@intel.com>2015-04-17 11:01:34 -0700
commit472ef9a02f2e5c5d0caa2809cb736a0f4f0d4693 (patch)
treea9d191f4319479b8b47c489d8af5594415195bea /src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
parentbb99a58e7710acd19463646c38cdddbd926e89c4 (diff)
downloadexternal_mesa3d-472ef9a02f2e5c5d0caa2809cb736a0f4f0d4693.zip
external_mesa3d-472ef9a02f2e5c5d0caa2809cb736a0f4f0d4693.tar.gz
external_mesa3d-472ef9a02f2e5c5d0caa2809cb736a0f4f0d4693.tar.bz2
i965/fs: Change SEL and MOV types as needed to propagate source modifiers
SEL and MOV instructions, as long as they don't have source modifiers, are just copying bits around. This commit adds support to copy propagation to switch the type of a SEL or MOV instruction as needed so that it can propagate source modifiers. This is needed because NIR generates integer SEL and MOV instructions whenver it doesn't know what else to generate. shader-db results with NIR: total FS instructions in shared programs: 4360910 -> 4360186 (-0.02%) FS instructions in affected programs: 59094 -> 58370 (-1.23%) helped: 341 HURT: 0 GAINED: 2 LOST: 0 Signed-off-by: Jason Ekstrand <jason.ekstrand@intel.com> Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com> Reviewed-by: Matt Turner <mattst88@gmail.com>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp34
1 files changed, 30 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
index e8d092c..6a8e7bf 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
@@ -275,6 +275,16 @@ is_logic_op(enum opcode opcode)
opcode == BRW_OPCODE_NOT);
}
+static bool
+can_change_source_types(fs_inst *inst)
+{
+ return !inst->src[0].abs && !inst->src[0].negate &&
+ (inst->opcode == BRW_OPCODE_MOV ||
+ (inst->opcode == BRW_OPCODE_SEL &&
+ inst->predicate != BRW_PREDICATE_NONE &&
+ !inst->src[1].abs && !inst->src[1].negate));
+}
+
bool
fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry)
{
@@ -346,7 +356,9 @@ fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry)
type_sz(inst->src[arg].type)) % type_sz(entry->src.type) != 0)
return false;
- if (has_source_modifiers && entry->dst.type != inst->src[arg].type)
+ if (has_source_modifiers &&
+ entry->dst.type != inst->src[arg].type &&
+ !can_change_source_types(inst))
return false;
if (brw->gen >= 8 && (entry->src.negate || entry->src.abs) &&
@@ -412,9 +424,23 @@ fs_visitor::try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry)
break;
}
- if (!inst->src[arg].abs) {
- inst->src[arg].abs = entry->src.abs;
- inst->src[arg].negate ^= entry->src.negate;
+ if (has_source_modifiers) {
+ if (entry->dst.type != inst->src[arg].type) {
+ /* We are propagating source modifiers from a MOV with a different
+ * type. If we got here, then we can just change the source and
+ * destination types of the instruction and keep going.
+ */
+ assert(can_change_source_types(inst));
+ for (int i = 0; i < inst->sources; i++) {
+ inst->src[i].type = entry->dst.type;
+ }
+ inst->dst.type = entry->dst.type;
+ }
+
+ if (!inst->src[arg].abs) {
+ inst->src[arg].abs = entry->src.abs;
+ inst->src[arg].negate ^= entry->src.negate;
+ }
}
return true;