[Mesa-dev] [PATCH 5/7] i965/fs: Don't dead code eliminate CMP(N).

Matt Turner mattst88 at gmail.com
Tue Oct 22 22:07:36 CEST 2013


An future commit will enable CSE for CMP instructions. It operates on
the following code

      cmp.ge.f0(8)  null     g45<8,8,1>F  0F
(+f0) sel(8)        g50<1>F  g40<8,8,1>F  g10<8,8,1>F
      cmp.ge.f0(8)  null     g45<8,8,1>F  0F
(+f0) sel(8)        g51<1>F  g41<8,8,1>F  g11<8,8,1>F
      cmp.ge.f0(8)  null     g45<8,8,1>F  0F
(+f0) sel(8)        g52<1>F  g42<8,8,1>F  g12<8,8,1>F
      cmp.ge.f0(8)  null     g45<8,8,1>F  0F
(+f0) sel(8)        g53<1>F  g43<8,8,1>F  g13<8,8,1>F

by adding a new cmp.ge.f0(8) instruction writing into a GRF destination
and replacing the existing compares with MOVs from that destination,
leading to:

      cmp.ge.f0(8)  g30<1>F  g45<8,8,1>F  0F
      mov(8)        null     g30<1>F
(+f0) sel(8)        g50<1>F  g40<8,8,1>F  g10<8,8,1>F
      mov(8)        null     g30<1>F
(+f0) sel(8)        g51<1>F  g41<8,8,1>F  g11<8,8,1>F
      mov(8)        null     g30<1>F
(+f0) sel(8)        g52<1>F  g42<8,8,1>F  g12<8,8,1>F
      mov(8)        null     g30<1>F
(+f0) sel(8)        g53<1>F  g43<8,8,1>F  g13<8,8,1>F

The next patch will enable dead code elimination of MOVs with a null
destination, which in turn would cause the pass to recognize that the
new compare's g30 destination is never read and delete the instruction.
This would leave the flag register in an unknown state and break the
program.

Since compare instructions write the flag register, they should not be
considered dead even if their destination is never read. Instead of
removing them if found to be dead, set their destination to null to free
a register.
---
 src/mesa/drivers/dri/i965/brw_fs.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 9b56764..5336851 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1906,10 +1906,12 @@ fs_visitor::dead_code_eliminate()
 
          if (dead) {
             /* Don't dead code eliminate instructions that write to the
-             * accumulator as a side-effect. Instead just set the destination
-             * to the null register to free it.
+             * accumulator or flag register as a side effect. Instead just set
+             * the destination to the null register to free it.
              */
             switch (inst->opcode) {
+            case BRW_OPCODE_CMP:
+            case BRW_OPCODE_CMPN:
             case BRW_OPCODE_ADDC:
             case BRW_OPCODE_SUBB:
             case BRW_OPCODE_MACH:
-- 
1.8.3.2



More information about the mesa-dev mailing list