summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2012-07-06 15:06:59 -0700
committerEric Anholt <eric@anholt.net>2012-07-18 12:30:06 -0700
commita454f8ec6df9334df42249be910cc2d57d913bff (patch)
tree61d0b7849330f097c642121f50afc23d7fe1c4d0
parentfc01376c50c15938f3b78431023ca3281304663d (diff)
i965/fs.h: Refactor tests for instructions modifying a register.
There's one instance of a potential behavior change: propagate_constants may now propagate into a part of a vgrf after a different part of it was overwritten by a send that returns multiple registers. I don't think we ever generate IR that meets that condition, but it's something to note if we bisect behavior change to this. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp25
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp16
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_cse.cpp8
4 files changed, 16 insertions, 34 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index de049d5b1bf..630150dbffd 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -165,12 +165,21 @@ fs_inst::regs_written()
*/
return 1;
}
bool
+fs_inst::overwrites_reg(const fs_reg &reg)
+{
+ return (reg.file == dst.file &&
+ reg.reg == dst.reg &&
+ reg.reg_offset >= dst.reg_offset &&
+ reg.reg_offset < dst.reg_offset + regs_written());
+}
+
+bool
fs_inst::is_tex()
{
return (opcode == SHADER_OPCODE_TEX ||
opcode == FS_OPCODE_TXB ||
opcode == SHADER_OPCODE_TXD ||
opcode == SHADER_OPCODE_TXF ||
@@ -1397,15 +1406,13 @@ fs_visitor::propagate_constants()
default:
break;
}
}
if (scan_inst->dst.file == GRF &&
- scan_inst->dst.reg == inst->dst.reg &&
- (scan_inst->dst.reg_offset == inst->dst.reg_offset ||
- scan_inst->regs_written() > 1)) {
+ scan_inst->overwrites_reg(inst->dst)) {
break;
}
}
}
if (progress)
@@ -1599,22 +1606,14 @@ fs_visitor::register_coalesce()
bool interfered = false;
for (fs_inst *scan_inst = (fs_inst *)inst->next;
!scan_inst->is_tail_sentinel();
scan_inst = (fs_inst *)scan_inst->next) {
if (scan_inst->dst.file == GRF) {
- if (scan_inst->dst.reg == inst->dst.reg &&
- (scan_inst->dst.reg_offset == inst->dst.reg_offset ||
- scan_inst->regs_written() > 1)) {
- interfered = true;
- break;
- }
- if (inst->src[0].file == GRF &&
- scan_inst->dst.reg == inst->src[0].reg &&
- (scan_inst->dst.reg_offset == inst->src[0].reg_offset ||
- scan_inst->regs_written() > 1)) {
+ if (scan_inst->overwrites_reg(inst->dst) ||
+ scan_inst->overwrites_reg(inst->src[0])) {
interfered = true;
break;
}
}
/* The gen6 MATH instruction can't handle source modifiers or
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
index deb58d84bee..6e3c46a39ea 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.h
+++ b/src/mesa/drivers/dri/i965/brw_fs.h
@@ -147,12 +147,13 @@ public:
fs_inst(enum opcode opcode, fs_reg dst, fs_reg src0, fs_reg src1);
fs_inst(enum opcode opcode, fs_reg dst,
fs_reg src0, fs_reg src1,fs_reg src2);
bool equals(fs_inst *inst);
int regs_written();
+ bool overwrites_reg(const fs_reg &reg);
bool is_tex();
bool is_math();
enum opcode opcode; /* BRW_OPCODE_* or FS_OPCODE_* */
fs_reg dst;
fs_reg src[3];
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 106964d4843..1870f43feba 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
@@ -95,29 +95,17 @@ fs_visitor::opt_copy_propagate_local(void *mem_ctx,
progress = true;
}
}
/* kill the destination from the ACP */
if (inst->dst.file == GRF) {
- int start_offset = inst->dst.reg_offset;
- int end_offset = start_offset + inst->regs_written();
-
foreach_list_safe(entry_node, acp) {
acp_entry *entry = (acp_entry *)entry_node;
- if (entry->dst.file == GRF &&
- entry->dst.reg == inst->dst.reg &&
- entry->dst.reg_offset >= start_offset &&
- entry->dst.reg_offset < end_offset) {
- entry->remove();
- continue;
- }
- if (entry->src.file == GRF &&
- entry->src.reg == inst->dst.reg &&
- entry->src.reg_offset >= start_offset &&
- entry->src.reg_offset < end_offset) {
+ if (inst->overwrites_reg(entry->dst) ||
+ inst->overwrites_reg(entry->src)) {
entry->remove();
}
}
}
/* If this instruction is a raw copy, add it to the ACP. */
diff --git a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
index fd28e14fd0e..7bf6698f91e 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
@@ -147,23 +147,17 @@ fs_visitor::opt_cse_local(fs_bblock *block, exec_list *aeb)
/* Continue iteration with copy->next */
inst = copy;
}
}
/* Kill all AEB entries that use the destination. */
- int start_offset = inst->dst.reg_offset;
- int end_offset = start_offset + inst->regs_written();
-
foreach_list_safe(entry_node, aeb) {
aeb_entry *entry = (aeb_entry *)entry_node;
for (int i = 0; i < 3; i++) {
- if (entry->generator->src[i].file == inst->dst.file &&
- entry->generator->src[i].reg == inst->dst.reg &&
- entry->generator->src[i].reg_offset >= start_offset &&
- entry->generator->src[i].reg_offset < end_offset) {
+ if (inst->overwrites_reg(entry->generator->src[i])) {
entry->remove();
ralloc_free(entry);
break;
}
}
}