forked from OSchip/llvm-project
[SROA] Support opaque pointers
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
This commit is contained in:
parent
806ff3c4a4
commit
6dfdc6bfd2
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -2766,7 +2778,9 @@ private:
|
|||
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
|
||||
|
|
|
@ -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.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue