[Beignet] [PATCH 4/4] GBE: move the image info register allocation to GEN IR stage.
Zhigang Gong
zhigang.gong at intel.com
Wed Jan 15 22:00:37 PST 2014
If we allocate image infor register at code generation stage,
we miss the liveness calculation. Thus there is a potential risk
that some image information register's livenss data is incorrect and
may cause very subtle bug. Now fix it.
Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
backend/src/backend/context.cpp | 14 +++-----------
backend/src/backend/gen_context.cpp | 17 -----------------
.../src/backend/gen_insn_gen7_schedule_info.hxx | 1 -
backend/src/backend/gen_insn_selection.hxx | 1 -
backend/src/backend/gen_reg_allocation.cpp | 3 +--
backend/src/ir/image.cpp | 10 ++++++++++
backend/src/ir/image.hpp | 3 +++
backend/src/ir/instruction.hpp | 3 ++-
backend/src/llvm/llvm_gen_backend.cpp | 5 +++--
9 files changed, 22 insertions(+), 35 deletions(-)
diff --git a/backend/src/backend/context.cpp b/backend/src/backend/context.cpp
index 1941689..7a80dc8 100644
--- a/backend/src/backend/context.cpp
+++ b/backend/src/backend/context.cpp
@@ -472,19 +472,11 @@ namespace gbe
if (srcID != 0) continue;
const unsigned char bti = ir::cast<ir::GetImageInfoInstruction>(insn).getImageIndex();
const unsigned char type = ir::cast<ir::GetImageInfoInstruction>(insn).getInfoType();;
- ir::ImageInfoKey key;
- key.index = bti;
- key.type = type;
- const ir::Register imageInfo(key.data | 0x8000);
- ir::Register realImageInfo;
+ ir::ImageInfoKey key(bti, type);
+ const ir::Register imageInfo = insn.getSrc(0);
if (curbeRegs.find(imageInfo) == curbeRegs.end()) {
uint32_t offset = this->getImageInfoCurbeOffset(key, 4);
- realImageInfo = insn.getSrc(0);
- insertCurbeReg(realImageInfo, offset);
- insertCurbeReg(imageInfo, (uint32_t)realImageInfo);
- } else {
- realImageInfo = ir::Register(curbeRegs.find(imageInfo)->second);
- insn.setSrc(0, realImageInfo);
+ insertCurbeReg(imageInfo, offset);
}
continue;
} else if (insn.getOpcode() == ir::OP_GET_SAMPLER_INFO) {
diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index ea7a9f1..6a9461b 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -1862,23 +1862,6 @@ namespace gbe
p->pop();
}
- void GenContext::emitGetImageInfoInstruction(const SelectionInstruction &insn) {
- const unsigned char bti = insn.extra.function;
- const unsigned char type = insn.extra.elem;
- const uint32_t dstNum = ir::GetImageInfoInstruction::getDstNum4Type(type);
- ir::ImageInfoKey key;
- key.index = bti;
- key.type = type;
-
- uint32_t offset = this->getImageInfoCurbeOffset(key, dstNum * 4) + GEN_REG_SIZE;
- for(uint32_t i = 0; i < dstNum; i++) {
- const uint32_t nr = offset / GEN_REG_SIZE;
- const uint32_t subnr = (offset % GEN_REG_SIZE) / sizeof(uint32_t);
- p->MOV(ra->genReg(insn.dst(i)), GenRegister::ud1grf(nr, subnr));
- offset += 32;
- }
- }
-
BVAR(OCL_OUTPUT_REG_ALLOC, false);
BVAR(OCL_OUTPUT_ASM, false);
bool GenContext::emitCode(void) {
diff --git a/backend/src/backend/gen_insn_gen7_schedule_info.hxx b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
index bb70b16..13cbd41 100644
--- a/backend/src/backend/gen_insn_gen7_schedule_info.hxx
+++ b/backend/src/backend/gen_insn_gen7_schedule_info.hxx
@@ -34,7 +34,6 @@ DECL_GEN7_SCHEDULE(Sample, 80, 1, 1)
DECL_GEN7_SCHEDULE(TypedWrite, 80, 1, 1)
DECL_GEN7_SCHEDULE(SpillReg, 80, 1, 1)
DECL_GEN7_SCHEDULE(UnSpillReg, 80, 1, 1)
-DECL_GEN7_SCHEDULE(GetImageInfo, 20, 4, 2)
DECL_GEN7_SCHEDULE(Atomic, 80, 1, 1)
DECL_GEN7_SCHEDULE(I64MUL, 20, 4, 2)
DECL_GEN7_SCHEDULE(I64SATADD, 20, 4, 2)
diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
index 0118619..e44b9d4 100644
--- a/backend/src/backend/gen_insn_selection.hxx
+++ b/backend/src/backend/gen_insn_selection.hxx
@@ -60,7 +60,6 @@ DECL_SELECTION_IR(BYTE_SCATTER, ByteScatterInstruction)
DECL_SELECTION_IR(DWORD_GATHER, DWordGatherInstruction)
DECL_SELECTION_IR(SAMPLE, SampleInstruction)
DECL_SELECTION_IR(TYPED_WRITE, TypedWriteInstruction)
-DECL_SELECTION_IR(GET_IMAGE_INFO, GetImageInfoInstruction)
DECL_SELECTION_IR(SPILL_REG, SpillRegInstruction)
DECL_SELECTION_IR(UNSPILL_REG, UnSpillRegInstruction)
DECL_SELECTION_IR(MUL_HI, BinaryWithTempInstruction)
diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp
index f3dc7ac..9362795 100644
--- a/backend/src/backend/gen_reg_allocation.cpp
+++ b/backend/src/backend/gen_reg_allocation.cpp
@@ -140,8 +140,7 @@ namespace gbe
INLINE void GenRegAllocator::Opaque::allocatePayloadRegs(void) {
using namespace ir;
for(auto &it : this->ctx.curbeRegs)
- if (it.first.value() < 0x8000)
- allocatePayloadReg(it.first, it.second);
+ allocatePayloadReg(it.first, it.second);
// Allocate all pushed registers (i.e. structure kernel arguments)
const Function &fn = ctx.getFunction();
diff --git a/backend/src/ir/image.cpp b/backend/src/ir/image.cpp
index af43ac7..8c34d70 100644
--- a/backend/src/ir/image.cpp
+++ b/backend/src/ir/image.cpp
@@ -64,6 +64,16 @@ namespace ir {
setInfoOffset4Type(imageInfo, key.type, offset);
}
+ Register ImageSet::appendInfo(ImageInfoKey key, Context *ctx)
+ {
+ auto it = infoRegMap.find(key.data);
+ if (it != infoRegMap.end())
+ return it->second;
+ Register reg = ctx->reg(FAMILY_DWORD);
+ infoRegMap.insert(std::make_pair(key.data, reg));
+ return reg;
+ }
+
void ImageSet::clearInfo()
{
struct ImageInfo *imageInfo;
diff --git a/backend/src/ir/image.hpp b/backend/src/ir/image.hpp
index 088e479..cf388d4 100644
--- a/backend/src/ir/image.hpp
+++ b/backend/src/ir/image.hpp
@@ -47,6 +47,8 @@ namespace ir {
void append(Register imageReg, Context *ctx);
/*! Append an image info slot. */
void appendInfo(ImageInfoKey key, uint32_t offset);
+ /*! Append an image info register. */
+ Register appendInfo(ImageInfoKey, Context *ctx);
/*! clear image info. */
void clearInfo();
/*! Get the image's index(actual location). */
@@ -88,6 +90,7 @@ namespace ir {
private:
map<Register, struct ImageInfo *> regMap;
map<uint32_t, struct ImageInfo *> indexMap;
+ map<uint32_t, Register> infoRegMap;
GBE_CLASS(ImageSet);
};
} /* namespace ir */
diff --git a/backend/src/ir/instruction.hpp b/backend/src/ir/instruction.hpp
index a9d9adf..66b64dd 100644
--- a/backend/src/ir/instruction.hpp
+++ b/backend/src/ir/instruction.hpp
@@ -373,7 +373,8 @@ namespace ir {
static bool isClassOf(const Instruction &insn);
};
- typedef union {
+ typedef union _ImageInfoKey{
+ _ImageInfoKey(uint8_t i, uint8_t t) : index(i), type(t) {};
struct {
uint8_t index; /*! the allocated image index */
uint8_t type; /*! the information type */
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 5fb6db1..b0555aa 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -2362,9 +2362,10 @@ namespace gbe
GBE_ASSERT(AI != AE); const ir::Register surfaceReg = this->getRegister(*AI); ++AI;
const ir::Register reg = this->getRegister(&I, 0);
int infoType = it->second - GEN_OCL_GET_IMAGE_WIDTH;
-
const uint8_t surfaceID = ctx.getFunction().getImageSet()->getIdx(surfaceReg);
- ctx.GET_IMAGE_INFO(infoType, reg, surfaceID, ctx.reg(ir::FAMILY_DWORD));
+ ir::ImageInfoKey key(surfaceID, infoType);
+ const ir::Register infoReg = ctx.getFunction().getImageSet()->appendInfo(key, &ctx);
+ ctx.GET_IMAGE_INFO(infoType, reg, surfaceID, infoReg);
break;
}
case GEN_OCL_GET_SAMPLER_INFO:
--
1.7.9.5
More information about the Beignet
mailing list