[Mesa-dev] [PATCH 2/2] nv50/ir: generalize sched block sizes and remove duplicated logic

Ilia Mirkin imirkin at alum.mit.edu
Wed Nov 2 04:38:03 UTC 2016


The GM107 had a bunch of prepareEmission needlessly duplicated because
the sched block size is different. Move that knowledge into the target,
and generalize the existing code.

Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---
 .../drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp |  4 +--
 .../drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 42 +---------------------
 .../drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp  |  4 +--
 .../drivers/nouveau/codegen/nv50_ir_target.cpp     | 16 +++++----
 .../drivers/nouveau/codegen/nv50_ir_target.h       |  4 +--
 .../nouveau/codegen/nv50_ir_target_nvc0.cpp        |  2 +-
 6 files changed, 18 insertions(+), 54 deletions(-)

diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
index 123ec5c..d6005f4 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
@@ -2653,14 +2653,14 @@ CodeEmitterGK110::prepareEmission(Function *func)
 
    CodeEmitter::prepareEmission(func);
 
-   if (targ->hasSWSched)
+   if (targ->schedInterval)
       calculateSchedDataNVC0(targ, func);
 }
 
 CodeEmitterGK110::CodeEmitterGK110(const TargetNVC0 *target)
    : CodeEmitter(target),
      targNVC0(target),
-     writeIssueDelays(target->hasSWSched)
+     writeIssueDelays(target->schedInterval)
 {
    code = NULL;
    codeSize = codeSizeLimit = 0;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
index ecd3faa..af00d16 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
@@ -34,7 +34,6 @@ public:
    virtual bool emitInstruction(Instruction *);
    virtual uint32_t getMinEncodingSize(const Instruction *) const;
 
-   virtual void prepareEmission(Program *);
    virtual void prepareEmission(Function *);
 
    inline void setProgramType(Program::Type pType) { progType = pType; }
@@ -3391,49 +3390,10 @@ CodeEmitterGM107::prepareEmission(Function *func)
    sched.run(func, true, true);
 }
 
-static inline uint32_t sizeToBundlesGM107(uint32_t size)
-{
-   return (size + 23) / 24;
-}
-
-void
-CodeEmitterGM107::prepareEmission(Program *prog)
-{
-   for (ArrayList::Iterator fi = prog->allFuncs.iterator();
-        !fi.end(); fi.next()) {
-      Function *func = reinterpret_cast<Function *>(fi.get());
-      func->binPos = prog->binSize;
-      prepareEmission(func);
-
-      // adjust sizes & positions for schedulding info:
-      if (prog->getTarget()->hasSWSched) {
-         uint32_t adjPos = func->binPos;
-         BasicBlock *bb = NULL;
-         for (int i = 0; i < func->bbCount; ++i) {
-            bb = func->bbArray[i];
-            int32_t adjSize = bb->binSize;
-            if (adjPos % 32) {
-               adjSize -= 32 - adjPos % 32;
-               if (adjSize < 0)
-                  adjSize = 0;
-            }
-            adjSize = bb->binSize + sizeToBundlesGM107(adjSize) * 8;
-            bb->binPos = adjPos;
-            bb->binSize = adjSize;
-            adjPos += adjSize;
-         }
-         if (bb)
-            func->binSize = adjPos - func->binPos;
-      }
-
-      prog->binSize += func->binSize;
-   }
-}
-
 CodeEmitterGM107::CodeEmitterGM107(const TargetGM107 *target)
    : CodeEmitter(target),
      targGM107(target),
-     writeIssueDelays(target->hasSWSched)
+     writeIssueDelays(target->schedInterval)
 {
    code = NULL;
    codeSize = codeSizeLimit = 0;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
index ef06939..6dc1cb2 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
@@ -3399,14 +3399,14 @@ CodeEmitterNVC0::prepareEmission(Function *func)
 {
    CodeEmitter::prepareEmission(func);
 
-   if (targ->hasSWSched)
+   if (targ->schedInterval)
       calculateSchedDataNVC0(targ, func);
 }
 
 CodeEmitterNVC0::CodeEmitterNVC0(const TargetNVC0 *target)
    : CodeEmitter(target),
      targNVC0(target),
-     writeIssueDelays(target->hasSWSched)
+     writeIssueDelays(target->schedInterval)
 {
    code = NULL;
    codeSize = codeSizeLimit = 0;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp
index 273ec34..427f095 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp
@@ -199,14 +199,17 @@ CodeEmitter::printBinary() const
    INFO("\n");
 }
 
-static inline uint32_t sizeToBundlesNVE4(uint32_t size)
+static inline uint32_t sizeToBundles(uint32_t size, uint32_t ops)
 {
-   return (size + 55) / 56;
+   uint32_t bytes = (ops - 1) * 8;
+   return (size + bytes - 1) / bytes;
 }
 
 void
 CodeEmitter::prepareEmission(Program *prog)
 {
+   const Target *target = prog->getTarget();
+   const uint32_t bytes = target->schedInterval * 8;
    for (ArrayList::Iterator fi = prog->allFuncs.iterator();
         !fi.end(); fi.next()) {
       Function *func = reinterpret_cast<Function *>(fi.get());
@@ -214,18 +217,19 @@ CodeEmitter::prepareEmission(Program *prog)
       prepareEmission(func);
 
       // adjust sizes & positions for schedulding info:
-      if (prog->getTarget()->hasSWSched) {
+      if (target->schedInterval) {
          uint32_t adjPos = func->binPos;
          BasicBlock *bb = NULL;
          for (int i = 0; i < func->bbCount; ++i) {
             bb = func->bbArray[i];
             int32_t adjSize = bb->binSize;
-            if (adjPos % 64) {
-               adjSize -= 64 - adjPos % 64;
+            if (adjPos % bytes) {
+               adjSize -= bytes - adjPos % bytes;
                if (adjSize < 0)
                   adjSize = 0;
             }
-            adjSize = bb->binSize + sizeToBundlesNVE4(adjSize) * 8;
+            adjSize = bb->binSize +
+               sizeToBundles(adjSize, target->schedInterval) * 8;
             bb->binPos = adjPos;
             bb->binSize = adjSize;
             adjPos += adjSize;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
index eaf50cc..113ea5c 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.h
@@ -157,7 +157,7 @@ enum OpClass
 class Target
 {
 public:
-   Target(bool m, bool j, bool s) : hasJoin(m), joinAnterior(j), hasSWSched(s) { }
+   Target(bool m, bool j, int s) : hasJoin(m), joinAnterior(j), schedInterval(s) { }
    virtual ~Target() { }
 
    static Target *create(uint32_t chipset);
@@ -237,7 +237,7 @@ public:
 public:
    const bool hasJoin;      // true if instructions have a join modifier
    const bool joinAnterior; // true if join is executed before the op
-   const bool hasSWSched;   // true if code should provide scheduling data
+   const int  schedInterval; // how often code should provide scheduling data
 
    static const uint8_t operationSrcNr[];
    static const OpClass operationClass[];
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
index 2d1f1b45..5404349 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target_nvc0.cpp
@@ -30,7 +30,7 @@ Target *getTargetNVC0(unsigned int chipset)
 }
 
 TargetNVC0::TargetNVC0(unsigned int card) :
-   Target(card < 0x110, false, card >= 0xe4)
+   Target(card < 0x110, false, card >= 0x110 ? 4 : card >= 0xe4 ? 8 : 0)
 {
    chipset = card;
    initOpInfo();
-- 
2.7.3



More information about the mesa-dev mailing list