/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===----------------------- AlignmentFromAssumptions.cpp -----------------===// |
2 | | // Set Load/Store Alignments From Assumptions |
3 | | // |
4 | | // The LLVM Compiler Infrastructure |
5 | | // |
6 | | // This file is distributed under the University of Illinois Open Source |
7 | | // License. See LICENSE.TXT for details. |
8 | | // |
9 | | //===----------------------------------------------------------------------===// |
10 | | // |
11 | | // This file implements a ScalarEvolution-based transformation to set |
12 | | // the alignments of load, stores and memory intrinsics based on the truth |
13 | | // expressions of assume intrinsics. The primary motivation is to handle |
14 | | // complex alignment assumptions that apply to vector loads and stores that |
15 | | // appear after vectorization and unrolling. |
16 | | // |
17 | | //===----------------------------------------------------------------------===// |
18 | | |
19 | | #define AA_NAME "alignment-from-assumptions" |
20 | | #define DEBUG_TYPE AA_NAME |
21 | | #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h" |
22 | | #include "llvm/ADT/SmallPtrSet.h" |
23 | | #include "llvm/ADT/Statistic.h" |
24 | | #include "llvm/Analysis/AliasAnalysis.h" |
25 | | #include "llvm/Analysis/AssumptionCache.h" |
26 | | #include "llvm/Analysis/GlobalsModRef.h" |
27 | | #include "llvm/Analysis/LoopInfo.h" |
28 | | #include "llvm/Analysis/ScalarEvolutionExpressions.h" |
29 | | #include "llvm/Analysis/ValueTracking.h" |
30 | | #include "llvm/IR/Constant.h" |
31 | | #include "llvm/IR/Dominators.h" |
32 | | #include "llvm/IR/Instruction.h" |
33 | | #include "llvm/IR/Intrinsics.h" |
34 | | #include "llvm/IR/Module.h" |
35 | | #include "llvm/Support/Debug.h" |
36 | | #include "llvm/Support/raw_ostream.h" |
37 | | #include "llvm/Transforms/Scalar.h" |
38 | | using namespace llvm; |
39 | | |
40 | | STATISTIC(NumLoadAlignChanged, |
41 | | "Number of loads changed by alignment assumptions"); |
42 | | STATISTIC(NumStoreAlignChanged, |
43 | | "Number of stores changed by alignment assumptions"); |
44 | | STATISTIC(NumMemIntAlignChanged, |
45 | | "Number of memory intrinsics changed by alignment assumptions"); |
46 | | |
47 | | namespace { |
48 | | struct AlignmentFromAssumptions : public FunctionPass { |
49 | | static char ID; // Pass identification, replacement for typeid |
50 | 17.4k | AlignmentFromAssumptions() : FunctionPass(ID) { |
51 | 17.4k | initializeAlignmentFromAssumptionsPass(*PassRegistry::getPassRegistry()); |
52 | 17.4k | } |
53 | | |
54 | | bool runOnFunction(Function &F) override; |
55 | | |
56 | 17.4k | void getAnalysisUsage(AnalysisUsage &AU) const override { |
57 | 17.4k | AU.addRequired<AssumptionCacheTracker>(); |
58 | 17.4k | AU.addRequired<ScalarEvolutionWrapperPass>(); |
59 | 17.4k | AU.addRequired<DominatorTreeWrapperPass>(); |
60 | 17.4k | |
61 | 17.4k | AU.setPreservesCFG(); |
62 | 17.4k | AU.addPreserved<AAResultsWrapperPass>(); |
63 | 17.4k | AU.addPreserved<GlobalsAAWrapperPass>(); |
64 | 17.4k | AU.addPreserved<LoopInfoWrapperPass>(); |
65 | 17.4k | AU.addPreserved<DominatorTreeWrapperPass>(); |
66 | 17.4k | AU.addPreserved<ScalarEvolutionWrapperPass>(); |
67 | 17.4k | } |
68 | | |
69 | | AlignmentFromAssumptionsPass Impl; |
70 | | }; |
71 | | } |
72 | | |
73 | | char AlignmentFromAssumptions::ID = 0; |
74 | | static const char aip_name[] = "Alignment from assumptions"; |
75 | 41.8k | INITIALIZE_PASS_BEGIN41.8k (AlignmentFromAssumptions, AA_NAME,
|
76 | 41.8k | aip_name, false, false) |
77 | 41.8k | INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) |
78 | 41.8k | INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) |
79 | 41.8k | INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) |
80 | 41.8k | INITIALIZE_PASS_END(AlignmentFromAssumptions, AA_NAME, |
81 | | aip_name, false, false) |
82 | | |
83 | 17.4k | FunctionPass *llvm::createAlignmentFromAssumptionsPass() { |
84 | 17.4k | return new AlignmentFromAssumptions(); |
85 | 17.4k | } |
86 | | |
87 | | // Given an expression for the (constant) alignment, AlignSCEV, and an |
88 | | // expression for the displacement between a pointer and the aligned address, |
89 | | // DiffSCEV, compute the alignment of the displaced pointer if it can be reduced |
90 | | // to a constant. Using SCEV to compute alignment handles the case where |
91 | | // DiffSCEV is a recurrence with constant start such that the aligned offset |
92 | | // is constant. e.g. {16,+,32} % 32 -> 16. |
93 | | static unsigned getNewAlignmentDiff(const SCEV *DiffSCEV, |
94 | | const SCEV *AlignSCEV, |
95 | 68 | ScalarEvolution *SE) { |
96 | 68 | // DiffUnits = Diff % int64_t(Alignment) |
97 | 68 | const SCEV *DiffAlignDiv = SE->getUDivExpr(DiffSCEV, AlignSCEV); |
98 | 68 | const SCEV *DiffAlign = SE->getMulExpr(DiffAlignDiv, AlignSCEV); |
99 | 68 | const SCEV *DiffUnitsSCEV = SE->getMinusSCEV(DiffAlign, DiffSCEV); |
100 | 68 | |
101 | 68 | DEBUG(dbgs() << "\talignment relative to " << *AlignSCEV << " is " << |
102 | 68 | *DiffUnitsSCEV << " (diff: " << *DiffSCEV << ")\n"); |
103 | 68 | |
104 | 68 | if (const SCEVConstant *ConstDUSCEV = |
105 | 52 | dyn_cast<SCEVConstant>(DiffUnitsSCEV)) { |
106 | 52 | int64_t DiffUnits = ConstDUSCEV->getValue()->getSExtValue(); |
107 | 52 | |
108 | 52 | // If the displacement is an exact multiple of the alignment, then the |
109 | 52 | // displaced pointer has the same alignment as the aligned pointer, so |
110 | 52 | // return the alignment value. |
111 | 52 | if (!DiffUnits) |
112 | 32 | return (unsigned) |
113 | 32 | cast<SCEVConstant>(AlignSCEV)->getValue()->getSExtValue(); |
114 | 20 | |
115 | 20 | // If the displacement is not an exact multiple, but the remainder is a |
116 | 20 | // constant, then return this remainder (but only if it is a power of 2). |
117 | 20 | uint64_t DiffUnitsAbs = std::abs(DiffUnits); |
118 | 20 | if (isPowerOf2_64(DiffUnitsAbs)) |
119 | 20 | return (unsigned) DiffUnitsAbs; |
120 | 16 | } |
121 | 16 | |
122 | 16 | return 0; |
123 | 16 | } |
124 | | |
125 | | // There is an address given by an offset OffSCEV from AASCEV which has an |
126 | | // alignment AlignSCEV. Use that information, if possible, to compute a new |
127 | | // alignment for Ptr. |
128 | | static unsigned getNewAlignment(const SCEV *AASCEV, const SCEV *AlignSCEV, |
129 | | const SCEV *OffSCEV, Value *Ptr, |
130 | 52 | ScalarEvolution *SE) { |
131 | 52 | const SCEV *PtrSCEV = SE->getSCEV(Ptr); |
132 | 52 | const SCEV *DiffSCEV = SE->getMinusSCEV(PtrSCEV, AASCEV); |
133 | 52 | |
134 | 52 | // On 32-bit platforms, DiffSCEV might now have type i32 -- we've always |
135 | 52 | // sign-extended OffSCEV to i64, so make sure they agree again. |
136 | 52 | DiffSCEV = SE->getNoopOrSignExtend(DiffSCEV, OffSCEV->getType()); |
137 | 52 | |
138 | 52 | // What we really want to know is the overall offset to the aligned |
139 | 52 | // address. This address is displaced by the provided offset. |
140 | 52 | DiffSCEV = SE->getMinusSCEV(DiffSCEV, OffSCEV); |
141 | 52 | |
142 | 52 | DEBUG(dbgs() << "AFI: alignment of " << *Ptr << " relative to " << |
143 | 52 | *AlignSCEV << " and offset " << *OffSCEV << |
144 | 52 | " using diff " << *DiffSCEV << "\n"); |
145 | 52 | |
146 | 52 | unsigned NewAlignment = getNewAlignmentDiff(DiffSCEV, AlignSCEV, SE); |
147 | 52 | DEBUG(dbgs() << "\tnew alignment: " << NewAlignment << "\n"); |
148 | 52 | |
149 | 52 | if (NewAlignment52 ) { |
150 | 36 | return NewAlignment; |
151 | 16 | } else if (const SCEVAddRecExpr *16 DiffARSCEV16 = |
152 | 8 | dyn_cast<SCEVAddRecExpr>(DiffSCEV)) { |
153 | 8 | // The relative offset to the alignment assumption did not yield a constant, |
154 | 8 | // but we should try harder: if we assume that a is 32-byte aligned, then in |
155 | 8 | // for (i = 0; i < 1024; i += 4) r += a[i]; not all of the loads from a are |
156 | 8 | // 32-byte aligned, but instead alternate between 32 and 16-byte alignment. |
157 | 8 | // As a result, the new alignment will not be a constant, but can still |
158 | 8 | // be improved over the default (of 4) to 16. |
159 | 8 | |
160 | 8 | const SCEV *DiffStartSCEV = DiffARSCEV->getStart(); |
161 | 8 | const SCEV *DiffIncSCEV = DiffARSCEV->getStepRecurrence(*SE); |
162 | 8 | |
163 | 8 | DEBUG(dbgs() << "\ttrying start/inc alignment using start " << |
164 | 8 | *DiffStartSCEV << " and inc " << *DiffIncSCEV << "\n"); |
165 | 8 | |
166 | 8 | // Now compute the new alignment using the displacement to the value in the |
167 | 8 | // first iteration, and also the alignment using the per-iteration delta. |
168 | 8 | // If these are the same, then use that answer. Otherwise, use the smaller |
169 | 8 | // one, but only if it divides the larger one. |
170 | 8 | NewAlignment = getNewAlignmentDiff(DiffStartSCEV, AlignSCEV, SE); |
171 | 8 | unsigned NewIncAlignment = getNewAlignmentDiff(DiffIncSCEV, AlignSCEV, SE); |
172 | 8 | |
173 | 8 | DEBUG(dbgs() << "\tnew start alignment: " << NewAlignment << "\n"); |
174 | 8 | DEBUG(dbgs() << "\tnew inc alignment: " << NewIncAlignment << "\n"); |
175 | 8 | |
176 | 8 | if (!NewAlignment || 8 !NewIncAlignment8 ) { |
177 | 0 | return 0; |
178 | 8 | } else if (8 NewAlignment > NewIncAlignment8 ) { |
179 | 4 | if (NewAlignment % NewIncAlignment == 04 ) { |
180 | 4 | DEBUG(dbgs() << "\tnew start/inc alignment: " << |
181 | 4 | NewIncAlignment << "\n"); |
182 | 4 | return NewIncAlignment; |
183 | 4 | } |
184 | 4 | } else if (4 NewIncAlignment > NewAlignment4 ) { |
185 | 0 | if (NewIncAlignment % NewAlignment == 00 ) { |
186 | 0 | DEBUG(dbgs() << "\tnew start/inc alignment: " << |
187 | 0 | NewAlignment << "\n"); |
188 | 0 | return NewAlignment; |
189 | 0 | } |
190 | 4 | } else if (4 NewIncAlignment == NewAlignment4 ) { |
191 | 4 | DEBUG(dbgs() << "\tnew start/inc alignment: " << |
192 | 8 | NewAlignment << "\n"); |
193 | 8 | return NewAlignment; |
194 | 8 | } |
195 | 8 | } |
196 | 8 | |
197 | 8 | return 0; |
198 | 8 | } |
199 | | |
200 | | bool AlignmentFromAssumptionsPass::extractAlignmentInfo(CallInst *I, |
201 | | Value *&AAPtr, |
202 | | const SCEV *&AlignSCEV, |
203 | 76 | const SCEV *&OffSCEV) { |
204 | 76 | // An alignment assume must be a statement about the least-significant |
205 | 76 | // bits of the pointer being zero, possibly with some offset. |
206 | 76 | ICmpInst *ICI = dyn_cast<ICmpInst>(I->getArgOperand(0)); |
207 | 76 | if (!ICI) |
208 | 4 | return false; |
209 | 72 | |
210 | 72 | // This must be an expression of the form: x & m == 0. |
211 | 72 | if (72 ICI->getPredicate() != ICmpInst::ICMP_EQ72 ) |
212 | 8 | return false; |
213 | 64 | |
214 | 64 | // Swap things around so that the RHS is 0. |
215 | 64 | Value *CmpLHS = ICI->getOperand(0); |
216 | 64 | Value *CmpRHS = ICI->getOperand(1); |
217 | 64 | const SCEV *CmpLHSSCEV = SE->getSCEV(CmpLHS); |
218 | 64 | const SCEV *CmpRHSSCEV = SE->getSCEV(CmpRHS); |
219 | 64 | if (CmpLHSSCEV->isZero()) |
220 | 0 | std::swap(CmpLHS, CmpRHS); |
221 | 64 | else if (64 !CmpRHSSCEV->isZero()64 ) |
222 | 18 | return false; |
223 | 46 | |
224 | 46 | BinaryOperator *CmpBO = dyn_cast<BinaryOperator>(CmpLHS); |
225 | 46 | if (!CmpBO || 46 CmpBO->getOpcode() != Instruction::And46 ) |
226 | 0 | return false; |
227 | 46 | |
228 | 46 | // Swap things around so that the right operand of the and is a constant |
229 | 46 | // (the mask); we cannot deal with variable masks. |
230 | 46 | Value *AndLHS = CmpBO->getOperand(0); |
231 | 46 | Value *AndRHS = CmpBO->getOperand(1); |
232 | 46 | const SCEV *AndLHSSCEV = SE->getSCEV(AndLHS); |
233 | 46 | const SCEV *AndRHSSCEV = SE->getSCEV(AndRHS); |
234 | 46 | if (isa<SCEVConstant>(AndLHSSCEV)46 ) { |
235 | 0 | std::swap(AndLHS, AndRHS); |
236 | 0 | std::swap(AndLHSSCEV, AndRHSSCEV); |
237 | 0 | } |
238 | 46 | |
239 | 46 | const SCEVConstant *MaskSCEV = dyn_cast<SCEVConstant>(AndRHSSCEV); |
240 | 46 | if (!MaskSCEV) |
241 | 0 | return false; |
242 | 46 | |
243 | 46 | // The mask must have some trailing ones (otherwise the condition is |
244 | 46 | // trivial and tells us nothing about the alignment of the left operand). |
245 | 46 | unsigned TrailingOnes = MaskSCEV->getAPInt().countTrailingOnes(); |
246 | 46 | if (!TrailingOnes) |
247 | 0 | return false; |
248 | 46 | |
249 | 46 | // Cap the alignment at the maximum with which LLVM can deal (and make sure |
250 | 46 | // we don't overflow the shift). |
251 | 46 | uint64_t Alignment; |
252 | 46 | TrailingOnes = std::min(TrailingOnes, |
253 | 46 | unsigned(sizeof(unsigned) * CHAR_BIT - 1)); |
254 | 46 | Alignment = std::min(1u << TrailingOnes, +Value::MaximumAlignment); |
255 | 46 | |
256 | 46 | Type *Int64Ty = Type::getInt64Ty(I->getParent()->getParent()->getContext()); |
257 | 46 | AlignSCEV = SE->getConstant(Int64Ty, Alignment); |
258 | 46 | |
259 | 46 | // The LHS might be a ptrtoint instruction, or it might be the pointer |
260 | 46 | // with an offset. |
261 | 46 | AAPtr = nullptr; |
262 | 46 | OffSCEV = nullptr; |
263 | 46 | if (PtrToIntInst *PToI46 = dyn_cast<PtrToIntInst>(AndLHS)) { |
264 | 38 | AAPtr = PToI->getPointerOperand(); |
265 | 38 | OffSCEV = SE->getZero(Int64Ty); |
266 | 46 | } else if (const SCEVAddExpr* 8 AndLHSAddSCEV8 = |
267 | 8 | dyn_cast<SCEVAddExpr>(AndLHSSCEV)) { |
268 | 8 | // Try to find the ptrtoint; subtract it and the rest is the offset. |
269 | 8 | for (SCEVAddExpr::op_iterator J = AndLHSAddSCEV->op_begin(), |
270 | 16 | JE = AndLHSAddSCEV->op_end(); J != JE16 ; ++J8 ) |
271 | 16 | if (const SCEVUnknown *16 OpUnk16 = dyn_cast<SCEVUnknown>(*J)) |
272 | 8 | if (PtrToIntInst *8 PToI8 = dyn_cast<PtrToIntInst>(OpUnk->getValue())) { |
273 | 8 | AAPtr = PToI->getPointerOperand(); |
274 | 8 | OffSCEV = SE->getMinusSCEV(AndLHSAddSCEV, *J); |
275 | 8 | break; |
276 | 8 | } |
277 | 8 | } |
278 | 46 | |
279 | 46 | if (!AAPtr) |
280 | 0 | return false; |
281 | 46 | |
282 | 46 | // Sign extend the offset to 64 bits (so that it is like all of the other |
283 | 46 | // expressions). |
284 | 46 | unsigned OffSCEVBits = OffSCEV->getType()->getPrimitiveSizeInBits(); |
285 | 46 | if (OffSCEVBits < 64) |
286 | 0 | OffSCEV = SE->getSignExtendExpr(OffSCEV, Int64Ty); |
287 | 46 | else if (46 OffSCEVBits > 6446 ) |
288 | 0 | return false; |
289 | 46 | |
290 | 46 | AAPtr = AAPtr->stripPointerCasts(); |
291 | 46 | return true; |
292 | 46 | } |
293 | | |
294 | 76 | bool AlignmentFromAssumptionsPass::processAssumption(CallInst *ACall) { |
295 | 76 | Value *AAPtr; |
296 | 76 | const SCEV *AlignSCEV, *OffSCEV; |
297 | 76 | if (!extractAlignmentInfo(ACall, AAPtr, AlignSCEV, OffSCEV)) |
298 | 30 | return false; |
299 | 46 | |
300 | 46 | // Skip ConstantPointerNull and UndefValue. Assumptions on these shouldn't |
301 | 46 | // affect other users. |
302 | 46 | if (46 isa<ConstantData>(AAPtr)46 ) |
303 | 2 | return false; |
304 | 44 | |
305 | 44 | const SCEV *AASCEV = SE->getSCEV(AAPtr); |
306 | 44 | |
307 | 44 | // Apply the assumption to all other users of the specified pointer. |
308 | 44 | SmallPtrSet<Instruction *, 32> Visited; |
309 | 44 | SmallVector<Instruction*, 16> WorkList; |
310 | 88 | for (User *J : AAPtr->users()) { |
311 | 88 | if (J == ACall) |
312 | 0 | continue; |
313 | 88 | |
314 | 88 | if (Instruction *88 K88 = dyn_cast<Instruction>(J)) |
315 | 88 | if (88 isValidAssumeForContext(ACall, K, DT)88 ) |
316 | 44 | WorkList.push_back(K); |
317 | 88 | } |
318 | 44 | |
319 | 204 | while (!WorkList.empty()204 ) { |
320 | 160 | Instruction *J = WorkList.pop_back_val(); |
321 | 160 | |
322 | 160 | if (LoadInst *LI160 = dyn_cast<LoadInst>(J)) { |
323 | 32 | unsigned NewAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV, |
324 | 32 | LI->getPointerOperand(), SE); |
325 | 32 | |
326 | 32 | if (NewAlignment > LI->getAlignment()32 ) { |
327 | 32 | LI->setAlignment(NewAlignment); |
328 | 32 | ++NumLoadAlignChanged; |
329 | 32 | } |
330 | 160 | } else if (StoreInst *128 SI128 = dyn_cast<StoreInst>(J)) { |
331 | 0 | unsigned NewAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV, |
332 | 0 | SI->getPointerOperand(), SE); |
333 | 0 |
|
334 | 0 | if (NewAlignment > SI->getAlignment()0 ) { |
335 | 0 | SI->setAlignment(NewAlignment); |
336 | 0 | ++NumStoreAlignChanged; |
337 | 0 | } |
338 | 128 | } else if (MemIntrinsic *128 MI128 = dyn_cast<MemIntrinsic>(J)) { |
339 | 12 | unsigned NewDestAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV, |
340 | 12 | MI->getDest(), SE); |
341 | 12 | |
342 | 12 | // For memory transfers, we need a common alignment for both the |
343 | 12 | // source and destination. If we have a new alignment for this |
344 | 12 | // instruction, but only for one operand, save it. If we reach the |
345 | 12 | // other operand through another assumption later, then we may |
346 | 12 | // change the alignment at that point. |
347 | 12 | if (MemTransferInst *MTI12 = dyn_cast<MemTransferInst>(MI)) { |
348 | 8 | unsigned NewSrcAlignment = getNewAlignment(AASCEV, AlignSCEV, OffSCEV, |
349 | 8 | MTI->getSource(), SE); |
350 | 8 | |
351 | 8 | DenseMap<MemTransferInst *, unsigned>::iterator DI = |
352 | 8 | NewDestAlignments.find(MTI); |
353 | 8 | unsigned AltDestAlignment = (DI == NewDestAlignments.end()) ? |
354 | 8 | 04 : DI->second4 ; |
355 | 8 | |
356 | 8 | DenseMap<MemTransferInst *, unsigned>::iterator SI = |
357 | 8 | NewSrcAlignments.find(MTI); |
358 | 8 | unsigned AltSrcAlignment = (SI == NewSrcAlignments.end()) ? |
359 | 8 | 04 : SI->second4 ; |
360 | 8 | |
361 | 8 | DEBUG(dbgs() << "\tmem trans: " << NewDestAlignment << " " << |
362 | 8 | AltDestAlignment << " " << NewSrcAlignment << |
363 | 8 | " " << AltSrcAlignment << "\n"); |
364 | 8 | |
365 | 8 | // Of these four alignments, pick the largest possible... |
366 | 8 | unsigned NewAlignment = 0; |
367 | 8 | if (NewDestAlignment <= std::max(NewSrcAlignment, AltSrcAlignment)) |
368 | 4 | NewAlignment = std::max(NewAlignment, NewDestAlignment); |
369 | 8 | if (AltDestAlignment <= std::max(NewSrcAlignment, AltSrcAlignment)) |
370 | 8 | NewAlignment = std::max(NewAlignment, AltDestAlignment); |
371 | 8 | if (NewSrcAlignment <= std::max(NewDestAlignment, AltDestAlignment)) |
372 | 4 | NewAlignment = std::max(NewAlignment, NewSrcAlignment); |
373 | 8 | if (AltSrcAlignment <= std::max(NewDestAlignment, AltDestAlignment)) |
374 | 8 | NewAlignment = std::max(NewAlignment, AltSrcAlignment); |
375 | 8 | |
376 | 8 | if (NewAlignment > MI->getAlignment()8 ) { |
377 | 4 | MI->setAlignment(ConstantInt::get(Type::getInt32Ty( |
378 | 4 | MI->getParent()->getContext()), NewAlignment)); |
379 | 4 | ++NumMemIntAlignChanged; |
380 | 4 | } |
381 | 8 | |
382 | 8 | NewDestAlignments.insert(std::make_pair(MTI, NewDestAlignment)); |
383 | 8 | NewSrcAlignments.insert(std::make_pair(MTI, NewSrcAlignment)); |
384 | 12 | } else if (4 NewDestAlignment > MI->getAlignment()4 ) { |
385 | 4 | assert((!isa<MemIntrinsic>(MI) || isa<MemSetInst>(MI)) && |
386 | 4 | "Unknown memory intrinsic"); |
387 | 4 | |
388 | 4 | MI->setAlignment(ConstantInt::get(Type::getInt32Ty( |
389 | 4 | MI->getParent()->getContext()), NewDestAlignment)); |
390 | 4 | ++NumMemIntAlignChanged; |
391 | 4 | } |
392 | 128 | } |
393 | 160 | |
394 | 160 | // Now that we've updated that use of the pointer, look for other uses of |
395 | 160 | // the pointer to update. |
396 | 160 | Visited.insert(J); |
397 | 132 | for (User *UJ : J->users()) { |
398 | 132 | Instruction *K = cast<Instruction>(UJ); |
399 | 132 | if (!Visited.count(K) && 132 isValidAssumeForContext(ACall, K, DT)116 ) |
400 | 116 | WorkList.push_back(K); |
401 | 132 | } |
402 | 160 | } |
403 | 76 | |
404 | 76 | return true; |
405 | 76 | } |
406 | | |
407 | 463k | bool AlignmentFromAssumptions::runOnFunction(Function &F) { |
408 | 463k | if (skipFunction(F)) |
409 | 75 | return false; |
410 | 463k | |
411 | 463k | auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F); |
412 | 463k | ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); |
413 | 463k | DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); |
414 | 463k | |
415 | 463k | return Impl.runImpl(F, AC, SE, DT); |
416 | 463k | } |
417 | | |
418 | | bool AlignmentFromAssumptionsPass::runImpl(Function &F, AssumptionCache &AC, |
419 | | ScalarEvolution *SE_, |
420 | 463k | DominatorTree *DT_) { |
421 | 463k | SE = SE_; |
422 | 463k | DT = DT_; |
423 | 463k | |
424 | 463k | NewDestAlignments.clear(); |
425 | 463k | NewSrcAlignments.clear(); |
426 | 463k | |
427 | 463k | bool Changed = false; |
428 | 463k | for (auto &AssumeVH : AC.assumptions()) |
429 | 77 | if (77 AssumeVH77 ) |
430 | 76 | Changed |= processAssumption(cast<CallInst>(AssumeVH)); |
431 | 463k | |
432 | 463k | return Changed; |
433 | 463k | } |
434 | | |
435 | | PreservedAnalyses |
436 | 92 | AlignmentFromAssumptionsPass::run(Function &F, FunctionAnalysisManager &AM) { |
437 | 92 | |
438 | 92 | AssumptionCache &AC = AM.getResult<AssumptionAnalysis>(F); |
439 | 92 | ScalarEvolution &SE = AM.getResult<ScalarEvolutionAnalysis>(F); |
440 | 92 | DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F); |
441 | 92 | if (!runImpl(F, AC, &SE, &DT)) |
442 | 72 | return PreservedAnalyses::all(); |
443 | 20 | |
444 | 20 | PreservedAnalyses PA; |
445 | 20 | PA.preserveSet<CFGAnalyses>(); |
446 | 20 | PA.preserve<AAManager>(); |
447 | 20 | PA.preserve<ScalarEvolutionAnalysis>(); |
448 | 20 | PA.preserve<GlobalsAA>(); |
449 | 20 | return PA; |
450 | 20 | } |