Mesa (master): vc4: Try to pair up instructions when only one of them has PM bit

Eric Anholt anholt at kemper.freedesktop.org
Thu Sep 17 19:00:47 UTC 2015


Module: Mesa
Branch: master
Commit: 8d3b92af21afb58b6a65e18bb05785d7aae72c27
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8d3b92af21afb58b6a65e18bb05785d7aae72c27

Author: Boyan Ding <boyan.j.ding at gmail.com>
Date:   Sun Aug 30 15:07:33 2015 +0800

vc4: Try to pair up instructions when only one of them has PM bit

Instructions with difference in PM field can actually be paired up if
the one without PM doesn't do packing/unpacking and non-NOP
packing/unpacking operations from PM instruction aren't added to the
other without PM.

total instructions in shared programs: 48209 -> 47460 (-1.55%)
instructions in affected programs:     11688 -> 10939 (-6.41%)

Signed-off-by: Boyan Ding <boyan.j.ding at gmail.com>
Reviewed-by: Eric Anholt <eric at anholt.net>

---

 src/gallium/drivers/vc4/vc4_qpu.c |  123 +++++++++++++++++++++++--------------
 1 file changed, 76 insertions(+), 47 deletions(-)

diff --git a/src/gallium/drivers/vc4/vc4_qpu.c b/src/gallium/drivers/vc4/vc4_qpu.c
index f67e3f8..6aa6b24 100644
--- a/src/gallium/drivers/vc4/vc4_qpu.c
+++ b/src/gallium/drivers/vc4/vc4_qpu.c
@@ -454,8 +454,7 @@ qpu_merge_inst(uint64_t a, uint64_t b)
                                 QPU_SET_FIELD(QPU_SIG_NONE, QPU_SIG));
 
         /* Misc fields that have to match exactly. */
-        ok = ok && merge_fields(&merge, a, b, QPU_SF | QPU_PM,
-                                ~0);
+        ok = ok && merge_fields(&merge, a, b, QPU_SF, ~0);
 
         if (!merge_fields(&merge, a, b, QPU_RADDR_A_MASK,
                           QPU_SET_FIELD(QPU_R_NOP, QPU_RADDR_A))) {
@@ -493,64 +492,94 @@ qpu_merge_inst(uint64_t a, uint64_t b)
                         return 0;
         }
 
-        /* packing: Make sure that non-NOP packs agree, then deal with
-         * special-case failing of adding a non-NOP pack to something with a
-         * NOP pack.
-         */
-        if (!merge_fields(&merge, a, b, QPU_PACK_MASK, 0))
-                return 0;
-        bool new_a_pack = (QPU_GET_FIELD(a, QPU_PACK) !=
-                           QPU_GET_FIELD(merge, QPU_PACK));
-        bool new_b_pack = (QPU_GET_FIELD(b, QPU_PACK) !=
-                           QPU_GET_FIELD(merge, QPU_PACK));
-        if (!(merge & QPU_PM)) {
-                /* Make sure we're not going to be putting a new
-                 * a-file packing on either half.
+        if (!merge_fields(&merge, a, b, QPU_PM, ~0)) {
+                /* If one instruction has PM bit set and the other not, the
+                 * one without PM shouldn't do packing/unpacking, and we
+                 * have to make sure non-NOP packing/unpacking from PM
+                 * instruction aren't added to it.
                  */
-                if (new_a_pack && writes_a_file(a))
-                        return 0;
+                uint64_t temp;
 
-                if (new_b_pack && writes_a_file(b))
-                        return 0;
-        } else {
-                /* Make sure we're not going to be putting new MUL packing on
-                 * either half.
-                 */
-                if (new_a_pack && QPU_GET_FIELD(a, QPU_OP_MUL) != QPU_M_NOP)
-                        return 0;
+                /* Let a be the one with PM bit */
+                if (!(a & QPU_PM)) {
+                        temp = a;
+                        a = b;
+                        b = temp;
+                }
 
-                if (new_b_pack && QPU_GET_FIELD(b, QPU_OP_MUL) != QPU_M_NOP)
+                if ((b & (QPU_PACK_MASK | QPU_UNPACK_MASK)) != 0)
                         return 0;
-        }
 
-        /* unpacking: Make sure that non-NOP unpacks agree, then deal with
-         * special-case failing of adding a non-NOP unpack to something with a
-         * NOP unpack.
-         */
-        if (!merge_fields(&merge, a, b, QPU_UNPACK_MASK, 0))
-                return 0;
-        bool new_a_unpack = (QPU_GET_FIELD(a, QPU_UNPACK) !=
-                             QPU_GET_FIELD(merge, QPU_UNPACK));
-        bool new_b_unpack = (QPU_GET_FIELD(b, QPU_UNPACK) !=
-                             QPU_GET_FIELD(merge, QPU_UNPACK));
-        if (!(merge & QPU_PM)) {
-                /* Make sure we're not going to be putting a new
-                 * a-file packing on either half.
-                 */
-                if (new_a_unpack && QPU_GET_FIELD(a, QPU_RADDR_A) != QPU_R_NOP)
+                if ((a & QPU_PACK_MASK) != 0 &&
+                    QPU_GET_FIELD(b, QPU_OP_MUL) != QPU_M_NOP)
                         return 0;
 
-                if (new_b_unpack && QPU_GET_FIELD(b, QPU_RADDR_A) != QPU_R_NOP)
+                if ((a & QPU_UNPACK_MASK) != 0 && reads_r4(b))
                         return 0;
         } else {
-                /* Make sure we're not going to be putting new r4 unpack on
-                 * either half.
+                /* packing: Make sure that non-NOP packs agree, then deal with
+                 * special-case failing of adding a non-NOP pack to something
+                 * with a NOP pack.
                  */
-                if (new_a_unpack && reads_r4(a))
+                if (!merge_fields(&merge, a, b, QPU_PACK_MASK, 0))
                         return 0;
+                bool new_a_pack = (QPU_GET_FIELD(a, QPU_PACK) !=
+                                QPU_GET_FIELD(merge, QPU_PACK));
+                bool new_b_pack = (QPU_GET_FIELD(b, QPU_PACK) !=
+                                QPU_GET_FIELD(merge, QPU_PACK));
+                if (!(merge & QPU_PM)) {
+                        /* Make sure we're not going to be putting a new
+                         * a-file packing on either half.
+                         */
+                        if (new_a_pack && writes_a_file(a))
+                                return 0;
+
+                        if (new_b_pack && writes_a_file(b))
+                                return 0;
+                } else {
+                        /* Make sure we're not going to be putting new MUL
+                         * packing oneither half.
+                         */
+                        if (new_a_pack &&
+                            QPU_GET_FIELD(a, QPU_OP_MUL) != QPU_M_NOP)
+                                return 0;
+
+                        if (new_b_pack &&
+                            QPU_GET_FIELD(b, QPU_OP_MUL) != QPU_M_NOP)
+                                return 0;
+                }
 
-                if (new_b_unpack && reads_r4(b))
+                /* unpacking: Make sure that non-NOP unpacks agree, then deal
+                 * with special-case failing of adding a non-NOP unpack to
+                 * something with a NOP unpack.
+                 */
+                if (!merge_fields(&merge, a, b, QPU_UNPACK_MASK, 0))
                         return 0;
+                bool new_a_unpack = (QPU_GET_FIELD(a, QPU_UNPACK) !=
+                                QPU_GET_FIELD(merge, QPU_UNPACK));
+                bool new_b_unpack = (QPU_GET_FIELD(b, QPU_UNPACK) !=
+                                QPU_GET_FIELD(merge, QPU_UNPACK));
+                if (!(merge & QPU_PM)) {
+                        /* Make sure we're not going to be putting a new
+                         * a-file packing on either half.
+                         */
+                        if (new_a_unpack &&
+                            QPU_GET_FIELD(a, QPU_RADDR_A) != QPU_R_NOP)
+                                return 0;
+
+                        if (new_b_unpack &&
+                            QPU_GET_FIELD(b, QPU_RADDR_A) != QPU_R_NOP)
+                                return 0;
+                } else {
+                        /* Make sure we're not going to be putting new r4
+                         * unpack on either half.
+                         */
+                        if (new_a_unpack && reads_r4(a))
+                                return 0;
+
+                        if (new_b_unpack && reads_r4(b))
+                                return 0;
+                }
         }
 
         if (ok)




More information about the mesa-commit mailing list