summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuiling Song <ruiling.song@intel.com>2014-12-04 10:52:09 +0800
committerZhigang Gong <zhigang.gong@intel.com>2014-12-04 14:01:43 +0800
commit07475bc0b4b6a588cb0326b5f156e6f2e8a888f3 (patch)
treef3b441ea7d096a3180e7f10e0055423f3101ecbd
parentb9d1080b709cd0178edb93796e5c3dcdc212f97a (diff)
GBE: support const private array initialization.
Developers are allowed to declare initialized private array like below: void func() { const arr[]={1, 2, 3, 4}; } The implementation is simply put them into __constant memory space. Signed-off-by: Ruiling Song <ruiling.song@intel.com> Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
-rw-r--r--backend/src/backend/gen_insn_selection.cpp43
-rw-r--r--backend/src/llvm/llvm_gen_backend.cpp56
2 files changed, 54 insertions, 45 deletions
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 96970c74..7ea24989 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -2844,7 +2844,6 @@ namespace gbe
vector<GenRegister> &dst2,
GenRegister addr,
uint32_t valueNum,
- ir::AddressSpace space,
ir::BTI bti) const
{
for (uint32_t x = 0; x < bti.count; x++) {
@@ -2852,7 +2851,7 @@ namespace gbe
for (uint32_t dstID = 0; dstID < valueNum; ++dstID)
dst2[dstID] = sel.selReg(sel.reg(ir::FAMILY_DWORD), ir::TYPE_U32);
- GenRegister temp = getRelativeAddress(sel, addr, space, bti.bti[x]);
+ GenRegister temp = getRelativeAddress(sel, addr, bti.bti[x]);
sel.UNTYPED_READ(temp, dst2.data(), valueNum, bti.bti[x]);
if(x > 0) {
sel.push();
@@ -2878,7 +2877,7 @@ namespace gbe
vector<GenRegister> dst2(valueNum);
for (uint32_t dstID = 0; dstID < valueNum; ++dstID)
dst2[dstID] = dst[dstID] = sel.selReg(insn.getValue(dstID), TYPE_U32);
- readDWord(sel, dst, dst2, addr, valueNum, insn.getAddressSpace(), bti);
+ readDWord(sel, dst, dst2, addr, valueNum, bti);
}
void emitDWordGather(Selection::Opaque &sel,
@@ -2925,7 +2924,7 @@ namespace gbe
GBE_ASSERT(valueNum == 1);
GBE_ASSERT(bti.count == 1);
vector<GenRegister> dst(valueNum);
- GenRegister tmpAddr = getRelativeAddress(sel, addr, insn.getAddressSpace(), bti.bti[0]);
+ GenRegister tmpAddr = getRelativeAddress(sel, addr, bti.bti[0]);
for ( uint32_t dstID = 0; dstID < valueNum; ++dstID)
dst[dstID] = sel.selReg(insn.getValue(dstID), ir::TYPE_U64);
sel.READ64(tmpAddr, dst.data(), valueNum, bti.bti[0]);
@@ -2996,7 +2995,7 @@ namespace gbe
tmp2[i] = tmp[i] = GenRegister::udxgrf(simdWidth, tmpReg[i]);
}
- readDWord(sel, tmp, tmp2, address, tmpRegNum, insn.getAddressSpace(), bti);
+ readDWord(sel, tmp, tmp2, address, tmpRegNum, bti);
for(uint32_t i = 0; i < tmpRegNum; i++) {
unsigned int elemNum = (valueNum - i * (4 / typeSize)) > 4/typeSize ?
@@ -3099,7 +3098,7 @@ namespace gbe
sel.ADD(alignedAddr, alignedAddr, GenRegister::immud(pos * 4));
sel.pop();
}
- readDWord(sel, t1, t2, alignedAddr, width, insn.getAddressSpace(), bti);
+ readDWord(sel, t1, t2, alignedAddr, width, bti);
remainedReg -= width;
pos += width;
} while(remainedReg);
@@ -3124,7 +3123,7 @@ namespace gbe
if (x > 0)
tmp = sel.selReg(sel.reg(family, simdWidth == 1), insn.getValueType());
- GenRegister addr = getRelativeAddress(sel, address, insn.getAddressSpace(), bti.bti[x]);
+ GenRegister addr = getRelativeAddress(sel, address, bti.bti[x]);
readByteAsDWord(sel, elemSize, addr, tmp, simdWidth, bti.bti[x]);
if (x > 0) {
sel.push();
@@ -3151,8 +3150,8 @@ namespace gbe
sel.INDIRECT_MOVE(dst, src);
}
- INLINE GenRegister getRelativeAddress(Selection::Opaque &sel, GenRegister address, ir::AddressSpace space, uint8_t bti) const {
- if(space == ir::MEM_LOCAL || space == ir::MEM_CONSTANT)
+ INLINE GenRegister getRelativeAddress(Selection::Opaque &sel, GenRegister address, uint8_t bti) const {
+ if (bti == 0xfe || bti == BTI_CONSTANT)
return address;
sel.push();
@@ -3162,6 +3161,14 @@ namespace gbe
sel.pop();
return temp;
}
+ // check whether all binded table index point to constant memory
+ INLINE bool isAllConstant(const ir::BTI &bti) const {
+ for (int x = 0; x < bti.count; x++) {
+ if (bti.bti[x] != BTI_CONSTANT)
+ return false;
+ }
+ return true;
+ }
INLINE bool emitOne(Selection::Opaque &sel, const ir::LoadInstruction &insn, bool &markChildren) const {
using namespace ir;
@@ -3179,14 +3186,10 @@ namespace gbe
sel.ADD(temp, address, sel.selReg(ocl::slmoffset, ir::TYPE_U32));
address = temp;
}
- BTI bti;
- if (space == MEM_CONSTANT || space == MEM_LOCAL) {
- bti.bti[0] = space == MEM_CONSTANT ? BTI_CONSTANT : 0xfe;
- bti.count = 1;
- } else {
- bti = insn.getBTI();
- }
- if (space == MEM_CONSTANT) {
+ const BTI &bti = insn.getBTI();
+ bool allConstant = isAllConstant(bti);
+
+ if (allConstant) {
// XXX TODO read 64bit constant through constant cache
// Per HW Spec, constant cache messages can read at least DWORD data.
// So, byte/short data type, we have to read through data cache.
@@ -3291,8 +3294,8 @@ namespace gbe
}
}
- INLINE GenRegister getRelativeAddress(Selection::Opaque &sel, GenRegister address, ir::AddressSpace space, uint8_t bti) const {
- if(space == ir::MEM_LOCAL || space == ir::MEM_CONSTANT)
+ INLINE GenRegister getRelativeAddress(Selection::Opaque &sel, GenRegister address, uint8_t bti) const {
+ if(bti == 0xfe)
return address;
sel.push();
@@ -3318,7 +3321,7 @@ namespace gbe
BTI bti = insn.getBTI();
for (int x = 0; x < bti.count; x++) {
- GenRegister temp = getRelativeAddress(sel, address, space, bti.bti[x]);
+ GenRegister temp = getRelativeAddress(sel, address, bti.bti[x]);
if (insn.isAligned() == true && elemSize == GEN_BYTE_SCATTER_QWORD)
this->emitWrite64(sel, insn, temp, bti.bti[x]);
else if (insn.isAligned() == true && elemSize == GEN_BYTE_SCATTER_DWORD)
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index b6cb4c73..c7ecc443 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -848,7 +848,7 @@ namespace gbe
if(!v.isConstantUsed()) continue;
const char *name = v.getName().data();
unsigned addrSpace = v.getType()->getAddressSpace();
- if(addrSpace == ir::AddressSpace::MEM_CONSTANT) {
+ if(addrSpace == ir::AddressSpace::MEM_CONSTANT || v.isConstant()) {
GBE_ASSERT(v.hasInitializer());
const Constant *c = v.getInitializer();
Type * type = c->getType();
@@ -1924,7 +1924,7 @@ namespace gbe
this->newRegister(const_cast<GlobalVariable*>(&v));
ir::Register reg = regTranslator.getScalar(const_cast<GlobalVariable*>(&v), 0);
ctx.LOADI(ir::TYPE_S32, reg, ctx.newIntegerImmediate(oldSlm + padding/8, ir::TYPE_S32));
- } else if(addrSpace == ir::MEM_CONSTANT) {
+ } else if(addrSpace == ir::MEM_CONSTANT || v.isConstant()) {
GBE_ASSERT(v.hasInitializer());
this->newRegister(const_cast<GlobalVariable*>(&v));
ir::Register reg = regTranslator.getScalar(const_cast<GlobalVariable*>(&v), 0);
@@ -1942,7 +1942,7 @@ namespace gbe
ctx.getFunction().getPrintfSet()->setIndexBufBTI(btiBase);
globalPointer.insert(std::make_pair(&v, incBtiBase()));
regTranslator.newScalarProxy(ir::ocl::printfiptr, const_cast<GlobalVariable*>(&v));
- } else if(v.getName().str().substr(0, 4) == ".str") {
+ } else if(v.getName().str().substr(0, 4) == ".str") {
/* When there are multi printf statements in multi kernel fucntions within the same
translate unit, if they have the same sting parameter, such as
kernel_func1 () {
@@ -1955,12 +1955,12 @@ namespace gbe
So when translating the kernel_func1, we can not unref that global var, so we will
get here. Just ignore it to avoid assert. */
} else {
- GBE_ASSERT(0);
+ GBE_ASSERT(0 && "Unsupported private memory access pattern");
}
}
}
-
}
+
static INLINE void findAllLoops(LoopInfo * LI, std::vector<std::pair<Loop*, int>> &lp)
{
for (Loop::reverse_iterator I = LI->rbegin(), E = LI->rend(); I != E; ++I) {
@@ -3873,27 +3873,33 @@ handle_write_image:
for (unsigned i = 0; i < origins.size(); i++) {
uint8_t new_bti = 0;
Value *origin = origins[i];
- unsigned space = origin->getType()->getPointerAddressSpace();
- switch (space) {
- case 0:
- new_bti = BTI_PRIVATE;
- break;
- case 1:
- {
- GlobalPtrIter iter = globalPointer.find(origin);
- GBE_ASSERT(iter != globalPointer.end());
- new_bti = iter->second;
- break;
+ // all constant put into constant cache, including __constant & const __private
+ if (isa<GlobalVariable>(origin)
+ && dyn_cast<GlobalVariable>(origin)->isConstant()) {
+ new_bti = BTI_CONSTANT;
+ } else {
+ unsigned space = origin->getType()->getPointerAddressSpace();
+ switch (space) {
+ case 0:
+ new_bti = BTI_PRIVATE;
+ break;
+ case 1:
+ {
+ GlobalPtrIter iter = globalPointer.find(origin);
+ GBE_ASSERT(iter != globalPointer.end());
+ new_bti = iter->second;
+ break;
+ }
+ case 2:
+ new_bti = BTI_CONSTANT;
+ break;
+ case 3:
+ new_bti = 0xfe;
+ break;
+ default:
+ GBE_ASSERT(0 && "address space not unhandled in gatherBTI()\n");
+ break;
}
- case 2:
- new_bti = BTI_CONSTANT;
- break;
- case 3:
- new_bti = 0xfe;
- break;
- default:
- GBE_ASSERT(0 && "address space not unhandled in gatherBTI()\n");
- break;
}
// avoid duplicate