1 //===- StackLifetime.cpp - Alloca Lifetime Analysis -----------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/Analysis/StackLifetime.h" 10 #include "llvm/ADT/DepthFirstIterator.h" 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/ADT/SmallVector.h" 13 #include "llvm/ADT/StringExtras.h" 14 #include "llvm/Config/llvm-config.h" 15 #include "llvm/IR/AssemblyAnnotationWriter.h" 16 #include "llvm/IR/BasicBlock.h" 17 #include "llvm/IR/CFG.h" 18 #include "llvm/IR/InstIterator.h" 19 #include "llvm/IR/Instructions.h" 20 #include "llvm/IR/IntrinsicInst.h" 21 #include "llvm/IR/Intrinsics.h" 22 #include "llvm/IR/User.h" 23 #include "llvm/IR/Value.h" 24 #include "llvm/Pass.h" 25 #include "llvm/Support/Casting.h" 26 #include "llvm/Support/CommandLine.h" 27 #include "llvm/Support/Compiler.h" 28 #include "llvm/Support/Debug.h" 29 #include "llvm/Support/FormattedStream.h" 30 #include <memory> 31 #include <tuple> 32 33 using namespace llvm; 34 35 #define DEBUG_TYPE "stack-lifetime" 36 37 const StackLifetime::LiveRange & 38 StackLifetime::getLiveRange(const AllocaInst *AI) const { 39 const auto IT = AllocaNumbering.find(AI); 40 assert(IT != AllocaNumbering.end()); 41 return LiveRanges[IT->second]; 42 } 43 44 static bool readMarker(const Instruction *I, bool *IsStart) { 45 if (!I->isLifetimeStartOrEnd()) 46 return false; 47 48 auto *II = cast<IntrinsicInst>(I); 49 *IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start; 50 return true; 51 } 52 53 std::vector<const IntrinsicInst *> StackLifetime::getMarkers() const { 54 std::vector<const IntrinsicInst *> Markers; 55 for (auto &M : InstructionNumbering) 56 if (M.getFirst()->isLifetimeStartOrEnd()) 57 Markers.push_back(M.getFirst()); 58 return Markers; 59 } 60 61 void StackLifetime::collectMarkers() { 62 InterestingAllocas.resize(NumAllocas); 63 DenseMap<const BasicBlock *, SmallDenseMap<const IntrinsicInst *, Marker>> 64 BBMarkerSet; 65 66 // Compute the set of start/end markers per basic block. 67 for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) { 68 const AllocaInst *AI = Allocas[AllocaNo]; 69 SmallVector<const Instruction *, 8> WorkList; 70 WorkList.push_back(AI); 71 while (!WorkList.empty()) { 72 const Instruction *I = WorkList.pop_back_val(); 73 for (const User *U : I->users()) { 74 if (auto *BI = dyn_cast<BitCastInst>(U)) { 75 WorkList.push_back(BI); 76 continue; 77 } 78 auto *UI = dyn_cast<IntrinsicInst>(U); 79 if (!UI) 80 continue; 81 bool IsStart; 82 if (!readMarker(UI, &IsStart)) 83 continue; 84 if (IsStart) 85 InterestingAllocas.set(AllocaNo); 86 BBMarkerSet[UI->getParent()][UI] = {AllocaNo, IsStart}; 87 } 88 } 89 } 90 91 // Compute instruction numbering. Only the following instructions are 92 // considered: 93 // * Basic block entries 94 // * Lifetime markers 95 // For each basic block, compute 96 // * the list of markers in the instruction order 97 // * the sets of allocas whose lifetime starts or ends in this BB 98 LLVM_DEBUG(dbgs() << "Instructions:\n"); 99 unsigned InstNo = 0; 100 for (const BasicBlock *BB : depth_first(&F)) { 101 LLVM_DEBUG(dbgs() << " " << InstNo << ": BB " << BB->getName() << "\n"); 102 unsigned BBStart = InstNo++; 103 104 BlockLifetimeInfo &BlockInfo = 105 BlockLiveness.try_emplace(BB, NumAllocas).first->getSecond(); 106 107 auto &BlockMarkerSet = BBMarkerSet[BB]; 108 if (BlockMarkerSet.empty()) { 109 unsigned BBEnd = InstNo; 110 BlockInstRange[BB] = std::make_pair(BBStart, BBEnd); 111 continue; 112 } 113 114 auto ProcessMarker = [&](const IntrinsicInst *I, const Marker &M) { 115 LLVM_DEBUG(dbgs() << " " << InstNo << ": " 116 << (M.IsStart ? "start " : "end ") << M.AllocaNo 117 << ", " << *I << "\n"); 118 119 BBMarkers[BB].push_back({InstNo, M}); 120 121 InstructionNumbering[I] = InstNo++; 122 123 if (M.IsStart) { 124 BlockInfo.End.reset(M.AllocaNo); 125 BlockInfo.Begin.set(M.AllocaNo); 126 } else { 127 BlockInfo.Begin.reset(M.AllocaNo); 128 BlockInfo.End.set(M.AllocaNo); 129 } 130 }; 131 132 if (BlockMarkerSet.size() == 1) { 133 ProcessMarker(BlockMarkerSet.begin()->getFirst(), 134 BlockMarkerSet.begin()->getSecond()); 135 } else { 136 // Scan the BB to determine the marker order. 137 for (const Instruction &I : *BB) { 138 const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I); 139 if (!II) 140 continue; 141 auto It = BlockMarkerSet.find(II); 142 if (It == BlockMarkerSet.end()) 143 continue; 144 ProcessMarker(II, It->getSecond()); 145 } 146 } 147 148 unsigned BBEnd = InstNo; 149 BlockInstRange[BB] = std::make_pair(BBStart, BBEnd); 150 } 151 NumInst = InstNo; 152 } 153 154 void StackLifetime::calculateLocalLiveness() { 155 bool Changed = true; 156 while (Changed) { 157 Changed = false; 158 159 for (const BasicBlock *BB : depth_first(&F)) { 160 BlockLifetimeInfo &BlockInfo = BlockLiveness.find(BB)->getSecond(); 161 162 // Compute LiveIn by unioning together the LiveOut sets of all preds. 163 BitVector LocalLiveIn; 164 for (auto *PredBB : predecessors(BB)) { 165 LivenessMap::const_iterator I = BlockLiveness.find(PredBB); 166 // If a predecessor is unreachable, ignore it. 167 if (I == BlockLiveness.end()) 168 continue; 169 switch (Type) { 170 case LivenessType::May: 171 LocalLiveIn |= I->second.LiveOut; 172 break; 173 case LivenessType::Must: 174 if (LocalLiveIn.empty()) 175 LocalLiveIn = I->second.LiveOut; 176 else 177 LocalLiveIn &= I->second.LiveOut; 178 break; 179 } 180 } 181 182 // Compute LiveOut by subtracting out lifetimes that end in this 183 // block, then adding in lifetimes that begin in this block. If 184 // we have both BEGIN and END markers in the same basic block 185 // then we know that the BEGIN marker comes after the END, 186 // because we already handle the case where the BEGIN comes 187 // before the END when collecting the markers (and building the 188 // BEGIN/END vectors). 189 BitVector LocalLiveOut = LocalLiveIn; 190 LocalLiveOut.reset(BlockInfo.End); 191 LocalLiveOut |= BlockInfo.Begin; 192 193 // Update block LiveIn set, noting whether it has changed. 194 if (LocalLiveIn.test(BlockInfo.LiveIn)) { 195 Changed = true; 196 BlockInfo.LiveIn |= LocalLiveIn; 197 } 198 199 // Update block LiveOut set, noting whether it has changed. 200 if (LocalLiveOut.test(BlockInfo.LiveOut)) { 201 Changed = true; 202 BlockInfo.LiveOut |= LocalLiveOut; 203 } 204 } 205 } // while changed. 206 } 207 208 void StackLifetime::calculateLiveIntervals() { 209 for (auto IT : BlockLiveness) { 210 const BasicBlock *BB = IT.getFirst(); 211 BlockLifetimeInfo &BlockInfo = IT.getSecond(); 212 unsigned BBStart, BBEnd; 213 std::tie(BBStart, BBEnd) = BlockInstRange[BB]; 214 215 BitVector Started, Ended; 216 Started.resize(NumAllocas); 217 Ended.resize(NumAllocas); 218 SmallVector<unsigned, 8> Start; 219 Start.resize(NumAllocas); 220 221 // LiveIn ranges start at the first instruction. 222 for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) { 223 if (BlockInfo.LiveIn.test(AllocaNo)) { 224 Started.set(AllocaNo); 225 Start[AllocaNo] = BBStart; 226 } 227 } 228 229 for (auto &It : BBMarkers[BB]) { 230 unsigned InstNo = It.first; 231 bool IsStart = It.second.IsStart; 232 unsigned AllocaNo = It.second.AllocaNo; 233 234 if (IsStart) { 235 assert(!Started.test(AllocaNo) || Start[AllocaNo] == BBStart); 236 if (!Started.test(AllocaNo)) { 237 Started.set(AllocaNo); 238 Ended.reset(AllocaNo); 239 Start[AllocaNo] = InstNo; 240 } 241 } else { 242 assert(!Ended.test(AllocaNo)); 243 if (Started.test(AllocaNo)) { 244 LiveRanges[AllocaNo].addRange(Start[AllocaNo], InstNo); 245 Started.reset(AllocaNo); 246 } 247 Ended.set(AllocaNo); 248 } 249 } 250 251 for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) 252 if (Started.test(AllocaNo)) 253 LiveRanges[AllocaNo].addRange(Start[AllocaNo], BBEnd); 254 } 255 } 256 257 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 258 LLVM_DUMP_METHOD void StackLifetime::dumpAllocas() const { 259 dbgs() << "Allocas:\n"; 260 for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) 261 dbgs() << " " << AllocaNo << ": " << *Allocas[AllocaNo] << "\n"; 262 } 263 264 LLVM_DUMP_METHOD void StackLifetime::dumpBlockLiveness() const { 265 dbgs() << "Block liveness:\n"; 266 for (auto IT : BlockLiveness) { 267 const BasicBlock *BB = IT.getFirst(); 268 const BlockLifetimeInfo &BlockInfo = BlockLiveness.find(BB)->getSecond(); 269 auto BlockRange = BlockInstRange.find(BB)->getSecond(); 270 dbgs() << " BB [" << BlockRange.first << ", " << BlockRange.second 271 << "): begin " << BlockInfo.Begin << ", end " << BlockInfo.End 272 << ", livein " << BlockInfo.LiveIn << ", liveout " 273 << BlockInfo.LiveOut << "\n"; 274 } 275 } 276 277 LLVM_DUMP_METHOD void StackLifetime::dumpLiveRanges() const { 278 dbgs() << "Alloca liveness:\n"; 279 for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) 280 dbgs() << " " << AllocaNo << ": " << LiveRanges[AllocaNo] << "\n"; 281 } 282 #endif 283 284 StackLifetime::StackLifetime(const Function &F, 285 ArrayRef<const AllocaInst *> Allocas, 286 LivenessType Type) 287 : F(F), Type(Type), Allocas(Allocas), NumAllocas(Allocas.size()) { 288 LLVM_DEBUG(dumpAllocas()); 289 290 for (unsigned I = 0; I < NumAllocas; ++I) 291 AllocaNumbering[Allocas[I]] = I; 292 293 collectMarkers(); 294 } 295 296 void StackLifetime::run() { 297 LiveRanges.resize(NumAllocas, LiveRange(NumInst)); 298 for (unsigned I = 0; I < NumAllocas; ++I) 299 if (!InterestingAllocas.test(I)) 300 LiveRanges[I] = getFullLiveRange(); 301 302 calculateLocalLiveness(); 303 LLVM_DEBUG(dumpBlockLiveness()); 304 calculateLiveIntervals(); 305 LLVM_DEBUG(dumpLiveRanges()); 306 } 307 308 class StackLifetime::LifetimeAnnotationWriter 309 : public AssemblyAnnotationWriter { 310 const StackLifetime &SL; 311 SmallVector<StringRef, 16> Names; 312 313 void printInstrAlive(unsigned InstrNo, formatted_raw_ostream &OS) { 314 Names.clear(); 315 for (const auto &KV : SL.AllocaNumbering) { 316 if (SL.LiveRanges[KV.getSecond()].test(InstrNo)) 317 Names.push_back(KV.getFirst()->getName()); 318 } 319 llvm::sort(Names); 320 OS << " ; Alive: <" << llvm::join(Names, " ") << ">\n"; 321 } 322 323 void printBBAlive(const BasicBlock *BB, bool Start, 324 formatted_raw_ostream &OS) { 325 auto ItBB = SL.BlockInstRange.find(BB); 326 if (ItBB == SL.BlockInstRange.end()) 327 return; // Unreachable. 328 unsigned InstrNo = 329 Start ? ItBB->getSecond().first : (ItBB->getSecond().second - 1); 330 printInstrAlive(InstrNo, OS); 331 } 332 333 void emitBasicBlockStartAnnot(const BasicBlock *BB, 334 formatted_raw_ostream &OS) override { 335 printBBAlive(BB, true, OS); 336 } 337 void emitBasicBlockEndAnnot(const BasicBlock *BB, 338 formatted_raw_ostream &OS) override { 339 printBBAlive(BB, false, OS); 340 } 341 342 void printInfoComment(const Value &V, formatted_raw_ostream &OS) override { 343 auto It = SL.InstructionNumbering.find(dyn_cast<IntrinsicInst>(&V)); 344 if (It == SL.InstructionNumbering.end()) 345 return; // Unintresting. 346 OS << "\n"; 347 printInstrAlive(It->getSecond(), OS); 348 } 349 350 public: 351 LifetimeAnnotationWriter(const StackLifetime &SL) : SL(SL) {} 352 }; 353 354 void StackLifetime::print(raw_ostream &OS) { 355 LifetimeAnnotationWriter AAW(*this); 356 F.print(OS, &AAW); 357 } 358 359 PreservedAnalyses StackLifetimePrinterPass::run(Function &F, 360 FunctionAnalysisManager &AM) { 361 SmallVector<const AllocaInst *, 8> Allocas; 362 for (auto &I : instructions(F)) 363 if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) 364 Allocas.push_back(AI); 365 StackLifetime SL(F, Allocas, Type); 366 SL.run(); 367 SL.print(OS); 368 return PreservedAnalyses::all(); 369 } 370