diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
-rw-r--r-- | llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/SROA.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp | 25 |
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); |