[Beignet] [PATCH 1/2] GBE: Support composite type constant.

Zhigang Gong zhigang.gong at linux.intel.com
Tue Sep 17 22:16:06 PDT 2013


This patchset LGTM, pushed, thanks.

On Wed, Sep 18, 2013 at 10:18:42AM +0800, Ruiling Song wrote:
> struct/vector/array of vector/struct of array/array of struct.
> 
> Also fix a bug 'constant index into constant array get wrong result'
> brought in by patch 'Fix non-4byte program global constant issue'.
> 
> Signed-off-by: Ruiling Song <ruiling.song at intel.com>
> ---
>  backend/src/llvm/llvm_gen_backend.cpp |  201 +++++++++++++++++++++------------
>  1 file changed, 130 insertions(+), 71 deletions(-)
> 
> diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
> index f357977..859107f 100644
> --- a/backend/src/llvm/llvm_gen_backend.cpp
> +++ b/backend/src/llvm/llvm_gen_backend.cpp
> @@ -460,7 +460,8 @@ namespace gbe
>      }
>  
>      virtual bool doInitialization(Module &M);
> -
> +    /*! helper function for parsing global constant data */
> +    void getConstantData(const Constant * c, void* mem, uint32_t& offset) const;
>      void collectGlobalConstant(void) const;
>  
>      bool runOnFunction(Function &F) {
> @@ -559,6 +560,99 @@ namespace gbe
>    };
>  
>    char GenWriter::ID = 0;
> +  void getSequentialData(const ConstantDataSequential *cda, void *ptr, uint32_t &offset) {
> +    StringRef data = cda->getRawDataValues();
> +    memcpy((char*)ptr+offset, data.data(), data.size());
> +    offset += data.size();
> +    return;
> +  }
> +
> +  void GenWriter::getConstantData(const Constant * c, void* mem, uint32_t& offset) const {
> +    Type * type = c->getType();
> +    Type::TypeID id = type->getTypeID();
> +
> +    GBE_ASSERT(c);
> +    if(isa<UndefValue>(c)) {
> +      uint32_t n = c->getNumOperands();
> +      Type * opTy = type->getArrayElementType();
> +      uint32_t size = opTy->getIntegerBitWidth()/ 8;
> +      offset += size*n;
> +      return;
> +    }
> +    switch(id) {
> +      case Type::TypeID::StructTyID:
> +        {
> +          const StructType * strTy = cast<StructType>(c->getType());
> +          uint32_t size = 0;
> +
> +          for(uint32_t op=0; op < strTy->getNumElements(); op++)
> +          {
> +            Type* elementType = strTy->getElementType(op);
> +            uint32_t align = 8 * getAlignmentByte(unit, elementType);
> +            uint32_t padding = getPadding(size, align);
> +            size += padding;
> +            size += getTypeBitSize(unit, elementType);
> +
> +            offset += padding/8;
> +            const Constant* sub = cast<Constant>(c->getOperand(op));
> +            GBE_ASSERT(sub);
> +            getConstantData(sub, mem, offset);
> +          }
> +          break;
> +        }
> +      case Type::TypeID::ArrayTyID:
> +        {
> +          const ConstantDataSequential *cds = dyn_cast<ConstantDataSequential>(c);
> +          if(cds)
> +            getSequentialData(cds, mem, offset);
> +          else {
> +            const ConstantArray *ca = dyn_cast<ConstantArray>(c);
> +            const ArrayType *arrTy = ca->getType();
> +            Type* elemTy = arrTy->getElementType();
> +            uint32_t elemSize = getTypeBitSize(unit, elemTy);
> +            uint32_t padding = getPadding(elemSize, 8 * getAlignmentByte(unit, elemTy));
> +            padding /= 8;
> +            uint32_t ops = c->getNumOperands();
> +            for(uint32_t op = 0; op < ops; ++op) {
> +              Constant * ca = dyn_cast<Constant>(c->getOperand(op));
> +              getConstantData(ca, mem, offset);
> +              offset += padding;
> +            }
> +          }
> +          break;
> +        }
> +      case Type::TypeID::VectorTyID:
> +        {
> +          const ConstantDataSequential *cds = dyn_cast<ConstantDataSequential>(c);
> +          GBE_ASSERT(cds);
> +          getSequentialData(cds, mem, offset);
> +          break;
> +        }
> +      case Type::TypeID::IntegerTyID:
> +        {
> +          const ConstantInt *ci = dyn_cast<ConstantInt>(c);
> +          *(uint64_t *)((char*)mem + offset) = ci->isNegative() ? ci->getSExtValue() : ci->getZExtValue();
> +          offset += ci->getBitWidth() / 8;
> +          break;
> +        }
> +      case Type::TypeID::FloatTyID:
> +        {
> +          const ConstantFP *cf = dyn_cast<ConstantFP>(c);
> +          *(float *)((char*)mem + offset) = cf->getValueAPF().convertToFloat();
> +          offset += sizeof(float);
> +          break;
> +        }
> +      case Type::TypeID::DoubleTyID:
> +        {
> +          const ConstantFP *cf = dyn_cast<ConstantFP>(c);
> +          *(double *)((char*)mem + offset) = cf->getValueAPF().convertToDouble();
> +          offset += sizeof(double);
> +          break;
> +        }
> +      default:
> +        NOT_IMPLEMENTED;
> +    }
> +  }
>  
>    void GenWriter::collectGlobalConstant(void) const {
>      const Module::GlobalListType &globalList = TheModule->getGlobalList();
> @@ -569,68 +663,13 @@ namespace gbe
>        if(addrSpace == ir::AddressSpace::MEM_CONSTANT) {
>          GBE_ASSERT(v.hasInitializer());
>          const Constant *c = v.getInitializer();
> -        if (c->getType()->getTypeID() != Type::ArrayTyID) {
> -          void *mem = malloc(sizeof(double));
> -          int size = 0;
> -          switch(c->getType()->getTypeID()) {
> -            case Type::TypeID::IntegerTyID: {
> -              const ConstantInt *ci = dyn_cast<ConstantInt>(c);
> -              *(uint64_t *)mem = ci->isNegative() ? ci->getSExtValue() : ci->getZExtValue();
> -              size = ci->getBitWidth() / 8;
> -              break;
> -            }
> -            case Type::TypeID::FloatTyID: {
> -              const ConstantFP *cf = dyn_cast<ConstantFP>(c);
> -              *(float *)mem = cf->getValueAPF().convertToFloat();
> -              size = sizeof(float);
> -              break;
> -            }
> -            case Type::TypeID::DoubleTyID: {
> -              const ConstantFP *cf = dyn_cast<ConstantFP>(c);
> -              *(double *)mem = cf->getValueAPF().convertToDouble();
> -              size = sizeof(double);
> -              break;
> -            }
> -            default:
> -              NOT_IMPLEMENTED;
> -          }
> -          unit.newConstant((char *)mem, name, size, size);
> -          free(mem);
> -          continue;
> -        }
> -        GBE_ASSERT(c->getType()->getTypeID() == Type::ArrayTyID);
> -        const ConstantDataArray *cda = dyn_cast<ConstantDataArray>(c);
> -        GBE_ASSERT(cda);
> -        unsigned len = cda->getNumElements();
> -        uint64_t elementSize = cda->getElementByteSize();
> -        Type::TypeID typeID = cda->getElementType()->getTypeID();
> -        void *mem = malloc(elementSize * len);
> -        for(unsigned j = 0; j < len; j ++) {
> -          switch(typeID) {
> -            case Type::TypeID::FloatTyID:
> -             {
> -              float f = cda->getElementAsFloat(j);
> -              memcpy((float *)mem + j, &f, elementSize);
> -             }
> -              break;
> -            case Type::TypeID::DoubleTyID:
> -             {
> -              double d = cda->getElementAsDouble(j);
> -              memcpy((double *)mem + j, &d, elementSize);
> -             }
> -              break;
> -            case Type::TypeID::IntegerTyID:
> -             {
> -              uint64_t u = (uint64_t) cda->getElementAsInteger(j);
> -              memcpy((char *)mem + j*elementSize, &u, elementSize);
> -             }
> -              break;
> -            default:
> -              NOT_IMPLEMENTED;
> -          }
> -        }
> +        Type * type = c->getType();
>  
> -        unit.newConstant((char *)mem, name, elementSize * len, sizeof(unsigned));
> +        uint32_t size = getTypeByteSize(unit, type);
> +        void* mem = malloc(size);
> +        uint32_t offset = 0;
> +        getConstantData(c, mem, offset);
> +        unit.newConstant((char *)mem, name, size, sizeof(unsigned));
>          free(mem);
>        }
>      }
> @@ -818,18 +857,38 @@ namespace gbe
>          return ir::Register(reg);
>        }
>        if (isa<ConstantExpr>(CPV)) {
> +        uint32_t TypeIndex;
> +        uint32_t constantOffset = 0;
> +        uint32_t offset = 0;
>          ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV);
> -        GBE_ASSERT(CE->isGEPWithNoNotionalOverIndexing());
> -        auto pointer = CE->getOperand(0);
> -        auto offset1 = dyn_cast<ConstantInt>(CE->getOperand(1));
> -        GBE_ASSERT(offset1->getZExtValue() == 0);
> -        auto offset2 = dyn_cast<ConstantInt>(CE->getOperand(2));
> -        int type_size = pointer->getType()->getPrimitiveSizeInBits() / 8;
> -        int type_offset = offset2->getSExtValue() * type_size;
> -        auto pointer_name = pointer->getName().str();
> +
> +        // currently only GetElementPtr is handled
> +        GBE_ASSERT(CE->getOpcode() == Instruction::GetElementPtr);
> +        Value *pointer = CE->getOperand(0);
> +        CompositeType* CompTy = cast<CompositeType>(pointer->getType());
> +        for(uint32_t op=1; op<CE->getNumOperands(); ++op) {
> +          ConstantInt* ConstOP = dyn_cast<ConstantInt>(CE->getOperand(op));
> +          GBE_ASSERT(ConstOP);
> +          TypeIndex = ConstOP->getZExtValue();
> +          for(uint32_t ty_i=0; ty_i<TypeIndex; ty_i++)
> +          {
> +            Type* elementType = CompTy->getTypeAtIndex(ty_i);
> +            uint32_t align = getAlignmentByte(unit, elementType);
> +            offset += getPadding(offset, align);
> +            offset += getTypeByteSize(unit, elementType);
> +          }
> +
> +          const uint32_t align = getAlignmentByte(unit, CompTy->getTypeAtIndex(TypeIndex));
> +          offset += getPadding(offset, align);
> +
> +          constantOffset += offset;
> +          CompTy = dyn_cast<CompositeType>(CompTy->getTypeAtIndex(TypeIndex));
> +        }
> +
> +        const std::string &pointer_name = pointer->getName().str();
>          ir::Register pointer_reg = ir::Register(unit.getConstantSet().getConstant(pointer_name).getReg());
>          ir::Register offset_reg = ctx.reg(ir::RegisterFamily::FAMILY_DWORD);
> -        ctx.LOADI(ir::Type::TYPE_S32, offset_reg, ctx.newIntegerImmediate(type_offset, ir::Type::TYPE_S32));
> +        ctx.LOADI(ir::Type::TYPE_S32, offset_reg, ctx.newIntegerImmediate(constantOffset, ir::Type::TYPE_S32));
>          ir::Register reg = ctx.reg(ir::RegisterFamily::FAMILY_DWORD);
>          ctx.ADD(ir::Type::TYPE_S32, reg, pointer_reg, offset_reg);
>          return reg;
> -- 
> 1.7.9.5
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list