[Mesa-dev] [PATCH] vc4: Try to pair up instructions when only one of them has PM bit
Boyan Ding
boyan.j.ding at gmail.com
Fri Sep 11 07:19:47 PDT 2015
2015-08-30 15:07 GMT+08:00 Boyan Ding <boyan.j.ding at gmail.com>:
> 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>
Ping.
I ran piglit with the patch today on my rpi2 and found no regression.
Regards,
Boyan Ding
> ---
> Use 'git diff -w' for easier review
>
> 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..d6bc804 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)
> --
> 2.5.0
>
More information about the mesa-dev
mailing list