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

Ilia Mirkin imirkin at alum.mit.edu
Mon Jan 25 18:09:42 PST 2016


On Mon, Jan 25, 2016 at 9:57 AM, Karol Herbst <nouveau at karolherbst.de> wrote:
> 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)

Please use NV50_IR_SUBOP_MOV_FINAL instead of 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);

Please make this "1" -- that way it will be disabled in case someone
passes NV50_PROG_OPTIMIZE=0.

  -ilia


More information about the mesa-dev mailing list