Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
145 changes: 34 additions & 111 deletions llvm/lib/CheerpUtils/SIMDLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,23 @@ struct SIMDLoweringVisitor: public InstVisitor<SIMDLoweringVisitor, VectorParts>
const FixedVectorType* vecType = cast<FixedVectorType>(I.getType());
Type* elType = vecType->getElementType();
const unsigned num = vecType->getNumElements();
VectorParts p = visitValue(I.getOperand(0));
assert(p.values[0]->getType() == elType->getPointerTo() &&
p.values.size() == num);
VectorParts p = visitValue(I.getPointerOperand());
IRBuilder<> Builder(&I);

// If the operand hasn't been lowered, we have to do a bitcast and some geps.
if (p.values.size() == 0)
{
Value* bitcast = Builder.CreateBitCast(I.getPointerOperand(), elType->getPointerTo());
p.values.push_back(bitcast);
for (unsigned i = 1; i < num; i++)
{
Value* index[] = {ConstantInt::get(Int32Ty, i)};
Value* gep = Builder.CreateInBoundsGEP(elType, bitcast, index);
p.values.push_back(gep);
}
}

VectorParts result;
IRBuilder<> Builder(&I);
for (unsigned i = 0; i < num; i++)
{
Value* load = Builder.CreateLoad(elType, p.values[i]);
Expand All @@ -123,12 +134,26 @@ struct SIMDLoweringVisitor: public InstVisitor<SIMDLoweringVisitor, VectorParts>
return VectorParts();

const FixedVectorType* vecType = cast<FixedVectorType>(I.getValueOperand()->getType());
Type* elType = vecType->getElementType();
const unsigned num = vecType->getNumElements();
VectorParts v = visitValue(I.getValueOperand());
VectorParts p = visitValue(I.getPointerOperand());
IRBuilder<> Builder(&I);

// If the pointer operand was not lowered, we have to do a bitcast and some geps.
if (p.values.size() == 0)
{
Value* bitcast = Builder.CreateBitCast(I.getPointerOperand(), elType->getPointerTo());
p.values.push_back(bitcast);
for (unsigned i = 1; i < num; i++)
{
Value* index[] = {ConstantInt::get(Int32Ty, i)};
Value* gep = Builder.CreateInBoundsGEP(elType, bitcast, index);
p.values.push_back(gep);
}
}

VectorParts result;
IRBuilder<> Builder(&I);
for (unsigned i = 0; i < num; i++)
{
Value* store = Builder.CreateStore(v.values[i], p.values[i]);
Expand All @@ -141,34 +166,6 @@ struct SIMDLoweringVisitor: public InstVisitor<SIMDLoweringVisitor, VectorParts>

VectorParts visitBitCastInst(BitCastInst& I)
{
if (I.getDestTy()->isPointerTy())
{
const Type* pointedType = I.getDestTy()->getPointerElementType();
if (!shouldLower(pointedType))
return VectorParts();

// If we're casting to a pointer to a vector, instead create
// pointers to the separate elements.
const FixedVectorType* vecType = cast<FixedVectorType>(pointedType);
const unsigned num = vecType->getNumElements();
Type* elType = vecType->getElementType()->getPointerTo();
IRBuilder<> Builder(&I);
VectorParts result;
Value* firstValue = I.getOperand(0);
if (elType != firstValue->getType())
firstValue = Builder.CreateBitCast(firstValue, elType);
result.values.push_back(firstValue);

for (unsigned i = 1; i < num; i++)
{
Value* index[] = {ConstantInt::get(Int32Ty, i)};
Value* gep = Builder.CreateInBoundsGEP(vecType->getElementType(), firstValue, index);
result.values.push_back(gep);
}
toDelete.push_back(&I);
changed = true;
return result;
}
if (!shouldLower(I.getDestTy()) && !shouldLower(I.getSrcTy()))
return VectorParts();

Expand Down Expand Up @@ -379,10 +376,10 @@ struct SIMDLoweringVisitor: public InstVisitor<SIMDLoweringVisitor, VectorParts>

VectorParts visitAllocaInst(AllocaInst& I)
{
if (!shouldLower(I.getType()->getPointerElementType()))
if (!shouldLower(I.getAllocatedType()))
return VectorParts();

const FixedVectorType* vecType = cast<FixedVectorType>(I.getType()->getPointerElementType());
const FixedVectorType* vecType = cast<FixedVectorType>(I.getAllocatedType());
Type* newType = vecType->getElementType();
unsigned amount = vecType->getNumElements();
IRBuilder<> Builder(&I);
Expand Down Expand Up @@ -532,70 +529,11 @@ struct SIMDLoweringVisitor: public InstVisitor<SIMDLoweringVisitor, VectorParts>
return result;
}

Type* recursiveCreateType(Type* originalType)
{
Type* newType = originalType;
if (const FixedVectorType* vecType = dyn_cast<FixedVectorType>(originalType))
newType = ArrayType::get(vecType->getElementType(), vecType->getNumElements());
else if (const ArrayType* arrayType = dyn_cast<ArrayType>(originalType))
{
Type* subType = recursiveCreateType(arrayType->getElementType());
newType = ArrayType::get(subType, arrayType->getNumElements());
}
else if (const StructType* structType = dyn_cast<StructType>(originalType))
{
SmallVector<Type*, 4> subTypes;
for (unsigned i = 0; i < structType->getNumElements(); i++)
subTypes.push_back(recursiveCreateType(structType->getElementType(i)));
newType = StructType::get(context, subTypes);
}
return newType;
};

VectorParts visitGetElementPtrInst(GetElementPtrInst& I)
{
if (!I.getType()->isVectorTy() && !(I.getType()->isPointerTy() && I.getType()->getPointerElementType()->isVectorTy()))
if (!I.getType()->isVectorTy())
return VectorParts();

if (I.getType()->isPointerTy())
{
const FixedVectorType* vecType = cast<FixedVectorType>(I.getType()->getPointerElementType());
if (!lowerAll && cheerp::getVectorBitwidth(vecType) <= 128)
return VectorParts();

// This is a pointer to a vector. We lower this to several GEPs to the first element.
const unsigned num = vecType->getNumElements();
Type* elementType = vecType->getElementType();
Type* arrayType = ArrayType::get(elementType, num);

// Has the pointed operand been lowered?
VectorParts v = visitValue(I.getPointerOperand());
Value* pointerOp = I.getPointerOperand();
Value* bitcastBase = pointerOp;
if (v.values.size() > 0)
bitcastBase = v.values[0];

// Create a bitcast to a new type that has an array instead of a vector for the innermost part.
IRBuilder<> Builder(&I);
Type* newType = recursiveCreateType(pointerOp->getType()->getPointerElementType());
Value* bitcast = Builder.CreateBitCast(bitcastBase, newType->getPointerTo());
// Create a new GEP using the same indices as before.
SmallVector<Value*, 4> indices;
for (auto it = I.idx_begin(); it != I.idx_end(); it++)
indices.push_back(*it);
Value* gep = Builder.CreateInBoundsGEP(newType, bitcast, indices);

// Now we create GEPs into this latest GEP to get the elements.
VectorParts result;
for (unsigned i = 0; i < num; i++)
{
SmallVector<Value*, 4> index = { ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, i) };
result.values.push_back(Builder.CreateInBoundsGEP(arrayType, gep, index));
}
toDelete.push_back(&I);
changed = true;
return result;
}
const FixedVectorType* vecType = cast<FixedVectorType>(I.getType());
const unsigned num = vecType->getNumElements();
IRBuilder<> Builder(I.getNextNode());
Expand Down Expand Up @@ -1026,8 +964,7 @@ struct SIMDLoweringVisitor: public InstVisitor<SIMDLoweringVisitor, VectorParts>
if (it != cache.end())
return it->second;

if (!shouldLower(V->getType()) &&
!(V->getType()->isPointerTy() && shouldLower(V->getType()->getPointerElementType())))
if (!shouldLower(V->getType()))
return VectorParts();

VectorParts ret;
Expand Down Expand Up @@ -1064,20 +1001,6 @@ struct SIMDLoweringVisitor: public InstVisitor<SIMDLoweringVisitor, VectorParts>
for (unsigned i = 0; i < amount; i++)
ret.values.push_back(uvElement);
}
else if (ConstantExpr* ce = dyn_cast<ConstantExpr>(V))
{
const FixedVectorType* vecType = cast<FixedVectorType>(ce->getType()->getPointerElementType());
const unsigned num = vecType->getNumElements();
Type* elementType = vecType->getElementType()->getPointerTo();
Constant* bitcast = ConstantExpr::getBitCast(ce, elementType);
ret.values.push_back(bitcast);
for (unsigned i = 1; i < num; i++)
{
Value* index[] = {ConstantInt::get(Int32Ty, i)};
Value* gep = ConstantExpr::getGetElementPtr(vecType->getElementType(), bitcast, index);
ret.values.push_back(gep);
}
}
else
{
llvm::errs() << *V << "\n";
Expand Down
Loading