[Beignet] [PATCH 3/5] add sends for atomic operation, only for ocl 1.2

Guo, Yejun yejun.guo at intel.com
Fri Dec 9 10:07:34 UTC 2016


Signed-off-by: Guo, Yejun <yejun.guo at intel.com>
---
 backend/src/backend/gen75_encoder.cpp      |  2 +-
 backend/src/backend/gen75_encoder.hpp      |  2 +-
 backend/src/backend/gen8_encoder.cpp       |  2 +-
 backend/src/backend/gen8_encoder.hpp       |  2 +-
 backend/src/backend/gen9_encoder.cpp       | 28 ++++++++++++++++++++++++++++
 backend/src/backend/gen9_encoder.hpp       |  1 +
 backend/src/backend/gen_context.cpp        | 20 ++++++++++++++------
 backend/src/backend/gen_encoder.cpp        |  4 ++--
 backend/src/backend/gen_encoder.hpp        |  2 +-
 backend/src/backend/gen_insn_selection.cpp | 25 ++++++++++++++++++++-----
 10 files changed, 70 insertions(+), 18 deletions(-)

diff --git a/backend/src/backend/gen75_encoder.cpp b/backend/src/backend/gen75_encoder.cpp
index 9cafaa7..725c774 100644
--- a/backend/src/backend/gen75_encoder.cpp
+++ b/backend/src/backend/gen75_encoder.cpp
@@ -126,7 +126,7 @@ namespace gbe
     return gen7_insn->bits3.ud;
   }
 
-  void Gen75Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum) {
+  void Gen75Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum, bool useSends) {
     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
 
     this->setHeader(insn);
diff --git a/backend/src/backend/gen75_encoder.hpp b/backend/src/backend/gen75_encoder.hpp
index 517afff..2a226cc 100644
--- a/backend/src/backend/gen75_encoder.hpp
+++ b/backend/src/backend/gen75_encoder.hpp
@@ -42,7 +42,7 @@ namespace gbe
     virtual void JMPI(GenRegister src, bool longjmp = false);
     /*! Patch JMPI/BRC/BRD (located at index insnID) with the given jump distance */
     virtual void patchJMPI(uint32_t insnID, int32_t jip, int32_t uip);
-    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum);
+    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum, bool useSends);
     virtual void UNTYPED_READ(GenRegister dst, GenRegister src, GenRegister bti, uint32_t elemNum);
     virtual void UNTYPED_WRITE(GenRegister src, GenRegister data, GenRegister bti, uint32_t elemNum);
     virtual void setHeader(GenNativeInstruction *insn);
diff --git a/backend/src/backend/gen8_encoder.cpp b/backend/src/backend/gen8_encoder.cpp
index 2928943..277acda 100644
--- a/backend/src/backend/gen8_encoder.cpp
+++ b/backend/src/backend/gen8_encoder.cpp
@@ -153,7 +153,7 @@ namespace gbe
     return gen8_insn->bits3.ud;
   }
 
-  void Gen8Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum) {
+  void Gen8Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister data, GenRegister bti, uint32_t srcNum, bool useSends) {
     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
 
     this->setHeader(insn);
diff --git a/backend/src/backend/gen8_encoder.hpp b/backend/src/backend/gen8_encoder.hpp
index 4afec0c..fa62a8d 100644
--- a/backend/src/backend/gen8_encoder.hpp
+++ b/backend/src/backend/gen8_encoder.hpp
@@ -44,7 +44,7 @@ namespace gbe
     virtual void F16TO32(GenRegister dest, GenRegister src0);
     virtual void F32TO16(GenRegister dest, GenRegister src0);
     virtual void LOAD_INT64_IMM(GenRegister dest, GenRegister value);
-    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum);
+    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister addr, GenRegister data, GenRegister bti, uint32_t srcNum, bool useSends);
     virtual void ATOMICA64(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum);
     virtual void UNTYPED_READ(GenRegister dst, GenRegister src, GenRegister bti, uint32_t elemNum);
     virtual void UNTYPED_WRITE(GenRegister src, GenRegister data, GenRegister bti, uint32_t elemNum, bool useSends);
diff --git a/backend/src/backend/gen9_encoder.cpp b/backend/src/backend/gen9_encoder.cpp
index 37ffb0d..b42c833 100644
--- a/backend/src/backend/gen9_encoder.cpp
+++ b/backend/src/backend/gen9_encoder.cpp
@@ -194,4 +194,32 @@ namespace gbe
         gen9_insn->bits2.sends.sel_reg32_desc = 1;
     }
   }
+
+  void Gen9Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister addr, GenRegister data, GenRegister bti, uint32_t srcNum, bool useSends)
+  {
+    if (!useSends)
+      Gen8Encoder::ATOMIC(dst, function, addr, data, bti, srcNum, false);
+    else {
+      assert(addr.reg() != data.reg());
+
+      GenNativeInstruction *insn = this->next(GEN_OPCODE_SENDS);
+      Gen9NativeInstruction *gen9_insn = &insn->gen9_insn;
+      this->setHeader(insn);
+      insn->header.destreg_or_condmod = GEN_SFID_DATAPORT1_DATA;
+
+      setSendsOperands(gen9_insn, dst, addr, data);
+      if (this->curr.execWidth == 8)
+        gen9_insn->bits2.sends.src1_length = srcNum - 1;
+      else if (this->curr.execWidth == 16)
+        gen9_insn->bits2.sends.src1_length = 2 * (srcNum - 1);
+      else
+        assert(!"unsupported");
+
+      if (bti.file == GEN_IMMEDIATE_VALUE) {
+        gen9_insn->bits2.sends.sel_reg32_desc = 0;
+        setAtomicMessageDesc(insn, function, bti.value.ud, 1);
+      } else
+        gen9_insn->bits2.sends.sel_reg32_desc = 1;
+    }
+  }
 } /* End of the name space. */
diff --git a/backend/src/backend/gen9_encoder.hpp b/backend/src/backend/gen9_encoder.hpp
index 4eb36e4..9b3af13 100644
--- a/backend/src/backend/gen9_encoder.hpp
+++ b/backend/src/backend/gen9_encoder.hpp
@@ -52,6 +52,7 @@ namespace gbe
     virtual unsigned setUntypedWriteSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemNum);
     virtual void BYTE_SCATTER(GenRegister addr, GenRegister data, GenRegister bti, uint32_t elemSize, bool useSends);
     virtual unsigned setByteScatterSendsMessageDesc(GenNativeInstruction *insn, unsigned bti, unsigned elemSize);
+    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister addr, GenRegister data, GenRegister bti, uint32_t srcNum, bool useSends);
   };
 }
 #endif /* __GBE_GEN9_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 4341677..d161ebf 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -1893,26 +1893,34 @@ namespace gbe
   }
 
   void GenContext::emitAtomicInstruction(const SelectionInstruction &insn) {
-    const GenRegister src = ra->genReg(insn.src(0));
+    const GenRegister addr = ra->genReg(insn.src(0));
     const GenRegister dst = ra->genReg(insn.dst(0));
     const uint32_t function = insn.extra.function;
     unsigned srcNum = insn.extra.elem;
 
+    GenRegister data = addr;
+    if (srcNum > 1)
+      data = ra->genReg(insn.src(1));
+
     const GenRegister bti = ra->genReg(insn.src(srcNum));
 
     if (bti.file == GEN_IMMEDIATE_VALUE) {
-      p->ATOMIC(dst, function, src, bti, srcNum);
+      p->ATOMIC(dst, function, addr, data, bti, srcNum, insn.extra.splitSend);
     } else {
       GenRegister flagTemp = ra->genReg(insn.dst(1));
       GenRegister btiTmp = ra->genReg(insn.dst(2));
 
-      unsigned desc = p->generateAtomicMessageDesc(function, 0, srcNum);
+      unsigned desc = 0;
+      if (insn.extra.splitSend)
+        desc = p->generateAtomicMessageDesc(function, 0, 1);
+      else
+        desc = p->generateAtomicMessageDesc(function, 0, srcNum);
 
       unsigned jip0 = beforeMessage(insn, bti, flagTemp, btiTmp, desc);
       p->push();
         p->curr.predicate = GEN_PREDICATE_NORMAL;
         p->curr.useFlag(insn.state.flag, insn.state.subFlag);
-        p->ATOMIC(dst, function, src, GenRegister::addr1(0), srcNum);
+        p->ATOMIC(dst, function, addr, data, GenRegister::addr1(0), srcNum, insn.extra.splitSend);
       p->pop();
       afterMessage(insn, bti, flagTemp, btiTmp, jip0);
     }
@@ -2833,7 +2841,7 @@ namespace gbe
       p->pop();
       p->curr.useFlag(insn.state.flag, insn.state.subFlag);
       p->curr.predicate = GEN_PREDICATE_NORMAL;
-      p->ATOMIC(incRes, GEN_ATOMIC_OP_INC, sndMsg, GenRegister::immud(bti), 1);
+      p->ATOMIC(incRes, GEN_ATOMIC_OP_INC, sndMsg, sndMsg, GenRegister::immud(bti), 1, false);
     } p->pop();
 
     // Calculate the final addr
@@ -3496,7 +3504,7 @@ namespace gbe
         p->MOV(data, GenRegister::immud(insn.extra.printfSize + 12));
       } p->pop();
 
-      p->ATOMIC(addr, GEN_ATOMIC_OP_ADD, addr, GenRegister::immud(insn.extra.printfBTI), 2);
+      p->ATOMIC(addr, GEN_ATOMIC_OP_ADD, addr, addr, GenRegister::immud(insn.extra.printfBTI), 2, false);
       /* Write out the header. */
       p->MOV(data, GenRegister::immud(0xAABBCCDD));
       p->UNTYPED_WRITE(addr, addr, GenRegister::immud(insn.extra.printfBTI), 1, false);
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index 9d23df3..a9bdd3a 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -633,14 +633,14 @@ namespace gbe
     return 0;
   }
 
-  void GenEncoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum) {
+  void GenEncoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister addr, GenRegister data, GenRegister bti, uint32_t srcNum, bool useSends) {
     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
 
     this->setHeader(insn);
     insn->header.destreg_or_condmod = GEN_SFID_DATAPORT_DATA;
 
     this->setDst(insn, GenRegister::uw16grf(dst.nr, 0));
-    this->setSrc0(insn, GenRegister::ud8grf(src.nr, 0));
+    this->setSrc0(insn, GenRegister::ud8grf(addr.nr, 0));
     if (bti.file == GEN_IMMEDIATE_VALUE) {
       this->setSrc1(insn, GenRegister::immud(0));
       setAtomicMessageDesc(insn, function, bti.value.ud, srcNum);
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index 31b6e92..b86e9e4 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -171,7 +171,7 @@ namespace gbe
     /*! Wait instruction (used for the barrier) */
     void WAIT(uint32_t n = 0);
     /*! Atomic instructions */
-    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum);
+    virtual void ATOMIC(GenRegister dst, uint32_t function, GenRegister addr, GenRegister data, GenRegister bti, uint32_t srcNum, bool useSends);
     /*! AtomicA64 instructions */
     virtual void ATOMICA64(GenRegister dst, uint32_t function, GenRegister src, GenRegister bti, uint32_t srcNum);
     /*! Untyped read (upto 4 channels) */
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index f46207f..1ebbbe6 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -1376,11 +1376,26 @@ namespace gbe
     insn->extra.function = function;
     insn->extra.elem = msgPayload;
 
-    SelectionVector *vector = this->appendVector();
-    vector->regNum = msgPayload; //bti not included in SelectionVector
-    vector->offsetID = 0;
-    vector->reg = &insn->src(0);
-    vector->isSrc = 1;
+    if (hasSends() && msgPayload > 1) {
+      insn->extra.splitSend = 1;
+      SelectionVector *vector = this->appendVector();
+      vector->regNum = 1;
+      vector->offsetID = 0;
+      vector->reg = &insn->src(0);
+      vector->isSrc = 1;
+
+      vector = this->appendVector();
+      vector->regNum = msgPayload - 1;
+      vector->offsetID = 1;
+      vector->reg = &insn->src(1);
+      vector->isSrc = 1;
+    } else {
+      SelectionVector *vector = this->appendVector();
+      vector->regNum = msgPayload; //bti not included in SelectionVector
+      vector->offsetID = 0;
+      vector->reg = &insn->src(0);
+      vector->isSrc = 1;
+    }
   }
 
   void Selection::Opaque::ATOMICA64(Reg dst, uint32_t function,
-- 
1.9.1



More information about the Beignet mailing list