OLD | NEW |
| (Empty) |
1 //===-- AllocaManager.cpp -------------------------------------------------===// | |
2 // | |
3 // The LLVM Compiler Infrastructure | |
4 // | |
5 // This file is distributed under the University of Illinois Open Source | |
6 // License. See LICENSE.TXT for details. | |
7 // | |
8 //===----------------------------------------------------------------------===// | |
9 // | |
10 // This file defines the AllocaManager class. | |
11 // | |
12 // The AllocaManager computes a frame layout, assigning every static alloca an | |
13 // offset. It does alloca liveness analysis in order to reuse stack memory, | |
14 // using lifetime intrinsics. | |
15 // | |
16 //===----------------------------------------------------------------------===// | |
17 | |
18 #define DEBUG_TYPE "allocamanager" | |
19 #include "AllocaManager.h" | |
20 #include "llvm/ADT/STLExtras.h" | |
21 #include "llvm/IR/DataLayout.h" | |
22 #include "llvm/IR/IntrinsicInst.h" | |
23 #include "llvm/IR/Module.h" | |
24 #include "llvm/IR/CFG.h" | |
25 #include "llvm/Support/Debug.h" | |
26 #include "llvm/Support/raw_ostream.h" | |
27 #include "llvm/Support/Timer.h" | |
28 #include "llvm/ADT/Statistic.h" | |
29 using namespace llvm; | |
30 | |
31 STATISTIC(NumAllocas, "Number of allocas eliminated"); | |
32 | |
33 // Return the size of the given alloca. | |
34 uint64_t AllocaManager::getSize(const AllocaInst *AI) { | |
35 assert(AI->isStaticAlloca()); | |
36 return DL->getTypeAllocSize(AI->getAllocatedType()) * | |
37 cast<ConstantInt>(AI->getArraySize())->getValue().getZExtValue(); | |
38 } | |
39 | |
40 // Return the alignment of the given alloca. | |
41 unsigned AllocaManager::getAlignment(const AllocaInst *AI) { | |
42 assert(AI->isStaticAlloca()); | |
43 unsigned Alignment = std::max(AI->getAlignment(), | |
44 DL->getABITypeAlignment(AI->getAllocatedType()))
; | |
45 MaxAlignment = std::max(Alignment, MaxAlignment); | |
46 return Alignment; | |
47 } | |
48 | |
49 AllocaManager::AllocaInfo AllocaManager::getInfo(const AllocaInst *AI) { | |
50 assert(AI->isStaticAlloca()); | |
51 return AllocaInfo(AI, getSize(AI), getAlignment(AI)); | |
52 } | |
53 | |
54 // Given a lifetime_start or lifetime_end intrinsic, determine if it's | |
55 // describing a single pointer suitable for our analysis. If so, | |
56 // return the pointer, otherwise return NULL. | |
57 const Value * | |
58 AllocaManager::getPointerFromIntrinsic(const CallInst *CI) { | |
59 const IntrinsicInst *II = cast<IntrinsicInst>(CI); | |
60 assert(II->getIntrinsicID() == Intrinsic::lifetime_start || | |
61 II->getIntrinsicID() == Intrinsic::lifetime_end); | |
62 | |
63 // Lifetime intrinsics have a size as their first argument and a pointer as | |
64 // their second argument. | |
65 const Value *Size = II->getArgOperand(0); | |
66 const Value *Ptr = II->getArgOperand(1); | |
67 | |
68 // Check to see if we can convert the size to a host integer. If we can't, | |
69 // it's probably not worth worrying about. | |
70 const ConstantInt *SizeCon = dyn_cast<ConstantInt>(Size); | |
71 if (!SizeCon) return NULL; | |
72 const APInt &SizeAP = SizeCon->getValue(); | |
73 if (SizeAP.getActiveBits() > 64) return NULL; | |
74 uint64_t MarkedSize = SizeAP.getZExtValue(); | |
75 | |
76 // Test whether the pointer operand is an alloca. This ought to be pretty | |
77 // simple, but e.g. PRE can decide to PRE bitcasts and no-op geps and | |
78 // split critical edges and insert phis for them, even though it's all | |
79 // just no-ops, so we have to dig through phis to see whether all the | |
80 // inputs are in fact the same pointer after stripping away casts. | |
81 const Value *Result = NULL; | |
82 SmallPtrSet<const PHINode *, 8> VisitedPhis; | |
83 SmallVector<const Value *, 8> Worklist; | |
84 Worklist.push_back(Ptr); | |
85 do { | |
86 const Value *P = Worklist.pop_back_val()->stripPointerCasts(); | |
87 | |
88 if (const PHINode *Phi = dyn_cast<PHINode>(P)) { | |
89 if (!VisitedPhis.insert(Phi).second) | |
90 continue; | |
91 for (unsigned i = 0, e = Phi->getNumOperands(); i < e; ++i) | |
92 Worklist.push_back(Phi->getOperand(i)); | |
93 continue; | |
94 } | |
95 if (const SelectInst *Select = dyn_cast<SelectInst>(P)) { | |
96 Worklist.push_back(Select->getTrueValue()); | |
97 Worklist.push_back(Select->getFalseValue()); | |
98 continue; | |
99 } | |
100 | |
101 if (Result == NULL) | |
102 Result = P; | |
103 else if (Result != P) | |
104 return NULL; | |
105 } while (!Worklist.empty()); | |
106 | |
107 // If it's a static Alloca, make sure the size is suitable. We test this here | |
108 // because if this fails, we need to be as conservative as if we don't know | |
109 // what the pointer is. | |
110 if (const AllocaInst *AI = dyn_cast<AllocaInst>(Result)) { | |
111 if (AI->isStaticAlloca() && MarkedSize < getSize(AI)) | |
112 return NULL; | |
113 } else if (isa<Instruction>(Result)) { | |
114 // And if it's any other kind of non-object/argument, we have to be | |
115 // similarly conservative, because we may be dealing with an escaped alloca | |
116 // that we can't see. | |
117 return NULL; | |
118 } | |
119 | |
120 // Yay, it's all just one Value! | |
121 return Result; | |
122 } | |
123 | |
124 // Test whether the given value is an alloca which we have a hope of | |
125 const AllocaInst *AllocaManager::isFavorableAlloca(const Value *V) { | |
126 const AllocaInst *AI = dyn_cast<AllocaInst>(V); | |
127 if (!AI) return NULL; | |
128 | |
129 if (!AI->isStaticAlloca()) return NULL; | |
130 | |
131 return AI; | |
132 } | |
133 | |
134 int AllocaManager::AllocaSort(const AllocaInfo *li, const AllocaInfo *ri) { | |
135 // Sort by alignment to minimize padding. | |
136 if (li->getAlignment() > ri->getAlignment()) return -1; | |
137 if (li->getAlignment() < ri->getAlignment()) return 1; | |
138 | |
139 // Ensure a stable sort. We can do this because the pointers are | |
140 // pointing into the same array. | |
141 if (li > ri) return -1; | |
142 if (li < ri) return 1; | |
143 | |
144 return 0; | |
145 } | |
146 | |
147 // Collect allocas | |
148 void AllocaManager::collectMarkedAllocas() { | |
149 NamedRegionTimer Timer("Collect Marked Allocas", "AllocaManager", | |
150 TimePassesIsEnabled); | |
151 | |
152 // Weird semantics: If an alloca *ever* appears in a lifetime start or end | |
153 // within the same function, its lifetime begins only at the explicit lifetime | |
154 // starts and ends only at the explicit lifetime ends and function exit | |
155 // points. Otherwise, its lifetime begins in the entry block and it is live | |
156 // everywhere. | |
157 // | |
158 // And so, instead of just walking the entry block to find all the static | |
159 // allocas, we walk the whole body to find the intrinsics so we can find the | |
160 // set of static allocas referenced in the intrinsics. | |
161 for (Function::const_iterator FI = F->begin(), FE = F->end(); | |
162 FI != FE; ++FI) { | |
163 for (BasicBlock::const_iterator BI = FI->begin(), BE = FI->end(); | |
164 BI != BE; ++BI) { | |
165 const CallInst *CI = dyn_cast<CallInst>(BI); | |
166 if (!CI) continue; | |
167 | |
168 const Value *Callee = CI->getCalledValue(); | |
169 if (Callee == LifetimeStart || Callee == LifetimeEnd) { | |
170 if (const Value *Ptr = getPointerFromIntrinsic(CI)) { | |
171 if (const AllocaInst *AI = isFavorableAlloca(Ptr)) | |
172 Allocas.insert(std::make_pair(AI, 0)); | |
173 } else if (isa<Instruction>(CI->getArgOperand(1)->stripPointerCasts()))
{ | |
174 // Oh noes, There's a lifetime intrinsics with something that | |
175 // doesn't appear to resolve to an alloca. This means that it's | |
176 // possible that it may be declaring a lifetime for some escaping | |
177 // alloca. Look out! | |
178 Allocas.clear(); | |
179 assert(AllocasByIndex.empty()); | |
180 return; | |
181 } | |
182 } | |
183 } | |
184 } | |
185 | |
186 // All that said, we still want the intrinsics in the order they appear in the | |
187 // block, so that we can represent later ones with earlier ones and skip | |
188 // worrying about dominance, so run through the entry block and index those | |
189 // allocas which we identified above. | |
190 AllocasByIndex.reserve(Allocas.size()); | |
191 const BasicBlock *EntryBB = &F->getEntryBlock(); | |
192 for (BasicBlock::const_iterator BI = EntryBB->begin(), BE = EntryBB->end(); | |
193 BI != BE; ++BI) { | |
194 const AllocaInst *AI = dyn_cast<AllocaInst>(BI); | |
195 if (!AI || !AI->isStaticAlloca()) continue; | |
196 | |
197 AllocaMap::iterator I = Allocas.find(AI); | |
198 if (I != Allocas.end()) { | |
199 I->second = AllocasByIndex.size(); | |
200 AllocasByIndex.push_back(getInfo(AI)); | |
201 } | |
202 } | |
203 assert(AllocasByIndex.size() == Allocas.size()); | |
204 } | |
205 | |
206 // Calculate the starting point from which inter-block liveness will be | |
207 // computed. | |
208 void AllocaManager::collectBlocks() { | |
209 NamedRegionTimer Timer("Collect Blocks", "AllocaManager", | |
210 TimePassesIsEnabled); | |
211 | |
212 size_t AllocaCount = AllocasByIndex.size(); | |
213 | |
214 BitVector Seen(AllocaCount); | |
215 | |
216 for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I) { | |
217 const BasicBlock *BB = I; | |
218 | |
219 BlockLifetimeInfo &BLI = BlockLiveness[BB]; | |
220 BLI.Start.resize(AllocaCount); | |
221 BLI.End.resize(AllocaCount); | |
222 | |
223 // Track which allocas we've seen. This is used because if a lifetime start | |
224 // is the first lifetime marker for an alloca in a block, the alloca is | |
225 // live-in. | |
226 Seen.reset(); | |
227 | |
228 // Walk the instructions and compute the Start and End sets. | |
229 for (BasicBlock::const_iterator BI = BB->begin(), BE = BB->end(); | |
230 BI != BE; ++BI) { | |
231 const CallInst *CI = dyn_cast<CallInst>(BI); | |
232 if (!CI) continue; | |
233 | |
234 const Value *Callee = CI->getCalledValue(); | |
235 if (Callee == LifetimeStart) { | |
236 if (const Value *Ptr = getPointerFromIntrinsic(CI)) { | |
237 if (const AllocaInst *AI = isFavorableAlloca(Ptr)) { | |
238 AllocaMap::const_iterator MI = Allocas.find(AI); | |
239 if (MI != Allocas.end()) { | |
240 size_t AllocaIndex = MI->second; | |
241 if (!Seen.test(AllocaIndex)) { | |
242 BLI.Start.set(AllocaIndex); | |
243 } | |
244 BLI.End.reset(AllocaIndex); | |
245 Seen.set(AllocaIndex); | |
246 } | |
247 } | |
248 } | |
249 } else if (Callee == LifetimeEnd) { | |
250 if (const Value *Ptr = getPointerFromIntrinsic(CI)) { | |
251 if (const AllocaInst *AI = isFavorableAlloca(Ptr)) { | |
252 AllocaMap::const_iterator MI = Allocas.find(AI); | |
253 if (MI != Allocas.end()) { | |
254 size_t AllocaIndex = MI->second; | |
255 BLI.End.set(AllocaIndex); | |
256 Seen.set(AllocaIndex); | |
257 } | |
258 } | |
259 } | |
260 } | |
261 } | |
262 | |
263 // Lifetimes that start in this block and do not end here are live-out. | |
264 BLI.LiveOut = BLI.Start; | |
265 BLI.LiveOut.reset(BLI.End); | |
266 if (BLI.LiveOut.any()) { | |
267 for (succ_const_iterator SI = succ_begin(BB), SE = succ_end(BB); | |
268 SI != SE; ++SI) { | |
269 InterBlockTopDownWorklist.insert(*SI); | |
270 } | |
271 } | |
272 | |
273 // Lifetimes that end in this block and do not start here are live-in. | |
274 // TODO: Is this actually true? What are the semantics of a standalone | |
275 // lifetime end? See also the code in computeInterBlockLiveness. | |
276 BLI.LiveIn = BLI.End; | |
277 BLI.LiveIn.reset(BLI.Start); | |
278 if (BLI.LiveIn.any()) { | |
279 for (const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB); | |
280 PI != PE; ++PI) { | |
281 InterBlockBottomUpWorklist.insert(*PI); | |
282 } | |
283 } | |
284 } | |
285 } | |
286 | |
287 // Compute the LiveIn and LiveOut sets for each block in F. | |
288 void AllocaManager::computeInterBlockLiveness() { | |
289 NamedRegionTimer Timer("Compute inter-block liveness", "AllocaManager", | |
290 TimePassesIsEnabled); | |
291 | |
292 size_t AllocaCount = AllocasByIndex.size(); | |
293 | |
294 BitVector Temp(AllocaCount); | |
295 | |
296 // Proporgate liveness backwards. | |
297 while (!InterBlockBottomUpWorklist.empty()) { | |
298 const BasicBlock *BB = InterBlockBottomUpWorklist.pop_back_val(); | |
299 BlockLifetimeInfo &BLI = BlockLiveness[BB]; | |
300 | |
301 // Compute the new live-out set. | |
302 for (succ_const_iterator SI = succ_begin(BB), SE = succ_end(BB); | |
303 SI != SE; ++SI) { | |
304 Temp |= BlockLiveness[*SI].LiveIn; | |
305 } | |
306 | |
307 // If it contains new live blocks, prepare to propagate them. | |
308 // TODO: As above, what are the semantics of a standalone lifetime end? | |
309 Temp.reset(BLI.Start); | |
310 if (Temp.test(BLI.LiveIn)) { | |
311 BLI.LiveIn |= Temp; | |
312 for (const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB); | |
313 PI != PE; ++PI) { | |
314 InterBlockBottomUpWorklist.insert(*PI); | |
315 } | |
316 } | |
317 Temp.reset(); | |
318 } | |
319 | |
320 // Proporgate liveness forwards. | |
321 while (!InterBlockTopDownWorklist.empty()) { | |
322 const BasicBlock *BB = InterBlockTopDownWorklist.pop_back_val(); | |
323 BlockLifetimeInfo &BLI = BlockLiveness[BB]; | |
324 | |
325 // Compute the new live-in set. | |
326 for (const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB); | |
327 PI != PE; ++PI) { | |
328 Temp |= BlockLiveness[*PI].LiveOut; | |
329 } | |
330 | |
331 // Also record the live-in values. | |
332 BLI.LiveIn |= Temp; | |
333 | |
334 // If it contains new live blocks, prepare to propagate them. | |
335 Temp.reset(BLI.End); | |
336 if (Temp.test(BLI.LiveOut)) { | |
337 BLI.LiveOut |= Temp; | |
338 for (succ_const_iterator SI = succ_begin(BB), SE = succ_end(BB); | |
339 SI != SE; ++SI) { | |
340 InterBlockTopDownWorklist.insert(*SI); | |
341 } | |
342 } | |
343 Temp.reset(); | |
344 } | |
345 } | |
346 | |
347 // Determine overlapping liveranges within blocks. | |
348 void AllocaManager::computeIntraBlockLiveness() { | |
349 NamedRegionTimer Timer("Compute intra-block liveness", "AllocaManager", | |
350 TimePassesIsEnabled); | |
351 | |
352 size_t AllocaCount = AllocasByIndex.size(); | |
353 | |
354 BitVector Current(AllocaCount); | |
355 | |
356 AllocaCompatibility.resize(AllocaCount, BitVector(AllocaCount, true)); | |
357 | |
358 for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I) { | |
359 const BasicBlock *BB = I; | |
360 const BlockLifetimeInfo &BLI = BlockLiveness[BB]; | |
361 | |
362 Current = BLI.LiveIn; | |
363 | |
364 for (int i = Current.find_first(); i >= 0; i = Current.find_next(i)) { | |
365 AllocaCompatibility[i].reset(Current); | |
366 } | |
367 | |
368 for (BasicBlock::const_iterator BI = BB->begin(), BE = BB->end(); | |
369 BI != BE; ++BI) { | |
370 const CallInst *CI = dyn_cast<CallInst>(BI); | |
371 if (!CI) continue; | |
372 | |
373 const Value *Callee = CI->getCalledValue(); | |
374 if (Callee == LifetimeStart) { | |
375 if (const Value *Ptr = getPointerFromIntrinsic(CI)) { | |
376 if (const AllocaInst *AI = isFavorableAlloca(Ptr)) { | |
377 size_t AIndex = Allocas[AI]; | |
378 // We conflict with everything else that's currently live. | |
379 AllocaCompatibility[AIndex].reset(Current); | |
380 // Everything else that's currently live conflicts with us. | |
381 for (int i = Current.find_first(); i >= 0; i = Current.find_next(i))
{ | |
382 AllocaCompatibility[i].reset(AIndex); | |
383 } | |
384 // We're now live. | |
385 Current.set(AIndex); | |
386 } | |
387 } | |
388 } else if (Callee == LifetimeEnd) { | |
389 if (const Value *Ptr = getPointerFromIntrinsic(CI)) { | |
390 if (const AllocaInst *AI = isFavorableAlloca(Ptr)) { | |
391 size_t AIndex = Allocas[AI]; | |
392 // We're no longer live. | |
393 Current.reset(AIndex); | |
394 } | |
395 } | |
396 } | |
397 } | |
398 } | |
399 } | |
400 | |
401 // Decide which allocas will represent which other allocas, and if so what their | |
402 // size and alignment will need to be. | |
403 void AllocaManager::computeRepresentatives() { | |
404 NamedRegionTimer Timer("Compute Representatives", "AllocaManager", | |
405 TimePassesIsEnabled); | |
406 | |
407 for (size_t i = 0, e = AllocasByIndex.size(); i != e; ++i) { | |
408 // If we've already represented this alloca with another, don't visit it. | |
409 if (AllocasByIndex[i].isForwarded()) continue; | |
410 if (i > size_t(INT_MAX)) continue; | |
411 | |
412 // Find compatible allocas. This is a simple greedy algorithm. | |
413 for (int j = int(i); ; ) { | |
414 assert(j >= int(i)); | |
415 j = AllocaCompatibility[i].find_next(j); | |
416 assert(j != int(i)); | |
417 if (j < 0) break; | |
418 if (!AllocaCompatibility[j][i]) continue; | |
419 | |
420 DEBUG(dbgs() << "Allocas: " | |
421 "Representing " | |
422 << AllocasByIndex[j].getInst()->getName() << " " | |
423 "with " | |
424 << AllocasByIndex[i].getInst()->getName() << "\n"); | |
425 ++NumAllocas; | |
426 | |
427 assert(!AllocasByIndex[j].isForwarded()); | |
428 | |
429 AllocasByIndex[i].mergeSize(AllocasByIndex[j].getSize()); | |
430 AllocasByIndex[i].mergeAlignment(AllocasByIndex[j].getAlignment()); | |
431 AllocasByIndex[j].forward(i); | |
432 | |
433 AllocaCompatibility[i] &= AllocaCompatibility[j]; | |
434 AllocaCompatibility[j].reset(); | |
435 } | |
436 } | |
437 } | |
438 | |
439 void AllocaManager::computeFrameOffsets() { | |
440 NamedRegionTimer Timer("Compute Frame Offsets", "AllocaManager", | |
441 TimePassesIsEnabled); | |
442 | |
443 // Walk through the entry block and collect all the allocas, including the | |
444 // ones with no lifetime markers that we haven't looked at yet. We walk in | |
445 // reverse order so that we can set the representative allocas as those that | |
446 // dominate the others as we go. | |
447 const BasicBlock *EntryBB = &F->getEntryBlock(); | |
448 for (BasicBlock::const_iterator BI = EntryBB->begin(), BE = EntryBB->end(); | |
449 BI != BE; ++BI) { | |
450 const AllocaInst *AI = dyn_cast<AllocaInst>(BI); | |
451 if (!AI || !AI->isStaticAlloca()) continue; | |
452 | |
453 AllocaMap::const_iterator I = Allocas.find(AI); | |
454 if (I != Allocas.end()) { | |
455 // An alloca with lifetime markers. Emit the record we've crafted for it, | |
456 // if we've chosen to keep it as a representative. | |
457 const AllocaInfo &Info = AllocasByIndex[I->second]; | |
458 if (!Info.isForwarded()) { | |
459 SortedAllocas.push_back(Info); | |
460 } | |
461 } else { | |
462 // An alloca with no lifetime markers. | |
463 SortedAllocas.push_back(getInfo(AI)); | |
464 } | |
465 } | |
466 | |
467 // Sort the allocas to hopefully reduce padding. | |
468 array_pod_sort(SortedAllocas.begin(), SortedAllocas.end(), AllocaSort); | |
469 | |
470 // Assign stack offsets. | |
471 uint64_t CurrentOffset = 0; | |
472 for (SmallVectorImpl<AllocaInfo>::const_iterator I = SortedAllocas.begin(), | |
473 E = SortedAllocas.end(); I != E; ++I) { | |
474 const AllocaInfo &Info = *I; | |
475 uint64_t NewOffset = RoundUpToAlignment(CurrentOffset, Info.getAlignment()); | |
476 | |
477 // For backwards compatibility, align every power-of-two multiple alloca to | |
478 // its greatest power-of-two factor, up to 8 bytes. In particular, cube2hash | |
479 // is known to depend on this. | |
480 // TODO: Consider disabling this and making people fix their code. | |
481 if (uint64_t Size = Info.getSize()) { | |
482 uint64_t P2 = uint64_t(1) << countTrailingZeros(Size); | |
483 unsigned CompatAlign = unsigned(std::min(P2, uint64_t(8))); | |
484 NewOffset = RoundUpToAlignment(NewOffset, CompatAlign); | |
485 } | |
486 | |
487 const AllocaInst *AI = Info.getInst(); | |
488 StaticAllocas[AI] = StaticAllocation(AI, NewOffset); | |
489 | |
490 CurrentOffset = NewOffset + Info.getSize(); | |
491 } | |
492 | |
493 // Add allocas that were represented by other allocas to the StaticAllocas map | |
494 // so that our clients can look them up. | |
495 for (unsigned i = 0, e = AllocasByIndex.size(); i != e; ++i) { | |
496 const AllocaInfo &Info = AllocasByIndex[i]; | |
497 if (!Info.isForwarded()) continue; | |
498 size_t j = Info.getForwardedID(); | |
499 assert(!AllocasByIndex[j].isForwarded()); | |
500 | |
501 StaticAllocaMap::const_iterator I = | |
502 StaticAllocas.find(AllocasByIndex[j].getInst()); | |
503 assert(I != StaticAllocas.end()); | |
504 | |
505 std::pair<StaticAllocaMap::const_iterator, bool> Pair = | |
506 StaticAllocas.insert(std::make_pair(AllocasByIndex[i].getInst(), | |
507 I->second)); | |
508 assert(Pair.second); (void)Pair; | |
509 } | |
510 | |
511 // Record the final frame size. Keep the stack pointer 16-byte aligned. | |
512 FrameSize = CurrentOffset; | |
513 FrameSize = RoundUpToAlignment(FrameSize, 16); | |
514 | |
515 DEBUG(dbgs() << "Allocas: " | |
516 "Statically allocated frame size is " << FrameSize << "\n"); | |
517 } | |
518 | |
519 AllocaManager::AllocaManager() : MaxAlignment(0) { | |
520 } | |
521 | |
522 void AllocaManager::analyze(const Function &Func, const DataLayout &Layout, | |
523 bool PerformColoring) { | |
524 NamedRegionTimer Timer("AllocaManager", TimePassesIsEnabled); | |
525 assert(Allocas.empty()); | |
526 assert(AllocasByIndex.empty()); | |
527 assert(AllocaCompatibility.empty()); | |
528 assert(BlockLiveness.empty()); | |
529 assert(StaticAllocas.empty()); | |
530 assert(SortedAllocas.empty()); | |
531 | |
532 DL = &Layout; | |
533 F = &Func; | |
534 | |
535 // Get the declarations for the lifetime intrinsics so we can quickly test to | |
536 // see if they are used at all, and for use later if they are. | |
537 const Module *M = F->getParent(); | |
538 LifetimeStart = M->getFunction(Intrinsic::getName(Intrinsic::lifetime_start)); | |
539 LifetimeEnd = M->getFunction(Intrinsic::getName(Intrinsic::lifetime_end)); | |
540 | |
541 // If we are optimizing and the module contains any lifetime intrinsics, run | |
542 // the alloca coloring algorithm. | |
543 if (PerformColoring && | |
544 ((LifetimeStart && !LifetimeStart->use_empty()) || | |
545 (LifetimeEnd && !LifetimeEnd->use_empty()))) { | |
546 | |
547 collectMarkedAllocas(); | |
548 | |
549 if (!AllocasByIndex.empty()) { | |
550 DEBUG(dbgs() << "Allocas: " | |
551 << AllocasByIndex.size() << " marked allocas found\n"); | |
552 | |
553 collectBlocks(); | |
554 computeInterBlockLiveness(); | |
555 computeIntraBlockLiveness(); | |
556 BlockLiveness.clear(); | |
557 | |
558 computeRepresentatives(); | |
559 AllocaCompatibility.clear(); | |
560 } | |
561 } | |
562 | |
563 computeFrameOffsets(); | |
564 SortedAllocas.clear(); | |
565 Allocas.clear(); | |
566 AllocasByIndex.clear(); | |
567 } | |
568 | |
569 void AllocaManager::clear() { | |
570 StaticAllocas.clear(); | |
571 } | |
572 | |
573 bool | |
574 AllocaManager::getFrameOffset(const AllocaInst *AI, uint64_t *Offset) const { | |
575 assert(AI->isStaticAlloca()); | |
576 StaticAllocaMap::const_iterator I = StaticAllocas.find(AI); | |
577 assert(I != StaticAllocas.end()); | |
578 *Offset = I->second.Offset; | |
579 return AI == I->second.Representative; | |
580 } | |
581 | |
582 const AllocaInst * | |
583 AllocaManager::getRepresentative(const AllocaInst *AI) const { | |
584 assert(AI->isStaticAlloca()); | |
585 StaticAllocaMap::const_iterator I = StaticAllocas.find(AI); | |
586 assert(I != StaticAllocas.end()); | |
587 return I->second.Representative; | |
588 } | |
OLD | NEW |