nv50/ir: restructure and rename postraconstantfolding pass
authorKarol Herbst <karolherbst@gmail.com>
Sun, 26 Mar 2017 19:45:57 +0000 (21:45 +0200)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sat, 1 Apr 2017 03:57:12 +0000 (23:57 -0400)
we might want to add more folding passes here, so make it a bit more generic

v2: leave the comment and reword commit message
v4: rename it to PostRaLoadPropagation

Signed-off-by: Karol Herbst <karolherbst@gmail.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp

index 2714b5ff7e00eaf1082eef899ad0a5621032b80c..6dc4e21e11ca048f371ef51ce4228932cbff3977 100644 (file)
@@ -3190,10 +3190,12 @@ FlatteningPass::tryPredicateConditional(BasicBlock *bb)
 // constraint SDST == SSRC2
 // TODO:
 // Does NVC0+ have other situations where this pass makes sense?
-class NV50PostRaConstantFolding : public Pass
+class PostRaLoadPropagation : public Pass
 {
 private:
-   virtual bool visit(BasicBlock *);
+   virtual bool visit(Instruction *);
+
+   void handleMAD(Instruction *);
 };
 
 static bool
@@ -3205,69 +3207,72 @@ post_ra_dead(Instruction *i)
    return true;
 }
 
-bool
-NV50PostRaConstantFolding::visit(BasicBlock *bb)
+// Fold Immediate into MAD; must be done after register allocation due to
+// constraint SDST == SSRC2
+void
+PostRaLoadPropagation::handleMAD(Instruction *i)
 {
-   Value *vtmp;
-   Instruction *def;
-
-   for (Instruction *i = bb->getFirst(); i; i = i->next) {
-      switch (i->op) {
-      case OP_MAD:
-         if (i->def(0).getFile() != FILE_GPR ||
-             i->src(0).getFile() != FILE_GPR ||
-             i->src(1).getFile() != FILE_GPR ||
-             i->src(2).getFile() != FILE_GPR ||
-             i->getDef(0)->reg.data.id != i->getSrc(2)->reg.data.id)
-            break;
-
-         if (i->getDef(0)->reg.data.id >= 64 ||
-             i->getSrc(0)->reg.data.id >= 64)
-            break;
+   if (i->def(0).getFile() != FILE_GPR ||
+       i->src(0).getFile() != FILE_GPR ||
+       i->src(1).getFile() != FILE_GPR ||
+       i->src(2).getFile() != FILE_GPR ||
+       i->getDef(0)->reg.data.id != i->getSrc(2)->reg.data.id)
+      return;
 
-         if (i->flagsSrc >= 0 && i->getSrc(i->flagsSrc)->reg.data.id != 0)
-            break;
+   if (i->getDef(0)->reg.data.id >= 64 ||
+       i->getSrc(0)->reg.data.id >= 64)
+      return;
 
-         if (i->getPredicate())
-            break;
+   if (i->flagsSrc >= 0 && i->getSrc(i->flagsSrc)->reg.data.id != 0)
+      return;
 
-         def = i->getSrc(1)->getInsn();
-         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 {
-               ImmediateValue val;
-               bool ret = def->src(0).getImmediate(val);
-               assert(ret);
-               if (i->getSrc(1)->reg.data.id & 1)
-                  val.reg.data.u32 >>= 16;
-               val.reg.data.u32 &= 0xffff;
-               i->setSrc(1, new_ImmediateValue(bb->getProgram(), val.reg.data.u32));
-            }
+   if (i->getPredicate())
+      return;
 
-            /* 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());
-            }
+   Value *vtmp;
+   Instruction *def = i->getSrc(1)->getInsn();
+
+   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 {
+         ImmediateValue val;
+         bool ret = def->src(0).getImmediate(val);
+         assert(ret);
+         if (i->getSrc(1)->reg.data.id & 1)
+            val.reg.data.u32 >>= 16;
+         val.reg.data.u32 &= 0xffff;
+         i->setSrc(1, new_ImmediateValue(prog, val.reg.data.u32));
+      }
 
-            break;
-         }
-         break;
-      default:
-         break;
+      /* 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());
       }
    }
+}
+
+bool
+PostRaLoadPropagation::visit(Instruction *i)
+{
+   switch (i->op) {
+   case OP_MAD:
+      handleMAD(i);
+      break;
+   default:
+      break;
+   }
 
    return true;
 }
@@ -3694,7 +3699,7 @@ Program::optimizePostRA(int level)
 {
    RUN_PASS(2, FlatteningPass, run);
    if (getTarget()->getChipset() < 0xc0)
-      RUN_PASS(2, NV50PostRaConstantFolding, run);
+      RUN_PASS(2, PostRaLoadPropagation, run);
 
    return true;
 }