[Beignet] [PATCH 1/3] GBE: support const private array initialization.

Zhigang Gong zhigang.gong at linux.intel.com
Wed Dec 3 22:52:58 PST 2014


The patchset LGTM, will push latter, thanks.

On Thu, Dec 04, 2014 at 10:52:09AM +0800, Ruiling Song wrote:
> 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 at intel.com>
> ---
>  backend/src/backend/gen_insn_selection.cpp |   43 +++++++++++-----------
>  backend/src/llvm/llvm_gen_backend.cpp      |   54 +++++++++++++++-------------
>  2 files changed, 53 insertions(+), 44 deletions(-)
> 
> diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
> index 96970c7..7ea2498 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 b6cb4c7..5bff92b 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,7 +1955,7 @@ 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");
>          }
>        }
>      }
> @@ -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
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list