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 <[email protected]> > --- > 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 > [email protected] > http://lists.freedesktop.org/mailman/listinfo/beignet _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
