|
21 | 21 |
|
22 | 22 | using namespace llvm; |
23 | 23 |
|
24 | | -static bool tryToPropagateAlign(Function &F, const DataLayout &DL) { |
25 | | - bool Changed = false; |
26 | | - |
27 | | - for (BasicBlock &BB : F) { |
28 | | - // We need to reset the map for each block because alignment information |
29 | | - // can't be propagated across blocks. This is because control flow could |
30 | | - // be dependent on the address at runtime, making an alignment assumption |
31 | | - // within one block not true in another. Some sort of dominator tree |
32 | | - // approach could be better, but restricting within a basic block is correct |
33 | | - // too. |
34 | | - DenseMap<Value *, Align> BestBasePointerAligns; |
35 | | - for (Instruction &I : BB) { |
36 | | - if (auto *PtrOp = getLoadStorePointerOperand(&I)) { |
37 | | - Align LoadStoreAlign = getLoadStoreAlignment(&I); |
38 | | - APInt OffsetFromBase = |
39 | | - APInt(DL.getIndexTypeSizeInBits(PtrOp->getType()), 0); |
40 | | - PtrOp = PtrOp->stripAndAccumulateConstantOffsets(DL, OffsetFromBase, true); |
41 | | - Align BasePointerAlign = |
42 | | - commonAlignment(LoadStoreAlign, OffsetFromBase.getLimitedValue()); |
43 | | - |
44 | | - auto [It, Inserted] = |
45 | | - BestBasePointerAligns.try_emplace(PtrOp, BasePointerAlign); |
46 | | - if (!Inserted) { |
47 | | - if (It->second > BasePointerAlign) { |
48 | | - Align BetterLoadStoreAlign = |
49 | | - commonAlignment(It->second, OffsetFromBase.getLimitedValue()); |
50 | | - setLoadStoreAlignment(&I, BetterLoadStoreAlign); |
51 | | - Changed = true; |
52 | | - } else { |
53 | | - It->second = BasePointerAlign; |
54 | | - } |
55 | | - } |
56 | | - } |
57 | | - } |
58 | | - } |
59 | | - return Changed; |
60 | | -} |
61 | | - |
62 | 24 | static bool tryToImproveAlign( |
63 | 25 | const DataLayout &DL, Instruction *I, |
64 | 26 | function_ref<Align(Value *PtrOp, Align OldAlign, Align PrefAlign)> Fn) { |
@@ -95,23 +57,51 @@ bool inferAlignment(Function &F, AssumptionCache &AC, DominatorTree &DT) { |
95 | 57 | } |
96 | 58 | } |
97 | 59 |
|
98 | | - // Compute alignment from known bits. |
99 | 60 | for (BasicBlock &BB : F) { |
| 61 | + // We need to reset the map for each block because alignment information |
| 62 | + // can't be propagated across blocks. This is because control flow could |
| 63 | + // be dependent on the address at runtime, making an alignment assumption |
| 64 | + // within one block not true in another. Some sort of dominator tree |
| 65 | + // approach could be better, but restricting within a basic block is correct |
| 66 | + // too. |
| 67 | + DenseMap<Value *, Align> BestBasePointerAligns; |
| 68 | + |
100 | 69 | for (Instruction &I : BB) { |
| 70 | + // Compute alignment from known bits. |
101 | 71 | Changed |= tryToImproveAlign( |
102 | 72 | DL, &I, [&](Value *PtrOp, Align OldAlign, Align PrefAlign) { |
103 | 73 | KnownBits Known = computeKnownBits(PtrOp, DL, &AC, &I, &DT); |
104 | 74 | unsigned TrailZ = std::min(Known.countMinTrailingZeros(), |
105 | 75 | +Value::MaxAlignmentExponent); |
106 | 76 | return Align(1ull << std::min(Known.getBitWidth() - 1, TrailZ)); |
107 | 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 | + Align BasePointerAlign = commonAlignment( |
| 88 | + LoadStoreAlign, OffsetFromBase.getLimitedValue()); |
| 89 | + |
| 90 | + auto [It, Inserted] = |
| 91 | + BestBasePointerAligns.try_emplace(PtrOp, BasePointerAlign); |
| 92 | + if (!Inserted) { |
| 93 | + if (It->second > BasePointerAlign) { |
| 94 | + Align BetterLoadStoreAlign = commonAlignment( |
| 95 | + It->second, OffsetFromBase.getLimitedValue()); |
| 96 | + return BetterLoadStoreAlign; |
| 97 | + } |
| 98 | + It->second = BasePointerAlign; |
| 99 | + } |
| 100 | + return LoadStoreAlign; |
| 101 | + }); |
108 | 102 | } |
109 | 103 | } |
110 | 104 |
|
111 | | - // Propagate alignment between loads and stores that originate from the same |
112 | | - // base pointer |
113 | | - Changed |= tryToPropagateAlign(F, DL); |
114 | | - |
115 | 105 | return Changed; |
116 | 106 | } |
117 | 107 |
|
|
0 commit comments