[Beignet] [PATCH V2] add sends support for oword/media block write
Guo, Yejun
yejun.guo at intel.com
Wed Dec 28 07:18:14 UTC 2016
v2: should also change the virtual function prototype for gen7
Signed-off-by: Guo, Yejun <yejun.guo at intel.com>
---
backend/src/backend/gen7_encoder.cpp | 2 +-
backend/src/backend/gen7_encoder.hpp | 2 +-
backend/src/backend/gen9_encoder.cpp | 57 ++++++++++++++++++++++++++++++
backend/src/backend/gen9_encoder.hpp | 2 ++
backend/src/backend/gen_context.cpp | 6 ++--
backend/src/backend/gen_encoder.cpp | 4 +--
backend/src/backend/gen_encoder.hpp | 4 +--
backend/src/backend/gen_insn_selection.cpp | 54 +++++++++++++++++++++-------
8 files changed, 111 insertions(+), 20 deletions(-)
diff --git a/backend/src/backend/gen7_encoder.cpp b/backend/src/backend/gen7_encoder.cpp
index 4f35491..4b2cd9a 100644
--- a/backend/src/backend/gen7_encoder.cpp
+++ b/backend/src/backend/gen7_encoder.cpp
@@ -280,7 +280,7 @@ namespace gbe
response_length);
}
- void Gen7Encoder::MBWRITE(GenRegister header, uint32_t bti, uint32_t size) {
+ void Gen7Encoder::MBWRITE(GenRegister header, GenRegister data, uint32_t bti, uint32_t size, bool useSends) {
GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
const uint32_t msg_length = 1 + size;
const uint32_t response_length = 0; // Size of registers
diff --git a/backend/src/backend/gen7_encoder.hpp b/backend/src/backend/gen7_encoder.hpp
index edb711d..7585b34 100644
--- a/backend/src/backend/gen7_encoder.hpp
+++ b/backend/src/backend/gen7_encoder.hpp
@@ -45,7 +45,7 @@ namespace gbe
/*! MBlock read */
virtual void MBREAD(GenRegister dst, GenRegister header, uint32_t bti, uint32_t elemSize);
/*! MBlock write */
- virtual void MBWRITE(GenRegister header, uint32_t bti, uint32_t elemSize);
+ virtual void MBWRITE(GenRegister header, GenRegister data, uint32_t bti, uint32_t elemSize, bool useSends);
};
}
#endif /* __GBE_GEN7_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen9_encoder.cpp b/backend/src/backend/gen9_encoder.cpp
index 940809b..b37fd98 100644
--- a/backend/src/backend/gen9_encoder.cpp
+++ b/backend/src/backend/gen9_encoder.cpp
@@ -244,4 +244,61 @@ namespace gbe
gen9_insn->bits2.sends.sel_reg32_desc = 1;
}
}
+
+ void Gen9Encoder::OBWRITE(GenRegister header, GenRegister data, uint32_t bti, uint32_t ow_size, bool useSends)
+ {
+ if (!useSends)
+ Gen8Encoder::OBWRITE(header, data, bti, ow_size, false);
+ else {
+ GBE_ASSERT(data.reg() != header.reg());
+ GenNativeInstruction *insn = this->next(GEN_OPCODE_SENDS);
+ Gen9NativeInstruction *gen9_insn = &insn->gen9_insn;
+
+ this->setHeader(insn);
+ insn->header.destreg_or_condmod = GEN_SFID_DATAPORT_DATA;
+
+ setSendsOperands(gen9_insn, GenRegister::null(), header, data);
+
+ uint32_t dataRegs = ow_size / 2;
+ // half reg should also have size 1
+ if (dataRegs == 0)
+ dataRegs = 1;
+ gen9_insn->bits2.sends.src1_length = dataRegs;
+
+ const uint32_t block_size = getOBlockSize(ow_size);
+ const uint32_t msg_length = 1;
+ const uint32_t response_length = 0;
+ setOBlockRW(insn,
+ bti,
+ block_size,
+ GEN7_OBLOCK_WRITE,
+ msg_length,
+ response_length);
+ }
+ }
+
+ void Gen9Encoder::MBWRITE(GenRegister header, GenRegister data, uint32_t bti, uint32_t data_size, bool useSends)
+ {
+ if (!useSends)
+ Gen8Encoder::MBWRITE(header, data, bti, data_size, false);
+ else {
+ GBE_ASSERT(data.reg() != header.reg());
+ GenNativeInstruction *insn = this->next(GEN_OPCODE_SENDS);
+ Gen9NativeInstruction *gen9_insn = &insn->gen9_insn;
+
+ this->setHeader(insn);
+ insn->header.destreg_or_condmod = GEN_SFID_DATAPORT_DATA;
+
+ setSendsOperands(gen9_insn, GenRegister::null(), header, data);
+ gen9_insn->bits2.sends.src1_length = data_size;
+
+ const uint32_t msg_length = 1;
+ const uint32_t response_length = 0;
+ setMBlockRW(insn,
+ bti,
+ GEN75_P1_MEDIA_TYPED_BWRITE,
+ msg_length,
+ response_length);
+ }
+ }
} /* End of the name space. */
diff --git a/backend/src/backend/gen9_encoder.hpp b/backend/src/backend/gen9_encoder.hpp
index d754d59..2eaa538 100644
--- a/backend/src/backend/gen9_encoder.hpp
+++ b/backend/src/backend/gen9_encoder.hpp
@@ -54,6 +54,8 @@ namespace gbe
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);
+ virtual void OBWRITE(GenRegister header, GenRegister data, uint32_t bti, uint32_t ow_size, bool useSends);
+ virtual void MBWRITE(GenRegister header, GenRegister data, uint32_t bti, uint32_t data_size, bool useSends);
};
}
#endif /* __GBE_GEN9_ENCODER_HPP__ */
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 10e2c9e..5f60ff3 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -3569,13 +3569,14 @@ namespace gbe
void GenContext::emitOBWriteInstruction(const SelectionInstruction &insn) {
const GenRegister header = ra->genReg(insn.src(0));
+ const GenRegister data = ra->genReg(insn.src(1));
const uint32_t bti = insn.getbti();
const uint32_t ow_size = insn.extra.elem;
bool isA64 = bti == 255;
if (isA64)
p->OBWRITEA64(header, bti, ow_size);
else
- p->OBWRITE(header, bti, ow_size);
+ p->OBWRITE(header, data, bti, ow_size, insn.extra.splitSend);
}
void GenContext::emitMBReadInstruction(const SelectionInstruction &insn) {
@@ -3587,8 +3588,9 @@ namespace gbe
void GenContext::emitMBWriteInstruction(const SelectionInstruction &insn) {
const GenRegister header = ra->genReg(insn.dst(0));
+ const GenRegister data = ra->genReg(insn.dst(1));
const size_t data_size = insn.extra.elem;
- p->MBWRITE(header, insn.getbti(), data_size);
+ p->MBWRITE(header, data, insn.getbti(), data_size, insn.extra.splitSend);
}
BVAR(OCL_OUTPUT_REG_ALLOC, false);
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index d95d03e..03ce0e2 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -1348,7 +1348,7 @@ namespace gbe
response_length);
}
- void GenEncoder::OBWRITE(GenRegister header, uint32_t bti, uint32_t ow_size) {
+ void GenEncoder::OBWRITE(GenRegister header, GenRegister data, uint32_t bti, uint32_t ow_size, bool useSends) {
GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
uint32_t sizeinreg = ow_size / 2;
// half reg should also have size 1
@@ -1384,7 +1384,7 @@ namespace gbe
response_length);
}
- void GenEncoder::MBWRITE(GenRegister header, uint32_t bti, uint32_t data_size) {
+ void GenEncoder::MBWRITE(GenRegister header, GenRegister data, uint32_t bti, uint32_t data_size, bool useSends) {
GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
const uint32_t msg_length = 1 + data_size;
const uint32_t response_length = 0; // Size of registers
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index 4e9fe58..3e45c81 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -297,11 +297,11 @@ namespace gbe
/*! OBlock read */
void OBREAD(GenRegister dst, GenRegister header, uint32_t bti, uint32_t ow_size);
/*! OBlock write */
- void OBWRITE(GenRegister header, uint32_t bti, uint32_t ow_size);
+ virtual void OBWRITE(GenRegister header, GenRegister data, uint32_t bti, uint32_t ow_size, bool useSends);
/*! MBlock read */
virtual void MBREAD(GenRegister dst, GenRegister header, uint32_t bti, uint32_t response_size);
/*! MBlock write */
- virtual void MBWRITE(GenRegister header, uint32_t bti, uint32_t data_size);
+ virtual void MBWRITE(GenRegister header, GenRegister data, uint32_t bti, uint32_t data_size, bool useSends);
/*! A64 OBlock read */
virtual void OBREADA64(GenRegister dst, GenRegister header, uint32_t bti, uint32_t ow_size);
/*! A64 OBlock write */
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index dd21960..7990737 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -2324,18 +2324,33 @@ namespace gbe
uint32_t bti,
uint32_t ow_size) {
SelectionInstruction *insn = this->appendInsn(SEL_OP_OBWRITE, 0, vec_size + 1);
- SelectionVector *vector = this->appendVector();
insn->src(0) = header;
for (uint32_t i = 0; i < vec_size; ++i)
insn->src(i + 1) = values[i];
insn->setbti(bti);
insn->extra.elem = ow_size; // number of OWord_size
- // tmp regs for OWORD write header and values
- vector->regNum = vec_size + 1;
- vector->reg = &insn->src(0);
- vector->offsetID = 0;
- vector->isSrc = 1;
+ if (hasSends()) {
+ insn->extra.splitSend = 1;
+ SelectionVector *vector = this->appendVector();
+ vector->regNum = 1;
+ vector->reg = &insn->src(0);
+ vector->offsetID = 0;
+ vector->isSrc = 1;
+
+ vector = this->appendVector();
+ vector->regNum = vec_size;
+ vector->reg = &insn->src(1);
+ vector->offsetID = 1;
+ vector->isSrc = 1;
+ } else {
+ // tmp regs for OWORD write header and values
+ SelectionVector *vector = this->appendVector();
+ vector->regNum = vec_size + 1;
+ vector->reg = &insn->src(0);
+ vector->offsetID = 0;
+ vector->isSrc = 1;
+ }
}
@@ -2366,18 +2381,33 @@ namespace gbe
uint32_t bti,
uint32_t data_size) {
SelectionInstruction *insn = this->appendInsn(SEL_OP_MBWRITE, 0, 1 + tmp_size);
- SelectionVector *vector = this->appendVector();
insn->src(0) = header;
for (uint32_t i = 0; i < tmp_size; ++i)
insn->src(1 + i) = values[i];
insn->setbti(bti);
insn->extra.elem = data_size; // msg data part size
- // We need to put the header and the data together
- vector->regNum = 1 + tmp_size;
- vector->reg = &insn->src(0);
- vector->offsetID = 0;
- vector->isSrc = 1;
+ if (hasSends()) {
+ insn->extra.splitSend = 1;
+ SelectionVector *vector = this->appendVector();
+ vector->regNum = 1;
+ vector->reg = &insn->src(0);
+ vector->offsetID = 0;
+ vector->isSrc = 1;
+
+ vector = this->appendVector();
+ vector->regNum = tmp_size;
+ vector->reg = &insn->src(1);
+ vector->offsetID = 1;
+ vector->isSrc = 1;
+ } else {
+ // We need to put the header and the data together
+ SelectionVector *vector = this->appendVector();
+ vector->regNum = 1 + tmp_size;
+ vector->reg = &insn->src(0);
+ vector->offsetID = 0;
+ vector->isSrc = 1;
+ }
}
// Boiler plate to initialize the selection library at c++ pre-main
--
1.9.1
More information about the Beignet
mailing list