summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-10-03 08:14:02 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-10-03 08:14:02 +0000
commit4b2b38d3982c115906ecc81fa9be3cf5d0330a3d (patch)
treee5c8097870208a40a05b0fca71ef0c56495775c9 /llvm/lib/Transforms
parentf4fba5cf7a0d01414b462eac4a3741e9a3f2ef0f (diff)
downloadbcm5719-llvm-4b2b38d3982c115906ecc81fa9be3cf5d0330a3d.tar.gz
bcm5719-llvm-4b2b38d3982c115906ecc81fa9be3cf5d0330a3d.zip
Try to use a better set of abstractions for computing the alignment
necessary during rewriting. As part of this, fix a real think-o here where we might have left off an alignment specification when the address is in fact underaligned. I haven't come up with any way to trigger this, as there is always some other factor that reduces the alignment, but it certainly might have been an observable bug in some way I can't think of. This also slightly changes the strategy for placing explicit alignments on loads and stores to only do so when the alignment does not match that required by the ABI. This causes a few redundant alignments to go away from test cases. I've also added a couple of tests that really push on the alignment that we end up with on loads and stores. More to come here as I try to fix an underlying bug I have conjectured and produced test cases for, although it's not clear if this bug is the one currently hitting dragonegg's gcc47 bootstrap. llvm-svn: 165100
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/SROA.cpp44
1 files changed, 28 insertions, 16 deletions
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index 316742a0da6..58bae0971e3 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -2170,18 +2170,36 @@ private:
return getAdjustedPtr(IRB, TD, &NewAI, Offset, PointerTy, getName(""));
}
- unsigned getAdjustedAlign(uint64_t Offset) {
+ /// \brief Compute suitable alignment to access an offset into the new alloca.
+ unsigned getOffsetAlign(uint64_t Offset) {
unsigned NewAIAlign = NewAI.getAlignment();
if (!NewAIAlign)
NewAIAlign = TD.getABITypeAlignment(NewAI.getAllocatedType());
return MinAlign(NewAIAlign, Offset);
}
- unsigned getAdjustedAlign() {
- return getAdjustedAlign(BeginOffset - NewAllocaBeginOffset);
+
+ /// \brief Compute suitable alignment to access this partition of the new
+ /// alloca.
+ unsigned getPartitionAlign() {
+ return getOffsetAlign(BeginOffset - NewAllocaBeginOffset);
}
- bool isTypeAlignSufficient(Type *Ty) {
- return TD.getABITypeAlignment(Ty) >= getAdjustedAlign();
+ /// \brief Compute suitable alignment to access a type at an offset of the
+ /// new alloca.
+ ///
+ /// \returns zero if the type's ABI alignment is a suitable alignment,
+ /// otherwise returns the maximal suitable alignment.
+ unsigned getOffsetTypeAlign(Type *Ty, uint64_t Offset) {
+ unsigned Align = getOffsetAlign(Offset);
+ return Align == TD.getABITypeAlignment(Ty) ? 0 : Align;
+ }
+
+ /// \brief Compute suitable alignment to access a type at the beginning of
+ /// this partition of the new alloca.
+ ///
+ /// See \c getOffsetTypeAlign for details; this routine delegates to it.
+ unsigned getPartitionTypeAlign(Type *Ty) {
+ return getOffsetTypeAlign(Ty, BeginOffset - NewAllocaBeginOffset);
}
ConstantInt *getIndex(IRBuilder<> &IRB, uint64_t Offset) {
@@ -2292,8 +2310,7 @@ private:
Value *NewPtr = getAdjustedAllocaPtr(IRB,
LI.getPointerOperand()->getType());
LI.setOperand(0, NewPtr);
- if (LI.getAlignment() || !isTypeAlignSufficient(LI.getType()))
- LI.setAlignment(getAdjustedAlign());
+ LI.setAlignment(getPartitionTypeAlign(LI.getType()));
DEBUG(dbgs() << " to: " << LI << "\n");
deleteIfTriviallyDead(OldOp);
@@ -2345,12 +2362,7 @@ private:
Value *NewPtr = getAdjustedAllocaPtr(IRB,
SI.getPointerOperand()->getType());
SI.setOperand(1, NewPtr);
- if (SI.getAlignment() ||
- !isTypeAlignSufficient(SI.getValueOperand()->getType()))
- SI.setAlignment(getAdjustedAlign());
- if (SI.getAlignment())
- SI.setAlignment(MinAlign(NewAI.getAlignment(),
- BeginOffset - NewAllocaBeginOffset));
+ SI.setAlignment(getPartitionTypeAlign(SI.getValueOperand()->getType()));
DEBUG(dbgs() << " to: " << SI << "\n");
deleteIfTriviallyDead(OldOp);
@@ -2367,7 +2379,7 @@ private:
if (!isa<Constant>(II.getLength())) {
II.setDest(getAdjustedAllocaPtr(IRB, II.getRawDest()->getType()));
Type *CstTy = II.getAlignmentCst()->getType();
- II.setAlignment(ConstantInt::get(CstTy, getAdjustedAlign()));
+ II.setAlignment(ConstantInt::get(CstTy, getPartitionAlign()));
deleteIfTriviallyDead(OldPtr);
return false;
@@ -2391,7 +2403,7 @@ private:
CallInst *New
= IRB.CreateMemSet(getAdjustedAllocaPtr(IRB,
II.getRawDest()->getType()),
- II.getValue(), Size, getAdjustedAlign(),
+ II.getValue(), Size, getPartitionAlign(),
II.isVolatile());
(void)New;
DEBUG(dbgs() << " to: " << *New << "\n");
@@ -2481,7 +2493,7 @@ private:
unsigned Align = II.getAlignment();
if (Align > 1)
Align = MinAlign(RelOffset.zextOrTrunc(64).getZExtValue(),
- MinAlign(II.getAlignment(), getAdjustedAlign()));
+ MinAlign(II.getAlignment(), getPartitionAlign()));
// For unsplit intrinsics, we simply modify the source and destination
// pointers in place. This isn't just an optimization, it is a matter of
OpenPOWER on IntegriCloud