summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
-rw-r--r--llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp17
-rw-r--r--llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp2
-rw-r--r--llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp6
-rw-r--r--llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp31
-rw-r--r--llvm/lib/Transforms/Scalar/SROA.cpp32
-rw-r--r--llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp25
6 files changed, 46 insertions, 67 deletions
diff --git a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
index f041a296684..a13e552cbd0 100644
--- a/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
+++ b/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
@@ -347,8 +347,6 @@ bool AlignmentFromAssumptions::processAssumption(CallInst *ACall) {
// instruction, but only for one operand, save it. If we reach the
// other operand through another assumption later, then we may
// change the alignment at that point.
- // FIXME: The above statement is no longer true. Fix the code below
- // to be able to reason about different dest/src alignments.
if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) {
unsigned NewSrcAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV,
MTI->getSource(), SE);
@@ -378,23 +376,20 @@ bool AlignmentFromAssumptions::processAssumption(CallInst *ACall) {
if (AltSrcAlignment <= std::max(NewDestAlignment, AltDestAlignment))
NewAlignment = std::max(NewAlignment, AltSrcAlignment);
- if (NewAlignment > MTI->getDestAlignment()) {
- MTI->setDestAlignment(NewAlignment);
- ++NumMemIntAlignChanged;
- }
-
- if (NewAlignment > MTI->getSrcAlignment()) {
- MTI->setSrcAlignment(NewAlignment);
+ if (NewAlignment > MI->getAlignment()) {
+ MI->setAlignment(ConstantInt::get(Type::getInt32Ty(
+ MI->getParent()->getContext()), NewAlignment));
++NumMemIntAlignChanged;
}
NewDestAlignments.insert(std::make_pair(MTI, NewDestAlignment));
NewSrcAlignments.insert(std::make_pair(MTI, NewSrcAlignment));
- } else if (NewDestAlignment > MI->getDestAlignment()) {
+ } else if (NewDestAlignment > MI->getAlignment()) {
assert((!isa<MemIntrinsic>(MI) || isa<MemSetInst>(MI)) &&
"Unknown memory intrinsic");
- MI->setDestAlignment(NewDestAlignment);
+ MI->setAlignment(ConstantInt::get(Type::getInt32Ty(
+ MI->getParent()->getContext()), NewDestAlignment));
++NumMemIntAlignChanged;
}
}
diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index b0e6d19c505..36ad0a5f7b9 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -611,7 +611,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) {
// as any store/memset/memcpy is likely using vector instructions so
// shortening it to not vector size is likely to be slower
MemIntrinsic* DepIntrinsic = cast<MemIntrinsic>(DepWrite);
- unsigned DepWriteAlign = DepIntrinsic->getDestAlignment();
+ unsigned DepWriteAlign = DepIntrinsic->getAlignment();
if (llvm::isPowerOf2_64(InstWriteOffset) ||
((DepWriteAlign != 0) && InstWriteOffset % DepWriteAlign == 0)) {
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index aed43b39d64..c2fb8cd49b7 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -414,8 +414,8 @@ bool LoopIdiomRecognize::processLoopMemSet(MemSetInst *MSI,
return false;
return processLoopStridedStore(Pointer, (unsigned)SizeInBytes,
- MSI->getDestAlignment(), MSI->getValue(), MSI,
- Ev, BECount, /*NegStride=*/false);
+ MSI->getAlignment(), MSI->getValue(), MSI, Ev,
+ BECount, /*NegStride=*/false);
}
/// mayLoopAccessLocation - Return true if the specified loop might access the
@@ -700,7 +700,7 @@ bool LoopIdiomRecognize::processLoopStoreOfLoopLoad(
CallInst *NewCall =
Builder.CreateMemCpy(StoreBasePtr, LoadBasePtr, NumBytes,
- SI->getAlignment(), LI->getAlignment());
+ std::min(SI->getAlignment(), LI->getAlignment()));
NewCall->setDebugLoc(SI->getDebugLoc());
DEBUG(dbgs() << " Formed memcpy: " << *NewCall << "\n"
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 2db2b802f08..f80b07bf219 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -229,8 +229,7 @@ public:
void addMemSet(int64_t OffsetFromFirst, MemSetInst *MSI) {
int64_t Size = cast<ConstantInt>(MSI->getLength())->getZExtValue();
- addRange(OffsetFromFirst, Size, MSI->getDest(), MSI->getDestAlignment(),
- MSI);
+ addRange(OffsetFromFirst, Size, MSI->getDest(), MSI->getAlignment(), MSI);
}
void addRange(int64_t Start, int64_t Size, Value *Ptr,
@@ -820,17 +819,20 @@ bool MemCpyOpt::processMemCpyMemCpyDependence(MemCpyInst *M, MemCpyInst *MDep) {
// If all checks passed, then we can transform M.
+ // Make sure to use the lesser of the alignment of the source and the dest
+ // since we're changing where we're reading from, but don't want to increase
+ // the alignment past what can be read from or written to.
// TODO: Is this worth it if we're creating a less aligned memcpy? For
// example we could be moving from movaps -> movq on x86.
+ unsigned Align = std::min(MDep->getAlignment(), M->getAlignment());
+
IRBuilder<> Builder(M);
if (UseMemMove)
Builder.CreateMemMove(M->getRawDest(), MDep->getRawSource(), M->getLength(),
- M->getDestAlignment(), MDep->getSrcAlignment(),
- M->isVolatile());
+ Align, M->isVolatile());
else
Builder.CreateMemCpy(M->getRawDest(), MDep->getRawSource(), M->getLength(),
- M->getDestAlignment(), MDep->getSrcAlignment(),
- M->isVolatile());
+ Align, M->isVolatile());
// Remove the instruction we're replacing.
MD->removeInstruction(M);
@@ -876,7 +878,7 @@ bool MemCpyOpt::processMemSetMemCpyDependence(MemCpyInst *MemCpy,
// If Dest is aligned, and SrcSize is constant, use the minimum alignment
// of the sum.
const unsigned DestAlign =
- std::max(MemSet->getDestAlignment(), MemCpy->getDestAlignment());
+ std::max(MemSet->getAlignment(), MemCpy->getAlignment());
if (DestAlign > 1)
if (ConstantInt *SrcSizeC = dyn_cast<ConstantInt>(SrcSize))
Align = MinAlign(SrcSizeC->getZExtValue(), DestAlign);
@@ -933,7 +935,7 @@ bool MemCpyOpt::performMemCpyToMemSetOptzn(MemCpyInst *MemCpy,
IRBuilder<> Builder(MemCpy);
Builder.CreateMemSet(MemCpy->getRawDest(), MemSet->getOperand(1),
- CopySize, MemCpy->getDestAlignment());
+ CopySize, MemCpy->getAlignment());
return true;
}
@@ -959,7 +961,7 @@ bool MemCpyOpt::processMemCpy(MemCpyInst *M) {
if (Value *ByteVal = isBytewiseValue(GV->getInitializer())) {
IRBuilder<> Builder(M);
Builder.CreateMemSet(M->getRawDest(), ByteVal, M->getLength(),
- M->getDestAlignment(), false);
+ M->getAlignment(), false);
MD->removeInstruction(M);
M->eraseFromParent();
++NumCpyToSet;
@@ -988,11 +990,8 @@ bool MemCpyOpt::processMemCpy(MemCpyInst *M) {
// d) memcpy from a just-memset'd source can be turned into memset.
if (DepInfo.isClobber()) {
if (CallInst *C = dyn_cast<CallInst>(DepInfo.getInst())) {
- // FIXME: Can we pass in either of dest/src alignment here instead of
- // convervatively taking the minimum?
- unsigned Align = std::min(M->getDestAlignment(), M->getSrcAlignment());
if (performCallSlotOptzn(M, M->getDest(), M->getSource(),
- CopySize->getZExtValue(), Align,
+ CopySize->getZExtValue(), M->getAlignment(),
C)) {
MD->removeInstruction(M);
M->eraseFromParent();
@@ -1109,11 +1108,7 @@ bool MemCpyOpt::processByValArgument(CallSite CS, unsigned ArgNo) {
getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
*CS->getParent()->getParent());
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- // FIXME: Can we use either of dest/src alignment here instead of
- // convervatively taking the minimum?
- unsigned MinAlign = std::min(MDep->getDestAlignment(),
- MDep->getSrcAlignment());
- if (MinAlign < ByValAlign &&
+ if (MDep->getAlignment() < ByValAlign &&
getOrEnforceKnownAlignment(MDep->getSource(), ByValAlign, DL,
CS.getInstruction(), &AC, &DT) < ByValAlign)
return false;
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index 223c531b7d7..bfd48ff15f6 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -2618,7 +2618,8 @@ private:
assert(!IsSplit);
assert(NewBeginOffset == BeginOffset);
II.setDest(getNewAllocaSlicePtr(IRB, OldPtr->getType()));
- II.setDestAlignment(getSliceAlign());
+ Type *CstTy = II.getAlignmentCst()->getType();
+ II.setAlignment(ConstantInt::get(CstTy, getSliceAlign()));
deleteIfTriviallyDead(OldPtr);
return false;
@@ -2734,16 +2735,15 @@ private:
// update both source and dest of a single call.
if (!IsSplittable) {
Value *AdjustedPtr = getNewAllocaSlicePtr(IRB, OldPtr->getType());
- if (IsDest) {
+ if (IsDest)
II.setDest(AdjustedPtr);
-
- if (II.getDestAlignment() > SliceAlign)
- II.setDestAlignment(MinAlign(II.getDestAlignment(), SliceAlign));
- } else {
+ else
II.setSource(AdjustedPtr);
- if (II.getSrcAlignment() > SliceAlign)
- II.setSrcAlignment(MinAlign(II.getSrcAlignment(), SliceAlign));
+ if (II.getAlignment() > SliceAlign) {
+ Type *CstTy = II.getAlignmentCst()->getType();
+ II.setAlignment(
+ ConstantInt::get(CstTy, MinAlign(II.getAlignment(), SliceAlign)));
}
DEBUG(dbgs() << " to: " << II << "\n");
@@ -2796,10 +2796,8 @@ private:
// Compute the relative offset for the other pointer within the transfer.
unsigned IntPtrWidth = DL.getPointerSizeInBits(OtherAS);
APInt OtherOffset(IntPtrWidth, NewBeginOffset - BeginOffset);
- unsigned OtherDestAlign = MinAlign(II.getDestAlignment() ? II.getDestAlignment() : 1,
- OtherOffset.zextOrTrunc(64).getZExtValue());
- unsigned OtherSrcAlign = MinAlign(II.getSrcAlignment() ? II.getSrcAlignment() : 1,
- OtherOffset.zextOrTrunc(64).getZExtValue());
+ unsigned OtherAlign = MinAlign(II.getAlignment() ? II.getAlignment() : 1,
+ OtherOffset.zextOrTrunc(64).getZExtValue());
if (EmitMemCpy) {
// Compute the other pointer, folding as much as possible to produce
@@ -2811,11 +2809,9 @@ private:
Type *SizeTy = II.getLength()->getType();
Constant *Size = ConstantInt::get(SizeTy, NewEndOffset - NewBeginOffset);
- CallInst *New = IRB.CreateMemCpy(IsDest ? OurPtr : OtherPtr,
- IsDest ? OtherPtr : OurPtr, Size,
- MinAlign(SliceAlign, OtherDestAlign),
- MinAlign(SliceAlign, OtherSrcAlign),
- II.isVolatile());
+ CallInst *New = IRB.CreateMemCpy(
+ IsDest ? OurPtr : OtherPtr, IsDest ? OtherPtr : OurPtr, Size,
+ MinAlign(SliceAlign, OtherAlign), II.isVolatile());
(void)New;
DEBUG(dbgs() << " to: " << *New << "\n");
return false;
@@ -2847,7 +2843,7 @@ private:
Value *SrcPtr = getAdjustedPtr(IRB, DL, OtherPtr, OtherOffset, OtherPtrTy,
OtherPtr->getName() + ".");
- unsigned SrcAlign = OtherSrcAlign;
+ unsigned SrcAlign = OtherAlign;
Value *DstPtr = &NewAI;
unsigned DstAlign = SliceAlign;
if (!IsDest) {
diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
index 679e241d971..114d22ddf2e 100644
--- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
@@ -716,7 +716,7 @@ void ConvertToScalarInfo::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI,
SrcPtr = Builder.CreateBitCast(SrcPtr, AIPTy);
LoadInst *SrcVal = Builder.CreateLoad(SrcPtr, "srcval");
- SrcVal->setAlignment(MTI->getSrcAlignment());
+ SrcVal->setAlignment(MTI->getAlignment());
Builder.CreateStore(SrcVal, NewAI);
} else if (GetUnderlyingObject(MTI->getDest(), DL, 0) != OrigAI) {
// Src must be OrigAI, change this to be a load from NewAI then a store
@@ -733,7 +733,7 @@ void ConvertToScalarInfo::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI,
Value *DstPtr = Builder.CreateBitCast(MTI->getDest(), AIPTy);
StoreInst *NewStore = Builder.CreateStore(SrcVal, DstPtr);
- NewStore->setAlignment(MTI->getDestAlignment());
+ NewStore->setAlignment(MTI->getAlignment());
} else {
// Noop transfer. Src == Dst
}
@@ -2182,8 +2182,7 @@ SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
// that doesn't have anything to do with the alloca that we are promoting. For
// memset, this Value* stays null.
Value *OtherPtr = nullptr;
- unsigned DestMemAlignment = MI->getDestAlignment();
- unsigned SrcMemAlignment = 0;
+ unsigned MemAlignment = MI->getAlignment();
if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) { // memmove/memcopy
if (Inst == MTI->getRawDest())
OtherPtr = MTI->getRawSource();
@@ -2191,7 +2190,6 @@ SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
assert(Inst == MTI->getRawSource());
OtherPtr = MTI->getRawDest();
}
- SrcMemAlignment = MTI->getSrcAlignment();
}
// If there is an other pointer, we want to convert it to the same pointer
@@ -2237,8 +2235,7 @@ SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
for (unsigned i = 0, e = NewElts.size(); i != e; ++i) {
// If this is a memcpy/memmove, emit a GEP of the other element address.
Value *OtherElt = nullptr;
- unsigned OtherDestEltAlign = DestMemAlignment;
- unsigned OtherSrcEltAlign = SrcMemAlignment;
+ unsigned OtherEltAlign = MemAlignment;
if (OtherPtr) {
Value *Idx[2] = { Zero,
@@ -2261,8 +2258,7 @@ SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
// mem intrinsic and the alignment of the element. If the alignment of
// the memcpy (f.e.) is 32 but the element is at a 4-byte offset, then the
// known alignment is just 4 bytes.
- OtherDestEltAlign = (unsigned)MinAlign(OtherDestEltAlign, EltOffset);
- OtherSrcEltAlign = (unsigned)MinAlign(OtherSrcEltAlign, EltOffset);
+ OtherEltAlign = (unsigned)MinAlign(OtherEltAlign, EltOffset);
}
Value *EltPtr = NewElts[i];
@@ -2273,13 +2269,12 @@ SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
if (isa<MemTransferInst>(MI)) {
if (SROADest) {
// From Other to Alloca.
- Value *Elt = new LoadInst(OtherElt, "tmp", false,
- OtherSrcEltAlign, MI);
+ Value *Elt = new LoadInst(OtherElt, "tmp", false, OtherEltAlign, MI);
new StoreInst(Elt, EltPtr, MI);
} else {
// From Alloca to Other.
Value *Elt = new LoadInst(EltPtr, "tmp", MI);
- new StoreInst(Elt, OtherElt, false, OtherDestEltAlign, MI);
+ new StoreInst(Elt, OtherElt, false, OtherEltAlign, MI);
}
continue;
}
@@ -2342,11 +2337,9 @@ SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
Value *Src = SROADest ? OtherElt : EltPtr; // Src ptr
if (isa<MemCpyInst>(MI))
- Builder.CreateMemCpy(Dst, Src, EltSize, OtherDestEltAlign,
- OtherSrcEltAlign, MI->isVolatile());
+ Builder.CreateMemCpy(Dst, Src, EltSize, OtherEltAlign,MI->isVolatile());
else
- Builder.CreateMemMove(Dst, Src, EltSize, OtherDestEltAlign,
- OtherSrcEltAlign, MI->isVolatile());
+ Builder.CreateMemMove(Dst, Src, EltSize,OtherEltAlign,MI->isVolatile());
}
}
DeadInsts.push_back(MI);
OpenPOWER on IntegriCloud