OLD | NEW |
| (Empty) |
1 //===-- AllocaManager.h ---------------------------------------------------===// | |
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 pass declares the AllocaManager class. | |
11 // | |
12 //===----------------------------------------------------------------------===// | |
13 | |
14 #ifndef JSBACKEND_ALLOCAMANAGER_H | |
15 #define JSBACKEND_ALLOCAMANAGER_H | |
16 | |
17 #include "llvm/ADT/BitVector.h" | |
18 #include "llvm/ADT/DenseMap.h" | |
19 #include "llvm/ADT/SmallVector.h" | |
20 #include "llvm/ADT/SetVector.h" | |
21 | |
22 namespace llvm { | |
23 | |
24 class AllocaInst; | |
25 class BasicBlock; | |
26 class CallInst; | |
27 class DataLayout; | |
28 class Function; | |
29 class Value; | |
30 | |
31 /// Compute frame layout for allocas. | |
32 class AllocaManager { | |
33 const DataLayout *DL; | |
34 const Function *LifetimeStart; | |
35 const Function *LifetimeEnd; | |
36 const Function *F; | |
37 | |
38 // Per-block lifetime information. | |
39 struct BlockLifetimeInfo { | |
40 BitVector Start; | |
41 BitVector End; | |
42 BitVector LiveIn; | |
43 BitVector LiveOut; | |
44 }; | |
45 typedef DenseMap<const BasicBlock *, BlockLifetimeInfo> LivenessMap; | |
46 LivenessMap BlockLiveness; | |
47 | |
48 // Worklist for inter-block liveness analysis. | |
49 typedef SmallSetVector<const BasicBlock *, 8> InterBlockWorklistVec; | |
50 InterBlockWorklistVec InterBlockTopDownWorklist; | |
51 InterBlockWorklistVec InterBlockBottomUpWorklist; | |
52 | |
53 // Map allocas to their index in AllocasByIndex. | |
54 typedef DenseMap<const AllocaInst *, size_t> AllocaMap; | |
55 AllocaMap Allocas; | |
56 | |
57 // Information about an alloca. Note that the size and alignment may vary | |
58 // from what's in the actual AllocaInst when an alloca is also representing | |
59 // another with perhaps greater size and/or alignment needs. | |
60 // | |
61 // When an alloca is represented by another, its AllocaInfo is marked as | |
62 // "forwarded", at which point it no longer holds a size and alignment, but | |
63 // the index of the representative AllocaInfo. | |
64 class AllocaInfo { | |
65 const AllocaInst *Inst; | |
66 uint64_t Size; | |
67 unsigned Alignment; | |
68 | |
69 public: | |
70 AllocaInfo(const AllocaInst *I, uint64_t S, unsigned A) | |
71 : Inst(I), Size(S), Alignment(A) { | |
72 assert(I != NULL); | |
73 assert(A != 0); | |
74 assert(!isForwarded()); | |
75 } | |
76 | |
77 bool isForwarded() const { return Alignment == 0; } | |
78 | |
79 size_t getForwardedID() const { | |
80 assert(isForwarded()); | |
81 return static_cast<size_t>(Size); | |
82 } | |
83 | |
84 void forward(size_t i) { | |
85 assert(!isForwarded()); | |
86 Alignment = 0; | |
87 Size = i; | |
88 assert(isForwarded()); | |
89 assert(getForwardedID() == i); | |
90 } | |
91 | |
92 const AllocaInst *getInst() const { return Inst; } | |
93 | |
94 uint64_t getSize() const { assert(!isForwarded()); return Size; } | |
95 unsigned getAlignment() const { assert(!isForwarded()); return Alignment; } | |
96 | |
97 void mergeSize(uint64_t S) { | |
98 assert(!isForwarded()); | |
99 Size = std::max(Size, S); | |
100 assert(!isForwarded()); | |
101 } | |
102 void mergeAlignment(unsigned A) { | |
103 assert(A != 0); | |
104 assert(!isForwarded()); | |
105 Alignment = std::max(Alignment, A); | |
106 assert(!isForwarded()); | |
107 } | |
108 }; | |
109 typedef SmallVector<AllocaInfo, 32> AllocaVec; | |
110 AllocaVec AllocasByIndex; | |
111 | |
112 // For each alloca, which allocas can it safely represent? Allocas are | |
113 // identified by AllocasByIndex index. | |
114 // TODO: Vector-of-vectors isn't the fastest data structure possible here. | |
115 typedef SmallVector<BitVector, 32> AllocaCompatibilityVec; | |
116 AllocaCompatibilityVec AllocaCompatibility; | |
117 | |
118 // This is for allocas that will eventually be sorted. | |
119 SmallVector<AllocaInfo, 32> SortedAllocas; | |
120 | |
121 // Static allocation results. | |
122 struct StaticAllocation { | |
123 const AllocaInst *Representative; | |
124 uint64_t Offset; | |
125 StaticAllocation() {} | |
126 StaticAllocation(const AllocaInst *A, uint64_t O) | |
127 : Representative(A), Offset(O) {} | |
128 }; | |
129 typedef DenseMap<const AllocaInst *, StaticAllocation> StaticAllocaMap; | |
130 StaticAllocaMap StaticAllocas; | |
131 uint64_t FrameSize; | |
132 | |
133 uint64_t getSize(const AllocaInst *AI); | |
134 unsigned getAlignment(const AllocaInst *AI); | |
135 AllocaInfo getInfo(const AllocaInst *AI); | |
136 const Value *getPointerFromIntrinsic(const CallInst *CI); | |
137 const AllocaInst *isFavorableAlloca(const Value *V); | |
138 static int AllocaSort(const AllocaInfo *l, const AllocaInfo *r); | |
139 | |
140 void collectMarkedAllocas(); | |
141 void collectBlocks(); | |
142 void computeInterBlockLiveness(); | |
143 void computeIntraBlockLiveness(); | |
144 void computeRepresentatives(); | |
145 void computeFrameOffsets(); | |
146 | |
147 unsigned MaxAlignment; | |
148 | |
149 public: | |
150 AllocaManager(); | |
151 | |
152 /// Analyze the given function and prepare for getRepresentative queries. | |
153 void analyze(const Function &Func, const DataLayout &Layout, | |
154 bool PerformColoring); | |
155 | |
156 /// Reset all stored state. | |
157 void clear(); | |
158 | |
159 /// Return the representative alloca for the given alloca. When allocas are | |
160 /// merged, one is chosen as the representative to stand for the rest. | |
161 /// References to the alloca should take the form of references to the | |
162 /// representative. | |
163 const AllocaInst *getRepresentative(const AllocaInst *AI) const; | |
164 | |
165 /// Set *offset to the frame offset for the given alloca. Return true if the | |
166 /// given alloca is representative, meaning that it needs an explicit | |
167 /// definition in the function entry. Return false if some other alloca | |
168 /// represents this one. | |
169 bool getFrameOffset(const AllocaInst *AI, uint64_t *offset) const; | |
170 | |
171 /// Return the total frame size for all static allocas and associated padding. | |
172 uint64_t getFrameSize() const { return FrameSize; } | |
173 | |
174 /// Return the largest alignment seen. | |
175 unsigned getMaxAlignment() const { return MaxAlignment; } | |
176 }; | |
177 | |
178 } // namespace llvm | |
179 | |
180 #endif | |
OLD | NEW |