| 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 |