[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