Skip to content

Commit 1ef4008

Browse files
committed
One call to tryToImproveAlign
1 parent 3e55c80 commit 1ef4008

File tree

1 file changed

+40
-36
lines changed

1 file changed

+40
-36
lines changed

llvm/lib/Transforms/Scalar/InferAlignment.cpp

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -57,53 +57,57 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) {
5757
}
5858
}
5959

60+
// Compute alignment from known bits.
61+
auto InferFromKnownBits = [&](Instruction &I, Value *PtrOp) {
62+
KnownBits Known = computeKnownBits(PtrOp, DL, &AC, &I, &DT);
63+
unsigned TrailZ =
64+
std::min(Known.countMinTrailingZeros(), +Value::MaxAlignmentExponent);
65+
return Align(1ull << std::min(Known.getBitWidth() - 1, TrailZ));
66+
};
67+
68+
// Propagate alignment between loads and stores that originate from the
69+
// same base pointer.
70+
DenseMap<Value *, Align> BestBasePointerAligns;
71+
auto InferFromBasePointer = [&](Value *PtrOp, Align LoadStoreAlign) {
72+
APInt OffsetFromBase =
73+
APInt(DL.getIndexTypeSizeInBits(PtrOp->getType()), 0);
74+
PtrOp = PtrOp->stripAndAccumulateConstantOffsets(DL, OffsetFromBase, true);
75+
// Derive the base pointer alignment from the load/store alignment
76+
// and the offset from the base pointer.
77+
Align BasePointerAlign =
78+
commonAlignment(LoadStoreAlign, OffsetFromBase.getLimitedValue());
79+
80+
auto [It, Inserted] =
81+
BestBasePointerAligns.try_emplace(PtrOp, BasePointerAlign);
82+
if (!Inserted) {
83+
// If the stored base pointer alignment is better than the
84+
// base pointer alignment we derived, we may be able to use it
85+
// to improve the load/store alignment. If not, store the
86+
// improved base pointer alignment for future iterations.
87+
if (It->second > BasePointerAlign) {
88+
Align BetterLoadStoreAlign =
89+
commonAlignment(It->second, OffsetFromBase.getLimitedValue());
90+
return BetterLoadStoreAlign;
91+
}
92+
It->second = BasePointerAlign;
93+
}
94+
return LoadStoreAlign;
95+
};
96+
6097
for (BasicBlock &BB : F) {
6198
// We need to reset the map for each block because alignment information
6299
// can't be propagated across blocks. This is because control flow could
63100
// be dependent on the address at runtime, making an alignment assumption
64101
// within one block not true in another. Some sort of dominator tree
65102
// approach could be better, but restricting within a basic block is correct
66103
// too.
67-
DenseMap<Value *, Align> BestBasePointerAligns;
104+
BestBasePointerAligns.clear();
68105

69106
for (Instruction &I : BB) {
70-
// Compute alignment from known bits.
71107
Changed |= tryToImproveAlign(
72108
DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) {
73-
KnownBits Known = computeKnownBits(PtrOp, DL, &AC, &I, &DT);
74-
unsigned TrailZ = std::min(Known.countMinTrailingZeros(),
75-
+Value::MaxAlignmentExponent);
76-
return Align(1ull << std::min(Known.getBitWidth() - 1, TrailZ));
77-
});
78-
79-
// Propagate alignment between loads and stores that originate from the
80-
// same base pointer.
81-
Changed |= tryToImproveAlign(
82-
DL, &I, [&](Value *PtrOp, Align LoadStoreAlign, Align PrefAlign) {
83-
APInt OffsetFromBase =
84-
APInt(DL.getIndexTypeSizeInBits(PtrOp->getType()), 0);
85-
PtrOp = PtrOp->stripAndAccumulateConstantOffsets(DL, OffsetFromBase,
86-
true);
87-
// Derive the base pointer alignment from the load/store alignment
88-
// and the offset from the base pointer.
89-
Align BasePointerAlign = commonAlignment(
90-
LoadStoreAlign, OffsetFromBase.getLimitedValue());
91-
92-
auto [It, Inserted] =
93-
BestBasePointerAligns.try_emplace(PtrOp, BasePointerAlign);
94-
if (!Inserted) {
95-
// If the stored base pointer alignment is better than the
96-
// base pointer alignment we derived, we may be able to use it
97-
// to improve the load/store alignment. If not, store the
98-
// improved base pointer alignment for future iterations.
99-
if (It->second > BasePointerAlign) {
100-
Align BetterLoadStoreAlign = commonAlignment(
101-
It->second, OffsetFromBase.getLimitedValue());
102-
return BetterLoadStoreAlign;
103-
}
104-
It->second = BasePointerAlign;
105-
}
106-
return LoadStoreAlign;
109+
return std::max(InferFromKnownBits(I, PtrOp),
110+
InferFromBasePointer(PtrOp, OldAlign));
107111
});
108112
}
109113
}

0 commit comments

Comments
 (0)