[Mesa-dev] [PATCH 1/2] nv50/ir: add PostRADCE Pass

Karol Herbst nouveau at karolherbst.de
Wed Feb 17 21:21:42 UTC 2016


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 <nouveau at 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



More information about the mesa-dev mailing list