[Beignet] [PATCH] add sends for atomic operation, only for ocl 1.2
Guo, Yejun
yejun.guo at intel.com
Wed Nov 30 04:33:52 UTC 2016
Signed-off-by: Guo, Yejun <yejun.guo at intel.com>
---
backend/src/backend/gen8_encoder.cpp | 2 +-
backend/src/backend/gen8_encoder.hpp | 2 +-
backend/src/backend/gen9_encoder.cpp | 26 ++++++++++++++++++++++++++
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 | 26 +++++++++++++++++++++-----
8 files changed, 67 insertions(+), 16 deletions(-)
diff --git a/backend/src/backend/gen8_encoder.cpp b/backend/src/backend/gen8_encoder.cpp
index 8f73346..a29e59d 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) {
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 f6a91a0..1e8ce36 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);
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);
diff --git a/backend/src/backend/gen9_encoder.cpp b/backend/src/backend/gen9_encoder.cpp
index b5be852..2d7e572 100644
--- a/backend/src/backend/gen9_encoder.cpp
+++ b/backend/src/backend/gen9_encoder.cpp
@@ -190,4 +190,30 @@ 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)
+ {
+ if (addr.reg() == data.reg())
+ Gen8Encoder::ATOMIC(dst, function, addr, data, bti, srcNum);
+ else {
+ 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 1c40b92..8b738cc 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);
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);
};
}
#endif /* __GBE_GEN9_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 9505592..0a76209 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 (insn.extra.splitSend && 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);
} 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);
p->pop();
afterMessage(insn, bti, flagTemp, btiTmp, jip0);
}
@@ -2837,7 +2845,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);
} p->pop();
// Calculate the final addr
@@ -3503,7 +3511,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);
/* Write out the header. */
p->MOV(data, GenRegister::immud(0xAABBCCDD));
p->UNTYPED_WRITE(addr, addr, GenRegister::immud(insn.extra.printfBTI), 1);
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index 38161c2..2a03625 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) {
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 e5eb2e2..e2a24fe 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);
/*! 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 9722423..9fb6d55 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -1345,11 +1345,27 @@ 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()) {
+ insn->extra.splitSend = 1;
+ SelectionVector *vector = this->appendVector();
+ vector->regNum = 1;
+ vector->offsetID = 0;
+ vector->reg = &insn->src(0);
+ vector->isSrc = 1;
+ if (msgPayload > 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