Skip to content

Commit 02ba405

Browse files
committed
[SCEVExpander] Remove typed pointer support (NFC)
1 parent ab86b8c commit 02ba405

File tree

2 files changed

+52
-208
lines changed

2 files changed

+52
-208
lines changed

llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,8 +441,8 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
441441
/// Expand a SCEVAddExpr with a pointer type into a GEP instead of using
442442
/// ptrtoint+arithmetic+inttoptr.
443443
Value *expandAddToGEP(const SCEV *const *op_begin, const SCEV *const *op_end,
444-
PointerType *PTy, Type *Ty, Value *V);
445-
Value *expandAddToGEP(const SCEV *Op, PointerType *PTy, Type *Ty, Value *V);
444+
Type *Ty, Value *V);
445+
Value *expandAddToGEP(const SCEV *Op, Type *Ty, Value *V);
446446

447447
/// Find a previous Value in ExprValueMap for expand.
448448
Value *FindValueInExprValueMap(const SCEV *S, const Instruction *InsertPt);

llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp

Lines changed: 50 additions & 206 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) {
163163
"InsertNoopCastOfTo cannot change sizes!");
164164

165165
// inttoptr only works for integral pointers. For non-integral pointers, we
166-
// can create a GEP on i8* null with the integral value as index. Note that
166+
// can create a GEP on null with the integral value as index. Note that
167167
// it is safe to use GEP of null instead of inttoptr here, because only
168168
// expressions already based on a GEP of null should be converted to pointers
169169
// during expansion.
@@ -173,9 +173,8 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) {
173173
auto *Int8PtrTy = Builder.getInt8PtrTy(PtrTy->getAddressSpace());
174174
assert(DL.getTypeAllocSize(Builder.getInt8Ty()) == 1 &&
175175
"alloc size of i8 must by 1 byte for the GEP to be correct");
176-
auto *GEP = Builder.CreateGEP(
176+
return Builder.CreateGEP(
177177
Builder.getInt8Ty(), Constant::getNullValue(Int8PtrTy), V, "scevgep");
178-
return Builder.CreateBitCast(GEP, Ty);
179178
}
180179
}
181180
// Short-circuit unnecessary bitcasts.
@@ -451,212 +450,66 @@ static void SplitAddRecs(SmallVectorImpl<const SCEV *> &Ops,
451450
/// can be folded using target addressing modes.
452451
///
453452
Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
454-
const SCEV *const *op_end,
455-
PointerType *PTy,
456-
Type *Ty,
453+
const SCEV *const *op_end, Type *Ty,
457454
Value *V) {
458-
SmallVector<Value *, 4> GepIndices;
459455
SmallVector<const SCEV *, 8> Ops(op_begin, op_end);
460-
bool AnyNonZeroIndices = false;
461456

462457
// Split AddRecs up into parts as either of the parts may be usable
463458
// without the other.
464459
SplitAddRecs(Ops, Ty, SE);
465460

466-
Type *IntIdxTy = DL.getIndexType(PTy);
467-
468-
// For opaque pointers, always generate i8 GEP.
469-
if (!PTy->isOpaque()) {
470-
// Descend down the pointer's type and attempt to convert the other
471-
// operands into GEP indices, at each level. The first index in a GEP
472-
// indexes into the array implied by the pointer operand; the rest of
473-
// the indices index into the element or field type selected by the
474-
// preceding index.
475-
Type *ElTy = PTy->getNonOpaquePointerElementType();
476-
for (;;) {
477-
// If the scale size is not 0, attempt to factor out a scale for
478-
// array indexing.
479-
SmallVector<const SCEV *, 8> ScaledOps;
480-
if (ElTy->isSized()) {
481-
const SCEV *ElSize = SE.getSizeOfExpr(IntIdxTy, ElTy);
482-
if (!ElSize->isZero()) {
483-
SmallVector<const SCEV *, 8> NewOps;
484-
for (const SCEV *Op : Ops) {
485-
const SCEV *Remainder = SE.getConstant(Ty, 0);
486-
if (FactorOutConstant(Op, Remainder, ElSize, SE, DL)) {
487-
// Op now has ElSize factored out.
488-
ScaledOps.push_back(Op);
489-
if (!Remainder->isZero())
490-
NewOps.push_back(Remainder);
491-
AnyNonZeroIndices = true;
492-
} else {
493-
// The operand was not divisible, so add it to the list of
494-
// operands we'll scan next iteration.
495-
NewOps.push_back(Op);
496-
}
497-
}
498-
// If we made any changes, update Ops.
499-
if (!ScaledOps.empty()) {
500-
Ops = NewOps;
501-
SimplifyAddOperands(Ops, Ty, SE);
502-
}
503-
}
504-
}
505-
506-
// Record the scaled array index for this level of the type. If
507-
// we didn't find any operands that could be factored, tentatively
508-
// assume that element zero was selected (since the zero offset
509-
// would obviously be folded away).
510-
Value *Scaled =
511-
ScaledOps.empty()
512-
? Constant::getNullValue(Ty)
513-
: expandCodeForImpl(SE.getAddExpr(ScaledOps), Ty);
514-
GepIndices.push_back(Scaled);
515-
516-
// Collect struct field index operands.
517-
while (StructType *STy = dyn_cast<StructType>(ElTy)) {
518-
bool FoundFieldNo = false;
519-
// An empty struct has no fields.
520-
if (STy->getNumElements() == 0) break;
521-
// Field offsets are known. See if a constant offset falls within any of
522-
// the struct fields.
523-
if (Ops.empty())
524-
break;
525-
assert(
526-
!STy->containsScalableVectorType() &&
527-
"GEPs are not supported on structures containing scalable vectors");
528-
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(Ops[0]))
529-
if (SE.getTypeSizeInBits(C->getType()) <= 64) {
530-
const StructLayout &SL = *DL.getStructLayout(STy);
531-
uint64_t FullOffset = C->getValue()->getZExtValue();
532-
if (FullOffset < SL.getSizeInBytes()) {
533-
unsigned ElIdx = SL.getElementContainingOffset(FullOffset);
534-
GepIndices.push_back(
535-
ConstantInt::get(Type::getInt32Ty(Ty->getContext()), ElIdx));
536-
ElTy = STy->getTypeAtIndex(ElIdx);
537-
Ops[0] =
538-
SE.getConstant(Ty, FullOffset - SL.getElementOffset(ElIdx));
539-
AnyNonZeroIndices = true;
540-
FoundFieldNo = true;
541-
}
542-
}
543-
// If no struct field offsets were found, tentatively assume that
544-
// field zero was selected (since the zero offset would obviously
545-
// be folded away).
546-
if (!FoundFieldNo) {
547-
ElTy = STy->getTypeAtIndex(0u);
548-
GepIndices.push_back(
549-
Constant::getNullValue(Type::getInt32Ty(Ty->getContext())));
550-
}
551-
}
552-
553-
if (ArrayType *ATy = dyn_cast<ArrayType>(ElTy))
554-
ElTy = ATy->getElementType();
555-
else
556-
// FIXME: Handle VectorType.
557-
// E.g., If ElTy is scalable vector, then ElSize is not a compile-time
558-
// constant, therefore can not be factored out. The generated IR is less
559-
// ideal with base 'V' cast to i8* and do ugly getelementptr over that.
560-
break;
561-
}
562-
}
563-
564-
// If none of the operands were convertible to proper GEP indices, cast
565-
// the base to i8* and do an ugly getelementptr with that. It's still
566-
// better than ptrtoint+arithmetic+inttoptr at least.
567-
if (!AnyNonZeroIndices) {
568-
// Cast the base to i8*.
569-
if (!PTy->isOpaque())
570-
V = InsertNoopCastOfTo(V,
571-
Type::getInt8PtrTy(Ty->getContext(), PTy->getAddressSpace()));
572-
573-
assert(!isa<Instruction>(V) ||
574-
SE.DT.dominates(cast<Instruction>(V), &*Builder.GetInsertPoint()));
575-
576-
// Expand the operands for a plain byte offset.
577-
Value *Idx = expandCodeForImpl(SE.getAddExpr(Ops), Ty);
578-
579-
// Fold a GEP with constant operands.
580-
if (Constant *CLHS = dyn_cast<Constant>(V))
581-
if (Constant *CRHS = dyn_cast<Constant>(Idx))
582-
return Builder.CreateGEP(Builder.getInt8Ty(), CLHS, CRHS);
583-
584-
// Do a quick scan to see if we have this GEP nearby. If so, reuse it.
585-
unsigned ScanLimit = 6;
586-
BasicBlock::iterator BlockBegin = Builder.GetInsertBlock()->begin();
587-
// Scanning starts from the last instruction before the insertion point.
588-
BasicBlock::iterator IP = Builder.GetInsertPoint();
589-
if (IP != BlockBegin) {
590-
--IP;
591-
for (; ScanLimit; --IP, --ScanLimit) {
592-
// Don't count dbg.value against the ScanLimit, to avoid perturbing the
593-
// generated code.
594-
if (isa<DbgInfoIntrinsic>(IP))
595-
ScanLimit++;
596-
if (IP->getOpcode() == Instruction::GetElementPtr &&
597-
IP->getOperand(0) == V && IP->getOperand(1) == Idx &&
598-
cast<GEPOperator>(&*IP)->getSourceElementType() ==
599-
Type::getInt8Ty(Ty->getContext()))
600-
return &*IP;
601-
if (IP == BlockBegin) break;
602-
}
603-
}
461+
assert(!isa<Instruction>(V) ||
462+
SE.DT.dominates(cast<Instruction>(V), &*Builder.GetInsertPoint()));
604463

605-
// Save the original insertion point so we can restore it when we're done.
606-
SCEVInsertPointGuard Guard(Builder, this);
464+
// Expand the operands for a plain byte offset.
465+
Value *Idx = expandCodeForImpl(SE.getAddExpr(Ops), Ty);
607466

608-
// Move the insertion point out of as many loops as we can.
609-
while (const Loop *L = SE.LI.getLoopFor(Builder.GetInsertBlock())) {
610-
if (!L->isLoopInvariant(V) || !L->isLoopInvariant(Idx)) break;
611-
BasicBlock *Preheader = L->getLoopPreheader();
612-
if (!Preheader) break;
467+
// Fold a GEP with constant operands.
468+
if (Constant *CLHS = dyn_cast<Constant>(V))
469+
if (Constant *CRHS = dyn_cast<Constant>(Idx))
470+
return Builder.CreateGEP(Builder.getInt8Ty(), CLHS, CRHS);
613471

614-
// Ok, move up a level.
615-
Builder.SetInsertPoint(Preheader->getTerminator());
472+
// Do a quick scan to see if we have this GEP nearby. If so, reuse it.
473+
unsigned ScanLimit = 6;
474+
BasicBlock::iterator BlockBegin = Builder.GetInsertBlock()->begin();
475+
// Scanning starts from the last instruction before the insertion point.
476+
BasicBlock::iterator IP = Builder.GetInsertPoint();
477+
if (IP != BlockBegin) {
478+
--IP;
479+
for (; ScanLimit; --IP, --ScanLimit) {
480+
// Don't count dbg.value against the ScanLimit, to avoid perturbing the
481+
// generated code.
482+
if (isa<DbgInfoIntrinsic>(IP))
483+
ScanLimit++;
484+
if (IP->getOpcode() == Instruction::GetElementPtr &&
485+
IP->getOperand(0) == V && IP->getOperand(1) == Idx &&
486+
cast<GEPOperator>(&*IP)->getSourceElementType() ==
487+
Type::getInt8Ty(Ty->getContext()))
488+
return &*IP;
489+
if (IP == BlockBegin) break;
616490
}
617-
618-
// Emit a GEP.
619-
return Builder.CreateGEP(Builder.getInt8Ty(), V, Idx, "scevgep");
620491
}
621492

622-
{
623-
SCEVInsertPointGuard Guard(Builder, this);
624-
625-
// Move the insertion point out of as many loops as we can.
626-
while (const Loop *L = SE.LI.getLoopFor(Builder.GetInsertBlock())) {
627-
if (!L->isLoopInvariant(V)) break;
628-
629-
bool AnyIndexNotLoopInvariant = any_of(
630-
GepIndices, [L](Value *Op) { return !L->isLoopInvariant(Op); });
631-
632-
if (AnyIndexNotLoopInvariant)
633-
break;
634-
635-
BasicBlock *Preheader = L->getLoopPreheader();
636-
if (!Preheader) break;
493+
// Save the original insertion point so we can restore it when we're done.
494+
SCEVInsertPointGuard Guard(Builder, this);
637495

638-
// Ok, move up a level.
639-
Builder.SetInsertPoint(Preheader->getTerminator());
640-
}
496+
// Move the insertion point out of as many loops as we can.
497+
while (const Loop *L = SE.LI.getLoopFor(Builder.GetInsertBlock())) {
498+
if (!L->isLoopInvariant(V) || !L->isLoopInvariant(Idx)) break;
499+
BasicBlock *Preheader = L->getLoopPreheader();
500+
if (!Preheader) break;
641501

642-
// Insert a pretty getelementptr. Note that this GEP is not marked inbounds,
643-
// because ScalarEvolution may have changed the address arithmetic to
644-
// compute a value which is beyond the end of the allocated object.
645-
Value *Casted = V;
646-
if (V->getType() != PTy)
647-
Casted = InsertNoopCastOfTo(Casted, PTy);
648-
Value *GEP = Builder.CreateGEP(PTy->getNonOpaquePointerElementType(),
649-
Casted, GepIndices, "scevgep");
650-
Ops.push_back(SE.getUnknown(GEP));
502+
// Ok, move up a level.
503+
Builder.SetInsertPoint(Preheader->getTerminator());
651504
}
652505

653-
return expand(SE.getAddExpr(Ops));
506+
// Emit a GEP.
507+
return Builder.CreateGEP(Builder.getInt8Ty(), V, Idx, "scevgep");
654508
}
655509

656-
Value *SCEVExpander::expandAddToGEP(const SCEV *Op, PointerType *PTy, Type *Ty,
657-
Value *V) {
510+
Value *SCEVExpander::expandAddToGEP(const SCEV *Op, Type *Ty, Value *V) {
658511
const SCEV *const Ops[1] = {Op};
659-
return expandAddToGEP(Ops, Ops + 1, PTy, Ty, V);
512+
return expandAddToGEP(Ops, Ops + 1, Ty, V);
660513
}
661514

662515
/// PickMostRelevantLoop - Given two loops pick the one that's most relevant for
@@ -782,7 +635,7 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
782635
}
783636

784637
assert(!Op->getType()->isPointerTy() && "Only first op can be pointer");
785-
if (PointerType *PTy = dyn_cast<PointerType>(Sum->getType())) {
638+
if (isa<PointerType>(Sum->getType())) {
786639
// The running sum expression is a pointer. Try to form a getelementptr
787640
// at this level with that as the base.
788641
SmallVector<const SCEV *, 4> NewOps;
@@ -795,7 +648,7 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
795648
X = SE.getSCEV(U->getValue());
796649
NewOps.push_back(X);
797650
}
798-
Sum = expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, Sum);
651+
Sum = expandAddToGEP(NewOps.begin(), NewOps.end(), Ty, Sum);
799652
} else if (Op->isNonConstantNegative()) {
800653
// Instead of doing a negate and add, just do a subtract.
801654
Value *W = expandCodeForImpl(SE.getNegativeSCEV(Op), Ty);
@@ -1105,15 +958,7 @@ Value *SCEVExpander::expandIVInc(PHINode *PN, Value *StepV, const Loop *L,
1105958
Value *IncV;
1106959
// If the PHI is a pointer, use a GEP, otherwise use an add or sub.
1107960
if (ExpandTy->isPointerTy()) {
1108-
PointerType *GEPPtrTy = cast<PointerType>(ExpandTy);
1109-
// If the step isn't constant, don't use an implicitly scaled GEP, because
1110-
// that would require a multiply inside the loop.
1111-
if (!isa<ConstantInt>(StepV))
1112-
GEPPtrTy = PointerType::get(Type::getInt1Ty(SE.getContext()),
1113-
GEPPtrTy->getAddressSpace());
1114-
IncV = expandAddToGEP(SE.getSCEV(StepV), GEPPtrTy, IntTy, PN);
1115-
if (IncV->getType() != PN->getType())
1116-
IncV = Builder.CreateBitCast(IncV, PN->getType());
961+
IncV = expandAddToGEP(SE.getSCEV(StepV), IntTy, PN);
1117962
} else {
1118963
IncV = useSubtract ?
1119964
Builder.CreateSub(PN, StepV, Twine(IVName) + ".iv.next") :
@@ -1513,12 +1358,12 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
15131358

15141359
// Re-apply any non-loop-dominating offset.
15151360
if (PostLoopOffset) {
1516-
if (PointerType *PTy = dyn_cast<PointerType>(ExpandTy)) {
1361+
if (isa<PointerType>(ExpandTy)) {
15171362
if (Result->getType()->isIntegerTy()) {
15181363
Value *Base = expandCodeForImpl(PostLoopOffset, ExpandTy);
1519-
Result = expandAddToGEP(SE.getUnknown(Result), PTy, IntTy, Base);
1364+
Result = expandAddToGEP(SE.getUnknown(Result), IntTy, Base);
15201365
} else {
1521-
Result = expandAddToGEP(PostLoopOffset, PTy, IntTy, Result);
1366+
Result = expandAddToGEP(PostLoopOffset, IntTy, Result);
15221367
}
15231368
} else {
15241369
Result = InsertNoopCastOfTo(Result, IntTy);
@@ -1572,10 +1417,9 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
15721417

15731418
// {X,+,F} --> X + {0,+,F}
15741419
if (!S->getStart()->isZero()) {
1575-
if (PointerType *PTy = dyn_cast<PointerType>(S->getType())) {
1420+
if (isa<PointerType>(S->getType())) {
15761421
Value *StartV = expand(SE.getPointerBase(S));
1577-
assert(StartV->getType() == PTy && "Pointer type mismatch for GEP!");
1578-
return expandAddToGEP(SE.removePointerBase(S), PTy, Ty, StartV);
1422+
return expandAddToGEP(SE.removePointerBase(S), Ty, StartV);
15791423
}
15801424

15811425
SmallVector<const SCEV *, 4> NewOps(S->operands());

0 commit comments

Comments
 (0)