[Mesa-dev] [PATCH 5/6] nv50/ir: add PostRADCE Pass

Karol Herbst nouveau at karolherbst.de
Mon Jan 25 06:57:52 PST 2016


From: Karol Herbst <git at karolherbst.de>

helps shaders in some games

total instructions in shared programs : 1901958 -> 1895185 (-0.36%)
total gprs used in shared programs    : 251739 -> 251739 (0.00%)
total local used in shared programs   : 5673 -> 5673 (0.00%)
total bytes used in shared programs   : 17440184 -> 17379448 (-0.35%)

                local        gpr       inst      bytes
    helped           0           0        1137        1137
      hurt           0           0           0           0

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   | 63 +++++++++++++++++-----
 2 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h
index d1fdd75..c709b12 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.h
@@ -757,7 +757,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 142d9a7..09a1c64 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 == 1)
+      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())
@@ -2879,15 +2882,6 @@ 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)
 {
@@ -2953,13 +2947,13 @@ NV50PostRaConstantFolding::visit(BasicBlock *bb)
          /* 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())) {
+         if (vtmp->getInsn()->isDead(true)) {
             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()))
+            if (src->getInsn() && src->getInsn()->isDead(true))
                delete_Instruction(prog, src->getInsn());
          }
 
@@ -3345,6 +3339,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)     \
@@ -3380,6 +3416,7 @@ Program::optimizePostRA(int level)
    RUN_PASS(2, FlatteningPass, run);
    if (getTarget()->getChipset() < 0xf0)
       RUN_PASS(2, NV50PostRaConstantFolding, run);
+   RUN_PASS(0, PostRADeadCodeElim, buryAll);
 
    return true;
 }
-- 
2.7.0



More information about the mesa-dev mailing list