[Beignet] [PATCH V2 09/17] Backend: Fix workgroup barrier call in gen context

Grigore Lupescu grigore.lupescu at intel.com
Mon Apr 11 14:38:21 UTC 2016


From: Grigore Lupescu <grigore.lupescu at intel.com>

Signed-off-by: Grigore Lupescu <grigore.lupescu at intel.com>
---
 backend/src/backend/gen_context.cpp        |  5 ++--
 backend/src/backend/gen_insn_selection.cpp | 42 +++++++++++++++++-------------
 2 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 6219b6c..3b51ea9 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -2639,6 +2639,7 @@ namespace gbe
     GenRegister threadId = ra->genReg(insn.src(0));
     GenRegister threadLoop = ra->genReg(insn.src(1));
     GenRegister barrierId = ra->genReg(GenRegister::ud1grf(ir::ocl::barrierid));
+    GenRegister localBarrier = ra->genReg(insn.src(5));
 
     uint32_t wg_op = insn.extra.workgroupOp;
     uint32_t simd = p->curr.execWidth;
@@ -2720,8 +2721,8 @@ namespace gbe
       p->curr.execWidth = 8;
       p->curr.physicalFlag = 0;
       p->curr.noMask = 1;
-      p->AND(msgData, barrierId, GenRegister::immud(0x0f000000));
-      p->BARRIER(msgData);
+      p->AND(localBarrier, barrierId, GenRegister::immud(0x0f000000));
+      p->BARRIER(localBarrier);
       p->curr.execWidth = 1;
       p->WAIT();
     p->pop();
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 152054e..d988bb8 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -699,10 +699,12 @@ namespace gbe
     /*! double division */
     void F64DIV(Reg dst, Reg src0, Reg src1, GenRegister* tmp, int tmpNum);
     /*! Work Group Operations */
-    void WORKGROUP_OP(uint32_t wg_op, Reg dst, GenRegister src, GenRegister data,
-                      GenRegister threadId, GenRegister threadN,
-                      GenRegister tmp, GenRegister slmOff, vector<GenRegister> msg,
-                      uint32_t msgSizeReq);
+    void WORKGROUP_OP(uint32_t wg_op, Reg dst, GenRegister src,
+                      GenRegister tmpData1,
+                      GenRegister localThreadID, GenRegister localThreadNUM,
+                      GenRegister tmpData2, GenRegister slmOff,
+                      vector<GenRegister> msg, uint32_t msgSizeReq,
+                      GenRegister localBarrier);
     /* common functions for both binary instruction and sel_cmp and compare instruction.
        It will handle the IMM or normal register assignment, and will try to avoid LOADI
        as much as possible. */
@@ -2045,15 +2047,16 @@ namespace gbe
   void Selection::Opaque::WORKGROUP_OP(uint32_t wg_op,
                                        Reg dst,
                                        GenRegister src,
-                                       GenRegister data,
-                                       GenRegister threadId,
-                                       GenRegister threadN,
-                                       GenRegister tmp,
+                                       GenRegister tmpData1,
+                                       GenRegister localThreadID,
+                                       GenRegister localThreadNUM,
+                                       GenRegister tmpData2,
                                        GenRegister slmOff,
                                        vector<GenRegister> msg,
-                                       uint32_t msgSizeReq = 6)
+                                       uint32_t msgSizeReq,
+                                       GenRegister localBarrier)
   {
-    SelectionInstruction *insn = this->appendInsn(SEL_OP_WORKGROUP_OP, 2 + msg.size(), 5);
+    SelectionInstruction *insn = this->appendInsn(SEL_OP_WORKGROUP_OP, 2 + msg.size(), 6);
     SelectionVector *vector = this->appendVector();
 
     /* allocate continuous GRF registers for READ/WRITE to SLM */
@@ -2065,15 +2068,16 @@ namespace gbe
     insn->extra.workgroupOp = wg_op;
 
     insn->dst(0) = dst;
-    insn->dst(1) = tmp;
+    insn->dst(1) = tmpData1;
     for(uint32_t i = 0; i < msg.size(); i++)
       insn->dst(2 + i) = msg[i];
 
-    insn->src(0) = threadId;
-    insn->src(1) = threadN;
+    insn->src(0) = localThreadID;
+    insn->src(1) = localThreadNUM;
     insn->src(2) = src;
-    insn->src(3) = data;
+    insn->src(3) = tmpData2;
     insn->src(4) = slmOff;
+    insn->src(5) = localBarrier;
   }
 
   // Boiler plate to initialize the selection library at c++ pre-main
@@ -6462,11 +6466,12 @@ namespace gbe
       const Type type = insn.getType();
       GenRegister dst = sel.selReg(insn.getDst(0), type);
       GenRegister src = sel.selReg(insn.getSrc(2), type);
-      GenRegister tmp = GenRegister::retype(sel.selReg(sel.reg(FAMILY_QWORD)), type);
-      GenRegister data = sel.selReg(sel.reg(FAMILY_QWORD), type);
+      GenRegister tmpData1 = GenRegister::retype(sel.selReg(sel.reg(FAMILY_QWORD)), type);
+      GenRegister tmpData2 = GenRegister::retype(sel.selReg(sel.reg(FAMILY_QWORD)), type);
       GenRegister slmOff = sel.selReg(sel.reg(FAMILY_QWORD), TYPE_U32);
       GenRegister localThreadID = sel.selReg(ocl::threadid, TYPE_U32);
       GenRegister localThreadNUM = sel.selReg(ocl::threadn, TYPE_U32);
+      GenRegister localBarrier = GenRegister::ud8grf(sel.reg(FAMILY_DWORD));
 
       /* Allocate registers for message sending
        * (read/write to shared local memory) */
@@ -6483,8 +6488,9 @@ namespace gbe
       sel.MOV(slmOff, GenRegister::immud(insn.getSlmAddr()));
 
       /* Perform workgroup op */
-      sel.WORKGROUP_OP(workGroupOp, dst, src, data,
-                       localThreadID, localThreadNUM, tmp, slmOff, msg);
+      sel.WORKGROUP_OP(workGroupOp, dst, src, tmpData1,
+                       localThreadID, localThreadNUM, tmpData2, slmOff, msg, 6,
+                       localBarrier);
 
       return true;
     }
-- 
2.5.0



More information about the Beignet mailing list