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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user