StackLifetime.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  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. #include "llvm/Analysis/StackLifetime.h"
  9. #include "llvm/ADT/DepthFirstIterator.h"
  10. #include "llvm/ADT/STLExtras.h"
  11. #include "llvm/ADT/SmallVector.h"
  12. #include "llvm/ADT/StringExtras.h"
  13. #include "llvm/Analysis/ValueTracking.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/Value.h"
  22. #include "llvm/Support/Casting.h"
  23. #include "llvm/Support/Compiler.h"
  24. #include "llvm/Support/Debug.h"
  25. #include "llvm/Support/FormattedStream.h"
  26. #include <algorithm>
  27. #include <tuple>
  28. using namespace llvm;
  29. #define DEBUG_TYPE "stack-lifetime"
  30. const StackLifetime::LiveRange &
  31. StackLifetime::getLiveRange(const AllocaInst *AI) const {
  32. const auto IT = AllocaNumbering.find(AI);
  33. assert(IT != AllocaNumbering.end());
  34. return LiveRanges[IT->second];
  35. }
  36. bool StackLifetime::isReachable(const Instruction *I) const {
  37. return BlockInstRange.find(I->getParent()) != BlockInstRange.end();
  38. }
  39. bool StackLifetime::isAliveAfter(const AllocaInst *AI,
  40. const Instruction *I) const {
  41. const BasicBlock *BB = I->getParent();
  42. auto ItBB = BlockInstRange.find(BB);
  43. assert(ItBB != BlockInstRange.end() && "Unreachable is not expected");
  44. // Search the block for the first instruction following 'I'.
  45. auto It = std::upper_bound(Instructions.begin() + ItBB->getSecond().first + 1,
  46. Instructions.begin() + ItBB->getSecond().second, I,
  47. [](const Instruction *L, const Instruction *R) {
  48. return L->comesBefore(R);
  49. });
  50. --It;
  51. unsigned InstNum = It - Instructions.begin();
  52. return getLiveRange(AI).test(InstNum);
  53. }
  54. // Returns unique alloca annotated by lifetime marker only if
  55. // markers has the same size and points to the alloca start.
  56. static const AllocaInst *findMatchingAlloca(const IntrinsicInst &II,
  57. const DataLayout &DL) {
  58. const AllocaInst *AI = findAllocaForValue(II.getArgOperand(1), true);
  59. if (!AI)
  60. return nullptr;
  61. auto AllocaSize = AI->getAllocationSize(DL);
  62. if (!AllocaSize)
  63. return nullptr;
  64. auto *Size = dyn_cast<ConstantInt>(II.getArgOperand(0));
  65. if (!Size)
  66. return nullptr;
  67. int64_t LifetimeSize = Size->getSExtValue();
  68. if (LifetimeSize != -1 && uint64_t(LifetimeSize) != *AllocaSize)
  69. return nullptr;
  70. return AI;
  71. }
  72. void StackLifetime::collectMarkers() {
  73. InterestingAllocas.resize(NumAllocas);
  74. DenseMap<const BasicBlock *, SmallDenseMap<const IntrinsicInst *, Marker>>
  75. BBMarkerSet;
  76. const DataLayout &DL = F.getParent()->getDataLayout();
  77. // Compute the set of start/end markers per basic block.
  78. for (const BasicBlock *BB : depth_first(&F)) {
  79. for (const Instruction &I : *BB) {
  80. const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
  81. if (!II || !II->isLifetimeStartOrEnd())
  82. continue;
  83. const AllocaInst *AI = findMatchingAlloca(*II, DL);
  84. if (!AI) {
  85. HasUnknownLifetimeStartOrEnd = true;
  86. continue;
  87. }
  88. auto It = AllocaNumbering.find(AI);
  89. if (It == AllocaNumbering.end())
  90. continue;
  91. auto AllocaNo = It->second;
  92. bool IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start;
  93. if (IsStart)
  94. InterestingAllocas.set(AllocaNo);
  95. BBMarkerSet[BB][II] = {AllocaNo, IsStart};
  96. }
  97. }
  98. // Compute instruction numbering. Only the following instructions are
  99. // considered:
  100. // * Basic block entries
  101. // * Lifetime markers
  102. // For each basic block, compute
  103. // * the list of markers in the instruction order
  104. // * the sets of allocas whose lifetime starts or ends in this BB
  105. LLVM_DEBUG(dbgs() << "Instructions:\n");
  106. for (const BasicBlock *BB : depth_first(&F)) {
  107. LLVM_DEBUG(dbgs() << " " << Instructions.size() << ": BB " << BB->getName()
  108. << "\n");
  109. auto BBStart = Instructions.size();
  110. Instructions.push_back(nullptr);
  111. BlockLifetimeInfo &BlockInfo =
  112. BlockLiveness.try_emplace(BB, NumAllocas).first->getSecond();
  113. auto &BlockMarkerSet = BBMarkerSet[BB];
  114. if (BlockMarkerSet.empty()) {
  115. BlockInstRange[BB] = std::make_pair(BBStart, Instructions.size());
  116. continue;
  117. }
  118. auto ProcessMarker = [&](const IntrinsicInst *I, const Marker &M) {
  119. LLVM_DEBUG(dbgs() << " " << Instructions.size() << ": "
  120. << (M.IsStart ? "start " : "end ") << M.AllocaNo
  121. << ", " << *I << "\n");
  122. BBMarkers[BB].push_back({Instructions.size(), M});
  123. Instructions.push_back(I);
  124. if (M.IsStart) {
  125. BlockInfo.End.reset(M.AllocaNo);
  126. BlockInfo.Begin.set(M.AllocaNo);
  127. } else {
  128. BlockInfo.Begin.reset(M.AllocaNo);
  129. BlockInfo.End.set(M.AllocaNo);
  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. BlockInstRange[BB] = std::make_pair(BBStart, Instructions.size());
  148. }
  149. }
  150. void StackLifetime::calculateLocalLiveness() {
  151. bool Changed = true;
  152. // LiveIn, LiveOut and BitsIn have a different meaning deppends on type.
  153. // ::Maybe true bits represent "may be alive" allocas, ::Must true bits
  154. // represent "may be dead". After the loop we will convert ::Must bits from
  155. // "may be dead" to "must be alive".
  156. while (Changed) {
  157. // TODO: Consider switching to worklist instead of traversing entire graph.
  158. Changed = false;
  159. for (const BasicBlock *BB : depth_first(&F)) {
  160. BlockLifetimeInfo &BlockInfo = BlockLiveness.find(BB)->getSecond();
  161. // Compute BitsIn by unioning together the LiveOut sets of all preds.
  162. BitVector BitsIn;
  163. for (const auto *PredBB : predecessors(BB)) {
  164. LivenessMap::const_iterator I = BlockLiveness.find(PredBB);
  165. // If a predecessor is unreachable, ignore it.
  166. if (I == BlockLiveness.end())
  167. continue;
  168. BitsIn |= I->second.LiveOut;
  169. }
  170. // Everything is "may be dead" for entry without predecessors.
  171. if (Type == LivenessType::Must && BitsIn.empty())
  172. BitsIn.resize(NumAllocas, true);
  173. // Update block LiveIn set, noting whether it has changed.
  174. if (BitsIn.test(BlockInfo.LiveIn)) {
  175. BlockInfo.LiveIn |= BitsIn;
  176. }
  177. // Compute LiveOut by subtracting out lifetimes that end in this
  178. // block, then adding in lifetimes that begin in this block. If
  179. // we have both BEGIN and END markers in the same basic block
  180. // then we know that the BEGIN marker comes after the END,
  181. // because we already handle the case where the BEGIN comes
  182. // before the END when collecting the markers (and building the
  183. // BEGIN/END vectors).
  184. switch (Type) {
  185. case LivenessType::May:
  186. BitsIn.reset(BlockInfo.End);
  187. // "may be alive" is set by lifetime start.
  188. BitsIn |= BlockInfo.Begin;
  189. break;
  190. case LivenessType::Must:
  191. BitsIn.reset(BlockInfo.Begin);
  192. // "may be dead" is set by lifetime end.
  193. BitsIn |= BlockInfo.End;
  194. break;
  195. }
  196. // Update block LiveOut set, noting whether it has changed.
  197. if (BitsIn.test(BlockInfo.LiveOut)) {
  198. Changed = true;
  199. BlockInfo.LiveOut |= BitsIn;
  200. }
  201. }
  202. } // while changed.
  203. if (Type == LivenessType::Must) {
  204. // Convert from "may be dead" to "must be alive".
  205. for (auto &[BB, BlockInfo] : BlockLiveness) {
  206. BlockInfo.LiveIn.flip();
  207. BlockInfo.LiveOut.flip();
  208. }
  209. }
  210. }
  211. void StackLifetime::calculateLiveIntervals() {
  212. for (auto IT : BlockLiveness) {
  213. const BasicBlock *BB = IT.getFirst();
  214. BlockLifetimeInfo &BlockInfo = IT.getSecond();
  215. unsigned BBStart, BBEnd;
  216. std::tie(BBStart, BBEnd) = BlockInstRange[BB];
  217. BitVector Started, Ended;
  218. Started.resize(NumAllocas);
  219. Ended.resize(NumAllocas);
  220. SmallVector<unsigned, 8> Start;
  221. Start.resize(NumAllocas);
  222. // LiveIn ranges start at the first instruction.
  223. for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) {
  224. if (BlockInfo.LiveIn.test(AllocaNo)) {
  225. Started.set(AllocaNo);
  226. Start[AllocaNo] = BBStart;
  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. if (IsStart) {
  234. if (!Started.test(AllocaNo)) {
  235. Started.set(AllocaNo);
  236. Ended.reset(AllocaNo);
  237. Start[AllocaNo] = InstNo;
  238. }
  239. } else {
  240. if (Started.test(AllocaNo)) {
  241. LiveRanges[AllocaNo].addRange(Start[AllocaNo], InstNo);
  242. Started.reset(AllocaNo);
  243. }
  244. Ended.set(AllocaNo);
  245. }
  246. }
  247. for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo)
  248. if (Started.test(AllocaNo))
  249. LiveRanges[AllocaNo].addRange(Start[AllocaNo], BBEnd);
  250. }
  251. }
  252. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  253. LLVM_DUMP_METHOD void StackLifetime::dumpAllocas() const {
  254. dbgs() << "Allocas:\n";
  255. for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo)
  256. dbgs() << " " << AllocaNo << ": " << *Allocas[AllocaNo] << "\n";
  257. }
  258. LLVM_DUMP_METHOD void StackLifetime::dumpBlockLiveness() const {
  259. dbgs() << "Block liveness:\n";
  260. for (auto IT : BlockLiveness) {
  261. const BasicBlock *BB = IT.getFirst();
  262. const BlockLifetimeInfo &BlockInfo = BlockLiveness.find(BB)->getSecond();
  263. auto BlockRange = BlockInstRange.find(BB)->getSecond();
  264. dbgs() << " BB (" << BB->getName() << ") [" << BlockRange.first << ", " << BlockRange.second
  265. << "): begin " << BlockInfo.Begin << ", end " << BlockInfo.End
  266. << ", livein " << BlockInfo.LiveIn << ", liveout "
  267. << BlockInfo.LiveOut << "\n";
  268. }
  269. }
  270. LLVM_DUMP_METHOD void StackLifetime::dumpLiveRanges() const {
  271. dbgs() << "Alloca liveness:\n";
  272. for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo)
  273. dbgs() << " " << AllocaNo << ": " << LiveRanges[AllocaNo] << "\n";
  274. }
  275. #endif
  276. StackLifetime::StackLifetime(const Function &F,
  277. ArrayRef<const AllocaInst *> Allocas,
  278. LivenessType Type)
  279. : F(F), Type(Type), Allocas(Allocas), NumAllocas(Allocas.size()) {
  280. LLVM_DEBUG(dumpAllocas());
  281. for (unsigned I = 0; I < NumAllocas; ++I)
  282. AllocaNumbering[Allocas[I]] = I;
  283. collectMarkers();
  284. }
  285. void StackLifetime::run() {
  286. if (HasUnknownLifetimeStartOrEnd) {
  287. // There is marker which we can't assign to a specific alloca, so we
  288. // fallback to the most conservative results for the type.
  289. switch (Type) {
  290. case LivenessType::May:
  291. LiveRanges.resize(NumAllocas, getFullLiveRange());
  292. break;
  293. case LivenessType::Must:
  294. LiveRanges.resize(NumAllocas, LiveRange(Instructions.size()));
  295. break;
  296. }
  297. return;
  298. }
  299. LiveRanges.resize(NumAllocas, LiveRange(Instructions.size()));
  300. for (unsigned I = 0; I < NumAllocas; ++I)
  301. if (!InterestingAllocas.test(I))
  302. LiveRanges[I] = getFullLiveRange();
  303. calculateLocalLiveness();
  304. LLVM_DEBUG(dumpBlockLiveness());
  305. calculateLiveIntervals();
  306. LLVM_DEBUG(dumpLiveRanges());
  307. }
  308. class StackLifetime::LifetimeAnnotationWriter
  309. : public AssemblyAnnotationWriter {
  310. const StackLifetime &SL;
  311. void printInstrAlive(unsigned InstrNo, formatted_raw_ostream &OS) {
  312. SmallVector<StringRef, 16> Names;
  313. for (const auto &KV : SL.AllocaNumbering) {
  314. if (SL.LiveRanges[KV.getSecond()].test(InstrNo))
  315. Names.push_back(KV.getFirst()->getName());
  316. }
  317. llvm::sort(Names);
  318. OS << " ; Alive: <" << llvm::join(Names, " ") << ">\n";
  319. }
  320. void emitBasicBlockStartAnnot(const BasicBlock *BB,
  321. formatted_raw_ostream &OS) override {
  322. auto ItBB = SL.BlockInstRange.find(BB);
  323. if (ItBB == SL.BlockInstRange.end())
  324. return; // Unreachable.
  325. printInstrAlive(ItBB->getSecond().first, OS);
  326. }
  327. void printInfoComment(const Value &V, formatted_raw_ostream &OS) override {
  328. const Instruction *Instr = dyn_cast<Instruction>(&V);
  329. if (!Instr || !SL.isReachable(Instr))
  330. return;
  331. SmallVector<StringRef, 16> Names;
  332. for (const auto &KV : SL.AllocaNumbering) {
  333. if (SL.isAliveAfter(KV.getFirst(), Instr))
  334. Names.push_back(KV.getFirst()->getName());
  335. }
  336. llvm::sort(Names);
  337. OS << "\n ; Alive: <" << llvm::join(Names, " ") << ">\n";
  338. }
  339. public:
  340. LifetimeAnnotationWriter(const StackLifetime &SL) : SL(SL) {}
  341. };
  342. void StackLifetime::print(raw_ostream &OS) {
  343. LifetimeAnnotationWriter AAW(*this);
  344. F.print(OS, &AAW);
  345. }
  346. PreservedAnalyses StackLifetimePrinterPass::run(Function &F,
  347. FunctionAnalysisManager &AM) {
  348. SmallVector<const AllocaInst *, 8> Allocas;
  349. for (auto &I : instructions(F))
  350. if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I))
  351. Allocas.push_back(AI);
  352. StackLifetime SL(F, Allocas, Type);
  353. SL.run();
  354. SL.print(OS);
  355. return PreservedAnalyses::all();
  356. }
  357. void StackLifetimePrinterPass::printPipeline(
  358. raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
  359. static_cast<PassInfoMixin<StackLifetimePrinterPass> *>(this)->printPipeline(
  360. OS, MapClassName2PassName);
  361. OS << "<";
  362. switch (Type) {
  363. case StackLifetime::LivenessType::May:
  364. OS << "may";
  365. break;
  366. case StackLifetime::LivenessType::Must:
  367. OS << "must";
  368. break;
  369. }
  370. OS << ">";
  371. }