helps shaders in Saints Row IV, bioshock infinite and shadow warrior no change in default shader-db
changes in my shader-db total instructions in shared programs : 1801054 -> 1794281 (-0.38%) total gprs used in shared programs : 233059 -> 233059 (0.00%) total local used in shared programs : 5569 -> 5569 (0.00%) total bytes used in shared programs : 16513528 -> 16451848 (-0.37%) v2: remove the DCE stuff from NV50PostRaConstantFolding alltogether only run this Pass with NV50_PROG_OPTIMIZE >= 1 Signed-off-by: Karol Herbst <nouv...@karolherbst.de> --- src/gallium/drivers/nouveau/codegen/nv50_ir.h | 2 +- .../drivers/nouveau/codegen/nv50_ir_peephole.cpp | 74 ++++++++++++++-------- 2 files changed, 49 insertions(+), 27 deletions(-) diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h index 9d7becf..63eae54 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.h @@ -758,7 +758,7 @@ public: } inline bool isPseudo() const { return op < OP_MOV; } - bool isDead() const; + bool isDead(bool postRa = false) const; bool isNop() const; bool isCommutationLegal(const Instruction *) const; // must be adjacent ! bool isActionEqual(const Instruction *) const; diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp index 6192c06..5c3ee37 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp @@ -61,7 +61,7 @@ Instruction::isNop() const return false; } -bool Instruction::isDead() const +bool Instruction::isDead(bool postRa) const { if (op == OP_STORE || op == OP_EXPORT || @@ -70,8 +70,11 @@ bool Instruction::isDead() const op == OP_WRSV) return false; + if (postRa && op == OP_MOV && subOp == NV50_IR_SUBOP_MOV_FINAL) + return false; + for (int d = 0; defExists(d); ++d) - if (getDef(d)->refCount() || getDef(d)->reg.data.id >= 0) + if (getDef(d)->refCount() || (!postRa && getDef(d)->reg.data.id >= 0)) return false; if (terminator || asFlow()) @@ -2913,19 +2916,9 @@ private: virtual bool visit(BasicBlock *); }; -static bool -post_ra_dead(Instruction *i) -{ - for (int d = 0; i->defExists(d); ++d) - if (i->getDef(d)->refCount()) - return false; - return true; -} - bool NV50PostRaConstantFolding::visit(BasicBlock *bb) { - Value *vtmp; Instruction *def; for (Instruction *i = bb->getFirst(); i; i = i->next) { @@ -2952,7 +2945,6 @@ NV50PostRaConstantFolding::visit(BasicBlock *bb) if (def && def->op == OP_SPLIT && typeSizeof(def->sType) == 4) def = def->getSrc(0)->getInsn(); if (def && def->op == OP_MOV && def->src(0).getFile() == FILE_IMMEDIATE) { - vtmp = i->getSrc(1); if (isFloatType(i->sType)) { i->setSrc(1, def->getSrc(0)); } else { @@ -2965,19 +2957,6 @@ NV50PostRaConstantFolding::visit(BasicBlock *bb) i->setSrc(1, new_ImmediateValue(bb->getProgram(), val.reg.data.u32)); } - /* There's no post-RA dead code elimination, so do it here - * XXX: if we add more code-removing post-RA passes, we might - * want to create a post-RA dead-code elim pass */ - if (post_ra_dead(vtmp->getInsn())) { - Value *src = vtmp->getInsn()->getSrc(0); - // Careful -- splits will have already been removed from the - // functions. Don't double-delete. - if (vtmp->getInsn()->bb) - delete_Instruction(prog, vtmp->getInsn()); - if (src->getInsn() && post_ra_dead(src->getInsn())) - delete_Instruction(prog, src->getInsn()); - } - break; } break; @@ -3364,6 +3343,48 @@ DeadCodeElim::checkSplitLoad(Instruction *ld1) // ============================================================================= +// POST-RA Dead-code-elimination + +// Remove computations of unused values. +class PostRADeadCodeElim : public Pass +{ +public: + bool buryAll(Program *); + +private: + virtual bool visit(BasicBlock *); + unsigned int deadCount; +}; + +bool +PostRADeadCodeElim::buryAll(Program *prog) +{ + do { + deadCount = 0; + if (!this->run(prog, false, false)) + return false; + } while (deadCount); + + return true; +} + +bool +PostRADeadCodeElim::visit(BasicBlock *bb) +{ + Instruction *prev; + + for (Instruction *i = bb->getExit(); i; i = prev) { + prev = i->prev; + if (i->isDead(true)) { + ++deadCount; + delete_Instruction(prog, i); + } + } + return true; +} + +// ============================================================================= + #define RUN_PASS(l, n, f) \ if (level >= (l)) { \ if (dbgFlags & NV50_IR_DEBUG_VERBOSE) \ @@ -3399,6 +3420,7 @@ Program::optimizePostRA(int level) RUN_PASS(2, FlatteningPass, run); if (getTarget()->getChipset() < 0xc0) RUN_PASS(2, NV50PostRaConstantFolding, run); + RUN_PASS(1, PostRADeadCodeElim, buryAll); return true; } -- 2.7.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev