[PATCH] D89692: [SCEV] SCEVPtrToIntExpr simplifications
Roman Lebedev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 25 14:11:12 PDT 2020
lebedev.ri added a comment.
@efriedma does this look about right?
Speaking for myself, this isn't quite what i want to have in the end,
it should be closer to: (just so i don't loose the code)
const SCEV *ScalarEvolution::getPtrToIntExpr(const SCEV *Op, Type *Ty,
unsigned Depth) {
assert(Ty->isIntegerTy() && "Target type must be an integer type!");
assert(Depth <= 1 && "getPtrToIntExpr() should self-recurse at most once.");
// We could be called with an integer-typed operands during SCEV rewrites.
// Since the operand is an integer already, just perform zext/trunc/self cast.
if (!Op->getType()->isPointerTy())
return getTruncateOrZeroExtend(Op, Ty);
// What would be an ID for such a SCEV cast expression?
FoldingSetNodeID ID;
ID.AddInteger(scPtrToInt);
ID.AddPointer(Op);
void *IP = nullptr;
// Is there already an expression for such a cast?
if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP))
return getTruncateOrZeroExtend(S, Ty);
// If not, is this expression something we can't reduce any further?
if (isa<SCEVUnknown>(Op)) {
// Create an explicit cast node.
// We can reuse the existing insert position since if we get here,
// we won't have made any changes which would invalidate it.
Type *IntPtrTy = getDataLayout().getIntPtrType(Op->getType());
assert(getDataLayout().getTypeSizeInBits(getEffectiveSCEVType(
Op->getType())) == getDataLayout().getTypeSizeInBits(IntPtrTy) &&
"We can only model ptrtoint if SCEV's effective (integer) type is "
"sufficiently wide to represent all possible pointer values.");
SCEV *S = new (SCEVAllocator)
SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy);
UniqueSCEVs.InsertNode(S, IP);
addToLoopUseLists(S);
return getTruncateOrZeroExtend(S, Ty);
}
assert(Depth == 0 &&
"getPtrToIntExpr() should not self-recurse for non-SCEVUnknown's.");
// Otherwise, we've got some expression that is more complex than just a
// single SCEVUnknown. But we don't want to have a SCEVPtrToIntExpr of an
// arbitrary expression, we want to have SCEVPtrToIntExpr of an SCEVUnknown
// only, and the expressions must otherwise be integer-typed.
// So sink the cast down to the SCEVUnknown's.
/// The SCEVPtrToIntSinkingRewriter takes a scalar evolution expression,
/// which computes a pointer-typed value, and rewrites the whole expression
/// tree so that *all* the computations are done on integers, and the only
/// pointer-typed operands in the expression are SCEVUnknown.
class SCEVPtrToIntSinkingRewriter
: public SCEVRewriteVisitor<SCEVPtrToIntSinkingRewriter> {
using Base = SCEVRewriteVisitor<SCEVPtrToIntSinkingRewriter>;
public:
SCEVPtrToIntSinkingRewriter(ScalarEvolution &SE) : SCEVRewriteVisitor(SE) {}
static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE) {
SCEVPtrToIntSinkingRewriter Rewriter(SE);
return Rewriter.visit(Scev);
}
const SCEV *visit(const SCEV *S) {
Type *STy = S->getType();
// If the expression is not pointer-typed, just keep it as-is.
if (!STy->isPointerTy())
return S;
// Else, recursively sink the cast down into it.
return Base::visit(S);
}
const SCEV *visitUnknown(const SCEVUnknown *Expr) {
Type *ExprPtrTy = Expr->getType();
assert(ExprPtrTy->isPointerTy() &&
"Should only reach pointer-typed SCEVUnknown's.");
Type *ExprIntPtrTy = SE.getDataLayout().getIntPtrType(ExprPtrTy);
return SE.getPtrToIntExpr(Expr, ExprIntPtrTy, /*Depth=*/1);
}
};
// And actually perform the cast sinking.
const SCEV *IntOp = SCEVPtrToIntSinkingRewriter::rewrite(Op, *this);
assert(IntOp->getType()->isIntegerTy() &&
"We must have succeeded in sinking the cast, "
"and ending up with an integer-typed expression!");
return getTruncateOrZeroExtend(IntOp, Ty);
}
... but that requires SCEVRewriteVisitor changes so it doesn't loose no-wrap flags on add/mul,
(unlike AddRec, where it already preserves them),
but i would imagine the approach to that refactoring to be non-obvious,
so i would prefer not to block this on that, and do that as a follow-up..
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D89692/new/
https://reviews.llvm.org/D89692
More information about the llvm-commits
mailing list