aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2023-02-22 17:05:33 +0100
committerNikita Popov <npopov@redhat.com>2023-02-27 10:57:53 +0100
commit0805d9d5aa904ffa110ee0527f7ea190e3e2c321 (patch)
treed4d4408ade0bfc48925340203087afefe6825c6f /llvm/lib
parent95c3c2b8570d307ad91c603856336acf32e5021f (diff)
downloadllvm-0805d9d5aa904ffa110ee0527f7ea190e3e2c321.zip
llvm-0805d9d5aa904ffa110ee0527f7ea190e3e2c321.tar.gz
llvm-0805d9d5aa904ffa110ee0527f7ea190e3e2c321.tar.bz2
[SCEV] Make scalable size representation more explicit
Represent scalable type sizes using C * vscale, where vscale is the vscale constant expression. This exposes a bit more information to SCEV, because the vscale multiplier is explicitly modeled in SCEV (rather than part of the sizeof expression). This is mainly intended as an alternative to D143642. Differential Revision: https://reviews.llvm.org/D144624
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp56
1 files changed, 18 insertions, 38 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 96cc518..a820879 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -368,9 +368,8 @@ void SCEV::print(raw_ostream &OS) const {
}
case scUnknown: {
const SCEVUnknown *U = cast<SCEVUnknown>(this);
- Type *AllocTy;
- if (U->isSizeOf(AllocTy)) {
- OS << "sizeof(" << *AllocTy << ")";
+ if (U->isVScale()) {
+ OS << "vscale";
return;
}
@@ -561,20 +560,8 @@ void SCEVUnknown::allUsesReplacedWith(Value *New) {
setValPtr(New);
}
-bool SCEVUnknown::isSizeOf(Type *&AllocTy) const {
- if (ConstantExpr *VCE = dyn_cast<ConstantExpr>(getValue()))
- if (VCE->getOpcode() == Instruction::PtrToInt)
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(VCE->getOperand(0)))
- if (CE->getOpcode() == Instruction::GetElementPtr &&
- CE->getOperand(0)->isNullValue() &&
- CE->getNumOperands() == 2)
- if (ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(1)))
- if (CI->isOne()) {
- AllocTy = cast<GEPOperator>(CE)->getSourceElementType();
- return true;
- }
-
- return false;
+bool SCEVUnknown::isVScale() const {
+ return match(getValue(), m_VScale());
}
//===----------------------------------------------------------------------===//
@@ -4326,33 +4313,26 @@ const SCEV *ScalarEvolution::getUMinExpr(SmallVectorImpl<const SCEV *> &Ops,
}
const SCEV *
-ScalarEvolution::getSizeOfScalableVectorExpr(Type *IntTy,
- ScalableVectorType *ScalableTy) {
- Constant *NullPtr = Constant::getNullValue(ScalableTy->getPointerTo());
- Constant *One = ConstantInt::get(IntTy, 1);
- Constant *GEP = ConstantExpr::getGetElementPtr(ScalableTy, NullPtr, One);
- // Note that the expression we created is the final expression, we don't
- // want to simplify it any further Also, if we call a normal getSCEV(),
- // we'll end up in an endless recursion. So just create an SCEVUnknown.
- return getUnknown(ConstantExpr::getPtrToInt(GEP, IntTy));
+ScalarEvolution::getSizeOfExpr(Type *IntTy, TypeSize Size) {
+ const SCEV *Res = getConstant(IntTy, Size.getKnownMinValue());
+ if (Size.isScalable()) {
+ // TODO: Why is there no ConstantExpr::getVScale()?
+ Type *SrcElemTy = ScalableVectorType::get(Type::getInt8Ty(getContext()), 1);
+ Constant *NullPtr = Constant::getNullValue(SrcElemTy->getPointerTo());
+ Constant *One = ConstantInt::get(IntTy, 1);
+ Constant *GEP = ConstantExpr::getGetElementPtr(SrcElemTy, NullPtr, One);
+ Constant *VScale = ConstantExpr::getPtrToInt(GEP, IntTy);
+ Res = getMulExpr(Res, getUnknown(VScale));
+ }
+ return Res;
}
const SCEV *ScalarEvolution::getSizeOfExpr(Type *IntTy, Type *AllocTy) {
- if (auto *ScalableAllocTy = dyn_cast<ScalableVectorType>(AllocTy))
- return getSizeOfScalableVectorExpr(IntTy, ScalableAllocTy);
- // We can bypass creating a target-independent constant expression and then
- // folding it back into a ConstantInt. This is just a compile-time
- // optimization.
- return getConstant(IntTy, getDataLayout().getTypeAllocSize(AllocTy));
+ return getSizeOfExpr(IntTy, getDataLayout().getTypeAllocSize(AllocTy));
}
const SCEV *ScalarEvolution::getStoreSizeOfExpr(Type *IntTy, Type *StoreTy) {
- if (auto *ScalableStoreTy = dyn_cast<ScalableVectorType>(StoreTy))
- return getSizeOfScalableVectorExpr(IntTy, ScalableStoreTy);
- // We can bypass creating a target-independent constant expression and then
- // folding it back into a ConstantInt. This is just a compile-time
- // optimization.
- return getConstant(IntTy, getDataLayout().getTypeStoreSize(StoreTy));
+ return getSizeOfExpr(IntTy, getDataLayout().getTypeStoreSize(StoreTy));
}
const SCEV *ScalarEvolution::getOffsetOfExpr(Type *IntTy,