r300: run dataflow optimizations in separate loops

Constant folding first, than copy propagate simple movs, after that
we run the merge movs pass and finally peephole. The important part
is to do the copy propagate for the whole program before running merge
movs.

We no longer check the return from merge_movs so convert it to void.

Shader-db changes with RV530:
total instructions in shared programs: 155361 -> 154787 (-0.37%)
instructions in affected programs: 67920 -> 67346 (-0.85%)
total temps in shared programs: 20836 -> 20773 (-0.30%)
temps in affected programs: 711 -> 648 (-8.86%)
total presub in shared programs: 8226 -> 8202 (-0.29%)
presub in affected programs: 223 -> 199 (-10.76%)
total temps in shared programs: 20836 -> 20773 (-0.30%)
temps in affected programs: 711 -> 648 (-8.86%)

Signed-off-by: Pavel Ondračka <pavel.ondracka@gmail.com>
Reviewed-by: Filip Gawin <filip@gawin.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17560>
This commit is contained in:
Pavel Ondračka
2022-06-17 21:09:32 +02:00
parent 2755faf938
commit 05785d482e
@@ -917,7 +917,7 @@ static unsigned int merge_negates(struct rc_src_register src1, struct rc_src_reg
return clean_negate(src1) | clean_negate(src2);
}
static int merge_movs(struct radeon_compiler * c, struct rc_instruction * inst)
static void merge_movs(struct radeon_compiler * c, struct rc_instruction * inst)
{
unsigned int orig_dst_reg = inst->U.I.DstReg.Index;
unsigned int orig_dst_file = inst->U.I.DstReg.File;
@@ -933,13 +933,13 @@ static int merge_movs(struct radeon_compiler * c, struct rc_instruction * inst)
* control flow.
*/
if (opcode->IsFlowControl)
return 0;
return;
/* Stop when the original destination is overwritten */
if (orig_dst_reg == cur->U.I.DstReg.Index &&
orig_dst_file == cur->U.I.DstReg.File &&
(orig_dst_wmask & cur->U.I.DstReg.WriteMask) != 0)
return 0;
return;
/* Stop the search when the original instruction destination
* is used as a source for anything.
@@ -947,7 +947,7 @@ static int merge_movs(struct radeon_compiler * c, struct rc_instruction * inst)
for (unsigned i = 0; i < opcode->NumSrcRegs; i++) {
if (cur->U.I.SrcReg[i].File == orig_dst_file &&
cur->U.I.SrcReg[i].Index == orig_dst_reg)
return 0;
return;
}
if (cur->U.I.Opcode == RC_OPCODE_MOV &&
@@ -971,18 +971,17 @@ static int merge_movs(struct radeon_compiler * c, struct rc_instruction * inst)
inst->U.I.SrcReg[0].Swizzle);
src.Negate = merge_negates(inst->U.I.SrcReg[0], cur->U.I.SrcReg[0]);
if (!c->SwizzleCaps->IsNative(RC_OPCODE_MOV, src))
return 0;
return;
cur->U.I.DstReg.WriteMask |= orig_dst_wmask;
cur->U.I.SrcReg[0] = src;
/* finally delete the original mov */
rc_remove_instruction(inst);
return 1;
return;
}
}
}
return 0;
}
void rc_optimize(struct radeon_compiler * c, void *user)
@@ -991,22 +990,40 @@ void rc_optimize(struct radeon_compiler * c, void *user)
while(inst != &c->Program.Instructions) {
struct rc_instruction * cur = inst;
inst = inst->Next;
constant_folding(c, cur);
}
if(peephole(c, cur))
continue;
/* Copy propagate simple movs away. */
inst = c->Program.Instructions.Next;
while(inst != &c->Program.Instructions) {
struct rc_instruction * cur = inst;
inst = inst->Next;
if (cur->U.I.Opcode == RC_OPCODE_MOV) {
if (c->is_r500) {
if (merge_movs(c, cur))
continue;
}
copy_propagate(c, cur);
/* cur may no longer be part of the program */
}
}
/* Merge MOVs to same source in different channels using the constant
* swizzles.
*/
if (c->is_r500) {
inst = c->Program.Instructions.Next;
while(inst != &c->Program.Instructions) {
struct rc_instruction * cur = inst;
inst = inst->Next;
if (cur->U.I.Opcode == RC_OPCODE_MOV)
merge_movs(c, cur);
}
}
/* Presubtract operations. */
inst = c->Program.Instructions.Next;
while(inst != &c->Program.Instructions) {
struct rc_instruction * cur = inst;
inst = inst->Next;
peephole(c, cur);
}
if (!c->has_omod) {
return;
}