Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple commits from AS branch that are independent #264

Merged
merged 14 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
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
6 changes: 4 additions & 2 deletions llvm/include/llvm/Cheerp/Utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ inline bool isValidVoidPtrSource(const llvm::Value* val)

inline llvm::Type* getElementType(llvm::Type* t, llvm::Type* candidate)
{
if(llvm::isa<llvm::PointerType>(t))
if(auto* pt = llvm::dyn_cast<llvm::PointerType>(t))
{
assert(candidate && candidate->getPointerTo() == t);
assert(candidate && candidate->getPointerTo(pt->getAddressSpace()) == pt);
return candidate;
}
else if (t->isVectorTy())
Expand Down Expand Up @@ -251,6 +251,8 @@ inline bool isBitCast(const llvm::Value* v)
{
if( llvm::isa< llvm::BitCastInst>(v) )
return true;
if( llvm::isa< llvm::AddrSpaceCastInst>(v) )
return true;
if(const llvm::ConstantExpr * ce = llvm::dyn_cast<llvm::ConstantExpr>(v) )
return ce->getOpcode() == llvm::Instruction::BitCast;
if(const llvm::IntrinsicInst* II=llvm::dyn_cast<llvm::IntrinsicInst>(v))
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/CheerpUtils/AllocaMerging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,9 @@ bool AllocaArraysMerging::runOnFunction(Function& F, cheerp::PointerAnalyzer& PA
Instruction* insertionPoint = nullptr;
for(auto it: arraysToMerge)
insertionPoint = cheerp::findCommonInsertionPoint(nullptr, DT, insertionPoint, it.first);
AllocaInst* newAlloca = new AllocaInst(newAllocaType, 0, "mergedArray", insertionPoint);
// TODO: make sure that all the arrays to merge have the same AS
unsigned AS = arraysToMerge.begin()->first->getAddressSpace();
AllocaInst* newAlloca = new AllocaInst(newAllocaType, AS, "mergedArray", insertionPoint);
Type* indexType = IntegerType::get(newAllocaType->getContext(), 32);
// Change every use of every merged array with an appropiate GEP
for(auto it: arraysToMerge)
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CheerpUtils/CallConstructors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ PreservedAnalyses CallConstructorsPass::run(llvm::Module &M, llvm::ModuleAnalysi

for (Constant* C: cheerp::getGlobalConstructors(M))
{
Builder.CreateCall(Ty, cast<Function>(C->getAggregateElement(1)));
Builder.CreateCall(Ty, cast<Function>(C->getAggregateElement(1)->stripPointerCastsSafe()));
}
Function* Main = getMainFunction(M);
bool Wasi = Triple(M.getTargetTriple()).getOS() == Triple::WASI;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CheerpUtils/PointerPasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ bool AllocaArrays::replaceAlloca(AllocaInst* ai, cheerp::GlobalDepsAnalyzer& gda
}

llvm::Type * at = llvm::ArrayType::get( ai->getAllocatedType(), ci->getZExtValue() );
AllocaInst * newAi = new AllocaInst( at, 0, nullptr, ai->getAlign() );
AllocaInst * newAi = new AllocaInst( at, ai->getAddressSpace(), nullptr, ai->getAlign() );
newAi->insertAfter( ai );
ai->removeFromParent();
newAi->takeName(ai);
Expand Down
24 changes: 13 additions & 11 deletions llvm/lib/CheerpUtils/StructMemFuncLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void StructMemFuncLowering::recursiveCopy(IRBuilder<>* IRB, Value* baseDst, Valu
// For aggregates we push a new index and overwrite it for each element
if(StructType* ST=dyn_cast<StructType>(curType))
{
assert(baseDst->getType() == containingType->getPointerTo());
assert(baseDst->getType() == containingType->getPointerTo(baseDst->getType()->getPointerAddressSpace()));
if (ST->hasByteLayout())
return createMemFunc(IRB, baseDst, baseSrc, containingType, DL->getTypeAllocSize(curType), indexes);
indexes.push_back(NULL);
Expand Down Expand Up @@ -100,13 +100,13 @@ void StructMemFuncLowering::recursiveCopy(IRBuilder<>* IRB, Value* baseDst, Valu
Value* elementSrc = baseSrc;
Value* elementDst = baseDst;

assert(baseSrc->getType() == containingType->getPointerTo());
assert(baseSrc->getType() == containingType->getPointerTo(baseSrc->getType()->getPointerAddressSpace()));
assert(baseSrc->getType() == baseDst->getType());
elementSrc = IRB->CreateGEP(containingType, baseSrc, indexes);
elementDst = IRB->CreateGEP(containingType, baseDst, indexes);

Type* loadType = GetElementPtrInst::getIndexedType(containingType, indexes);
assert(loadType->getPointerTo() == elementSrc->getType());
assert(loadType->getPointerTo(elementSrc->getType()->getPointerAddressSpace()) == elementSrc->getType());

Instruction* element = IRB->CreateAlignedLoad(loadType, elementSrc, MaybeAlign(baseAlign));
MDNode* newAliasScope = NULL;
Expand Down Expand Up @@ -187,7 +187,7 @@ void StructMemFuncLowering::recursiveReset(IRBuilder<>* IRB, Value* baseDst, Val
computedResetVal=IRB->CreateShl(computedResetVal, 8);
computedResetVal=IRB->CreateOr(computedResetVal, expandedResetVal);
}
assert(containingType->getPointerTo() == baseDst->getType());
assert(containingType->getPointerTo(baseDst->getType()->getPointerAddressSpace()) == baseDst->getType());
Value* elementDst = IRB->CreateGEP(containingType, baseDst, indexes);
IRB->CreateAlignedStore(computedResetVal, elementDst, MaybeAlign(baseAlign));
}
Expand All @@ -208,7 +208,7 @@ void StructMemFuncLowering::recursiveReset(IRBuilder<>* IRB, Value* baseDst, Val
Function* splatIntrinsic = Intrinsic::getDeclaration(BB->getModule(), Intrinsic::cheerp_wasm_splat, argTypes);
computedResetVal = IRB->CreateCall(splatIntrinsic, { resetVal });
}
assert(containingType->getPointerTo() == baseDst->getType());
assert(containingType->getPointerTo(baseDst->getType()->getPointerAddressSpace()) == baseDst->getType());
Value* elementDst = IRB->CreateGEP(containingType, baseDst, indexes);
IRB->CreateAlignedStore(computedResetVal, elementDst, MaybeAlign(baseAlign));
}
Expand All @@ -229,7 +229,7 @@ void StructMemFuncLowering::recursiveReset(IRBuilder<>* IRB, Value* baseDst, Val
floatResetVal = ConstantFP::get(curType->getContext(), APFloat(APFloat::IEEEsingle(), floatConstant));
else
floatResetVal = ConstantFP::get(curType->getContext(), APFloat(APFloat::IEEEdouble(), floatConstant));
assert(containingType->getPointerTo() == baseDst->getType());
assert(containingType->getPointerTo(baseDst->getType()->getPointerAddressSpace()) == baseDst->getType());
Value* elementDst = IRB->CreateGEP(containingType, baseDst, indexes);
IRB->CreateAlignedStore(floatResetVal, elementDst, MaybeAlign(baseAlign));
}
Expand All @@ -238,7 +238,7 @@ void StructMemFuncLowering::recursiveReset(IRBuilder<>* IRB, Value* baseDst, Val
// Only constant NULL is supported
// TODO: Stop non constant in the frontend
assert(cast<ConstantInt>( resetVal )->getZExtValue() == 0);
assert(containingType->getPointerTo() == baseDst->getType());
assert(containingType->getPointerTo(baseDst->getType()->getPointerAddressSpace()) == baseDst->getType());
Value* elementDst = IRB->CreateGEP(containingType, baseDst, indexes);
IRB->CreateAlignedStore(ConstantPointerNull::get(PT), elementDst, MaybeAlign(baseAlign));
}
Expand Down Expand Up @@ -277,16 +277,17 @@ void StructMemFuncLowering::createGenericLoop(IRBuilder<>* IRB, BasicBlock* prev
PHINode* dstPHI = NULL;
Value* srcVal = src;
Value* dstVal = dst;
unsigned AS = dst->getType()->getPointerAddressSpace();

if(needsLoop)
{
if(mode != MEMSET)
{
srcPHI = IRB->CreatePHI(pointedType->getPointerTo(), 2);
srcPHI = IRB->CreatePHI(pointedType->getPointerTo(AS), 2);
srcPHI->addIncoming(src, previousBlock);
srcVal = srcPHI;
}
dstPHI = IRB->CreatePHI(pointedType->getPointerTo(), 2);
dstPHI = IRB->CreatePHI(pointedType->getPointerTo(AS), 2);
dstPHI->addIncoming(dst, previousBlock);
dstVal = dstPHI;
baseAlign = DL->getABITypeAlignment(pointedType);
Expand Down Expand Up @@ -439,6 +440,7 @@ bool StructMemFuncLowering::runOnBlock(BasicBlock& BB, bool asmjs)
//In MEMSET mode src is the value to be written
Value* src=CI->getOperand(1);
Value* size=CI->getOperand(2);
unsigned AS = dst->getType()->getPointerAddressSpace();
Type* int32Type = IntegerType::get(BB.getContext(), 32);
assert(alignInt != 0);
// Do not inline memory intrinsics with a large or non-constant size
Expand Down Expand Up @@ -497,10 +499,10 @@ bool StructMemFuncLowering::runOnBlock(BasicBlock& BB, bool asmjs)
elemSize = sizeInt - (sizeInt % elemSize);
}
IRBuilder<> IRB(CI);
dst = IRB.CreateBitCast(dst, pointedType->getPointerTo());
dst = IRB.CreateBitCast(dst, pointedType->getPointerTo(AS));
// In MEMSET mode src is the i8 value to write
if(mode != MEMSET)
src = IRB.CreateBitCast(src, pointedType->getPointerTo());
src = IRB.CreateBitCast(src, pointedType->getPointerTo(AS));
// We have found a good alignment above, check if we need to split the intrinsic to deal with an unaligned tail
if(uint32_t tailSize = sizeInt % elemSize) {
IRBuilder<> IRB(CI->getNextNode());
Expand Down
10 changes: 5 additions & 5 deletions llvm/lib/CheerpUtils/TypeOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -749,12 +749,12 @@ TypeOptimizer::TypeMappingInfo TypeOptimizer::rewriteType(Type* t)
if(newType->isArrayTy())
{
// It's never a good idea to use pointers to array, we may end up creating wrapper arrays for arrays
return CacheAndReturn(PointerType::get(newType->getArrayElementType(), 0), TypeMappingInfo::POINTER_FROM_ARRAY);
return CacheAndReturn(PointerType::get(newType->getArrayElementType(), pt->getAddressSpace()), TypeMappingInfo::POINTER_FROM_ARRAY);
}
else if(newType == elementType)
return CacheAndReturn(pt, TypeMappingInfo::IDENTICAL);
else
return CacheAndReturn(PointerType::get(newType, 0), TypeMappingInfo::IDENTICAL);
return CacheAndReturn(PointerType::get(newType, pt->getPointerAddressSpace()), TypeMappingInfo::IDENTICAL);
}
if(ArrayType* at=dyn_cast<ArrayType>(t))
{
Expand Down Expand Up @@ -1478,7 +1478,7 @@ Function* TypeOptimizer::rewriteFunctionSignature(Function* F)
F->setAttributes(PAL);

// Create the new function body and insert it into the module.
Function *NF = Function::Create(newFuncType, F->getLinkage(), F->getName());
Function *NF = Function::Create(newFuncType, F->getLinkage(), F->getAddressSpace(), F->getName());
NF->copyAttributesFrom(F);
NF->copyMetadata(F, 0);

Expand Down Expand Up @@ -2070,7 +2070,7 @@ void TypeOptimizer::rewriteFunction(Function* F)
{
// In this case we need to rewrite the allocated type and use that directly
// Moreover, we need to generate a GEP that will be used instead of this alloca
Type* newPtrType = PointerType::get(newAllocatedType, 0);
Type* newPtrType = PointerType::get(newAllocatedType, AI->getAddressSpace());
I.mutateType(newPtrType);
Type* Int32 = IntegerType::get(I.getType()->getContext(), 32);
Value* Zero = ConstantInt::get(Int32, 0);
Expand Down Expand Up @@ -2192,7 +2192,7 @@ Constant* TypeOptimizer::rewriteGlobal(GlobalVariable* GV)
if(newInfo.elementMappingKind == TypeMappingInfo::POINTER_FROM_ARRAY)
{
Type* newAllocatedType = rewriteType(GV->getValueType());
Type* newPtrType = PointerType::get(newAllocatedType, 0);
Type* newPtrType = PointerType::get(newAllocatedType, GV->getAddressSpace());
GV->mutateType(newPtrType);
Type* Int32 = IntegerType::get(GV->getType()->getContext(), 32);
Value* Zero = ConstantInt::get(Int32, 0);
Expand Down
11 changes: 9 additions & 2 deletions llvm/lib/CheerpUtils/Utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ bool InlineableCache::isInlineableImpl(const Instruction& I)
// Split regular, regular, and byte layout are always inlined.
return true;
}
else if(I.getOpcode()==Instruction::BitCast)
else if(I.getOpcode()==Instruction::BitCast || I.getOpcode()==Instruction::AddrSpaceCast)
{
if (!I.getType()->isPointerTy())
{
Expand Down Expand Up @@ -388,6 +388,7 @@ bool InlineableCache::isInlineableImpl(const Instruction& I)
// Reached the direct user
if(!nextInst->hasOneUse() &&
(nextInst->getOpcode() == Instruction::BitCast ||
nextInst->getOpcode() == Instruction::AddrSpaceCast ||
nextInst->getOpcode() == Instruction::Trunc))
{
// Avoid interacting with the bitcast/trunc logic for now
Expand Down Expand Up @@ -1224,6 +1225,12 @@ bool replaceCallOfBitCastWithBitCastOfCall(CallBase& callInst, bool mayFail, boo
assert(performPtrIntConversions);
return new PtrToIntInst(src, newType, "", insertPoint);
} else if(oldType->isPointerTy() && newType->isPointerTy()) {
if (oldType->getPointerAddressSpace() != newType->getPointerAddressSpace()) {
oldType = PointerType::getWithSamePointeeType(cast<PointerType>(oldType), newType->getPointerAddressSpace());
src = new AddrSpaceCastInst(src, oldType, "", insertPoint);
if (oldType == newType)
return src;
}
return new BitCastInst(src, newType, "", insertPoint);
} else if(oldType->isIntegerTy() && newType->isIntegerTy()) {
if(oldType->getIntegerBitWidth() < newType->getIntegerBitWidth())
Expand All @@ -1248,7 +1255,7 @@ bool replaceCallOfBitCastWithBitCastOfCall(CallBase& callInst, bool mayFail, boo
return false;
}

if (bitCast->getOpcode() != Instruction::BitCast)
if (bitCast->getOpcode() != Instruction::BitCast && bitCast->getOpcode() != Instruction::AddrSpaceCast)
{
assert(mayFail && "ConstantExpr BitCast expected");
return false;
Expand Down
11 changes: 5 additions & 6 deletions llvm/lib/CheerpWriter/CheerpWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2033,9 +2033,8 @@ void CheerpWriter::compilePointerBaseTyped(const Value* p, Type* elementType, bo
if(kind == RAW)
{
assert(isa<PointerType>(p->getType()));
Type* ty = llvm::cast<PointerType>(p->getType())->getPointerElementType();
if (isWasmTarget)
compileHeapForType(ty);
compileHeapForType(elementType);
else
stream << "nullArray";
return;
Expand Down Expand Up @@ -3424,7 +3423,7 @@ void CheerpWriter::compileGEPBase(const llvm::User* gep_inst, bool forEscapingPo
return;
}
compileCompleteObject(gep_inst->getOperand(0), indices.front());
Type* basePointedType = basePointerType->getPointerElementType();
Type* basePointedType = cast<GEPOperator>(gep_inst)->getSourceElementType();
if (useDownCastArray)
{
compileAccessToElement(basePointedType, makeArrayRef(std::next(indices.begin()),indices.end()), /*compileLastWrapperArray*/true);
Expand Down Expand Up @@ -3573,7 +3572,7 @@ void CheerpWriter::compileGEPOffset(const llvm::User* gep_inst, PARENT_PRIORITY
{
if (useDownCastArray)
{
Type* basePointedType = basePointerType->getPointerElementType();
Type* basePointedType = cast<GEPOperator>(gep_inst)->getSourceElementType();
compileCompleteObject(gep_inst->getOperand(0), indices.front());
compileAccessToElement(basePointedType, makeArrayRef(std::next(indices.begin()), indices.end()), /*compileLastWrapperArray*/true);
stream << ".o";
Expand Down Expand Up @@ -4671,7 +4670,7 @@ void CheerpWriter::compileLoadElem(const LoadInst& li, Type* Ty, StructType* STy
compileCompleteObject(ptrOp);
if(STy)
{
compileAccessToElement(STy, {ConstantInt::get(IntegerType::get(Ty->getContext(), 32), structElemIdx)}, false);
compileAccessToElement(STy, {ConstantInt::get(IntegerType::get(Ty->getContext(), 32), structElemIdx)}, true);
}
if(isOffset)
stream << 'o';
Expand Down Expand Up @@ -4821,7 +4820,7 @@ void CheerpWriter::compileStoreElem(const StoreInst& si, Type* Ty, StructType* S
compileCompleteObject(ptrOp);
if(STy)
{
compileAccessToElement(STy, {ConstantInt::get(IntegerType::get(Ty->getContext(), 32), structElemIdx)}, false);
compileAccessToElement(STy, {ConstantInt::get(IntegerType::get(Ty->getContext(), 32), structElemIdx)}, true);
}
if(isOffset)
stream << 'o';
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CheerpWriter/PreExecute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,7 @@ Constant* PreExecute::findPointerFromGlobal(const DataLayout* DL,
if (!typeFound)
return NULL;
Constant* GEP = ConstantExpr::getGetElementPtr(GV->getValueType(), GV, Indices);
assert(GEP->getType() == typeFound->getPointerTo());
assert(GEP->getType() == typeFound->getPointerTo(GEP->getType()->getPointerAddressSpace()));
if(GEP->getType() != memType)
return ConstantExpr::getBitCast(GEP, memType);
return GEP;
Expand Down
Loading
Loading