Skip to content

Commit

Permalink
[SROA] Support opaque pointers
Browse files Browse the repository at this point in the history
Make the following changes in order to support opaque pointers in SROA:

 * Generate i8 GEPs for opaque pointers.
 * Explicitly enforce that promotable allocas only have stores of
   the alloca type -- previously this was implicitly enforced.
 * Replace a check for pointer element type with load/store type.

Differential Revision: https://reviews.llvm.org/D109259
  • Loading branch information
nikic committed Sep 8, 2021
1 parent 806ff3c commit 6dfdc6b
Show file tree
Hide file tree
Showing 3 changed files with 2,177 additions and 5 deletions.
22 changes: 18 additions & 4 deletions llvm/lib/Transforms/Scalar/SROA.cpp
Expand Up @@ -1611,6 +1611,15 @@ static Value *getNaturalGEPWithOffset(IRBuilderTy &IRB, const DataLayout &DL,
static Value *getAdjustedPtr(IRBuilderTy &IRB, const DataLayout &DL, Value *Ptr,
APInt Offset, Type *PointerTy,
const Twine &NamePrefix) {
// Create i8 GEP for opaque pointers.
if (Ptr->getType()->isOpaquePointerTy()) {
if (Offset != 0)
Ptr = IRB.CreateInBoundsGEP(IRB.getInt8Ty(), Ptr, IRB.getInt(Offset),
NamePrefix + "sroa_idx");
return IRB.CreatePointerBitCastOrAddrSpaceCast(Ptr, PointerTy,
NamePrefix + "sroa_cast");
}

// Even though we don't look through PHI nodes, we could be called on an
// instruction in an unreachable block, which may be on a cycle.
SmallPtrSet<Value *, 4> Visited;
Expand Down Expand Up @@ -1874,13 +1883,13 @@ static bool isVectorPromotionViableForSlice(Partition &P, const Slice &S,
} else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(U->getUser())) {
if (!II->isLifetimeStartOrEnd() && !II->isDroppable())
return false;
} else if (U->get()->getType()->getPointerElementType()->isStructTy()) {
// Disable vector promotion when there are loads or stores of an FCA.
return false;
} else if (LoadInst *LI = dyn_cast<LoadInst>(U->getUser())) {
if (LI->isVolatile())
return false;
Type *LTy = LI->getType();
// Disable vector promotion when there are loads or stores of an FCA.
if (LTy->isStructTy())
return false;
if (P.beginOffset() > S.beginOffset() || P.endOffset() < S.endOffset()) {
assert(LTy->isIntegerTy());
LTy = SplitIntTy;
Expand All @@ -1891,6 +1900,9 @@ static bool isVectorPromotionViableForSlice(Partition &P, const Slice &S,
if (SI->isVolatile())
return false;
Type *STy = SI->getValueOperand()->getType();
// Disable vector promotion when there are loads or stores of an FCA.
if (STy->isStructTy())
return false;
if (P.beginOffset() > S.beginOffset() || P.endOffset() < S.endOffset()) {
assert(STy->isIntegerTy());
STy = SplitIntTy;
Expand Down Expand Up @@ -2766,7 +2778,9 @@ class llvm::sroa::AllocaSliceRewriter
deleteIfTriviallyDead(OldOp);

LLVM_DEBUG(dbgs() << " to: " << *NewSI << "\n");
return NewSI->getPointerOperand() == &NewAI && !SI.isVolatile();
return NewSI->getPointerOperand() == &NewAI &&
NewSI->getValueOperand()->getType() == NewAllocaTy &&
!SI.isVolatile();
}

/// Compute an integer value from splatting an i8 across the given
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
Expand Up @@ -70,7 +70,8 @@ bool llvm::isAllocaPromotable(const AllocaInst *AI) {
if (LI->isVolatile())
return false;
} else if (const StoreInst *SI = dyn_cast<StoreInst>(U)) {
if (SI->getOperand(0) == AI)
if (SI->getValueOperand() == AI ||
SI->getValueOperand()->getType() != AI->getAllocatedType())
return false; // Don't allow a store OF the AI, only INTO the AI.
// Note that atomic stores can be transformed; atomic semantics do
// not have any meaning for a local alloca.
Expand Down

0 comments on commit 6dfdc6b

Please sign in to comment.