this paths reorders instructions in a way, so that the hardware is able to dual issue more instructions leading to higher performance.
with all previos commits put together changes for ./GpuTest /test=pixmark_piano /benchmark /no_scorebox /msaa=0 /benchmark_duration_ms=60000 /width=1024 /height=640: inst_executed: 1.03G inst_issued1: 614M -> 500M inst_issued2: 213M -> 271M score: 1021 -> 1056 Signed-off-by: Karol Herbst <karolher...@gmail.com> --- .../drivers/nouveau/codegen/nv50_ir_peephole.cpp | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp index a9172f8..88354c9 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp @@ -3385,6 +3385,62 @@ DeadCodeElim::checkSplitLoad(Instruction *ld1) // ============================================================================= +// Tries to improve dual issueing trivially +// +// the PASS checks for every instruction A,B with A->next == B and +// !canDualIssue(A,B), if there is a Instruction C in the same BB which can be +// moved between A and B and canDualIssue(A,C) is true +class PostRADualIssue : public Pass +{ +private: + virtual bool visit(BasicBlock *); +}; + +static bool +isChainedCommutationLegal(Instruction *a, Instruction *b) +{ + Instruction *check = a; + do { + if (!check->isCommutationLegal(b) || (check->op == OP_TEX && check->op == OP_TEX)) + return false; + check = check->next; + } while (check != b); + return true; +} + +bool +PostRADualIssue::visit(BasicBlock *bb) +{ + const Target *target = prog->getTarget(); + Instruction *i, *next, *check; + + for (i = bb->getEntry(); i; i = next) { + next = i->next; + + // check next + if (!next || next->fixed || next->join || next->asFlow() || target->canDualIssue(i, next)) + continue; + + check = next->next; + // we can't move fixed, flow instructions and instruction marked as join + while (check && !check->fixed && !check->join && !check->asFlow() && check->prev->bb == check->bb && isChainedCommutationLegal(next, check)) { + if (target->canDualIssue(i, check)) { + // move the instruction after i step by step + while (check->prev != i) + bb->permuteAdjacent(check->prev, check); + + // we have to always continue with the currently next instruction + next = i->next; + break; + } + check = check->next; + } + } + return true; +} + +// ============================================================================= + #define RUN_PASS(l, n, f) \ if (level >= (l)) { \ if (dbgFlags & NV50_IR_DEBUG_VERBOSE) \ @@ -3420,6 +3476,9 @@ Program::optimizePostRA(int level) RUN_PASS(2, FlatteningPass, run); if (getTarget()->getChipset() < 0xc0) RUN_PASS(2, NV50PostRaConstantFolding, run); + // should be last + if (getTarget()->hasDualIssueing()) + RUN_PASS(2, PostRADualIssue, run); return true; } -- 2.9.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev