diff options
author | Ruiling Song <ruiling.song@intel.com> | 2014-12-04 10:52:09 +0800 |
---|---|---|
committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-12-04 14:01:43 +0800 |
commit | 07475bc0b4b6a588cb0326b5f156e6f2e8a888f3 (patch) | |
tree | f3b441ea7d096a3180e7f10e0055423f3101ecbd | |
parent | b9d1080b709cd0178edb93796e5c3dcdc212f97a (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.cpp | 43 | ||||
-rw-r--r-- | backend/src/llvm/llvm_gen_backend.cpp | 56 |
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 |