StackSafetyAnalysis.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194
  1. //===- StackSafetyAnalysis.cpp - Stack memory safety 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. //===----------------------------------------------------------------------===//
  10. #include "llvm/Analysis/StackSafetyAnalysis.h"
  11. #include "llvm/ADT/APInt.h"
  12. #include "llvm/ADT/SmallPtrSet.h"
  13. #include "llvm/ADT/SmallVector.h"
  14. #include "llvm/ADT/Statistic.h"
  15. #include "llvm/Analysis/ModuleSummaryAnalysis.h"
  16. #include "llvm/Analysis/ScalarEvolution.h"
  17. #include "llvm/Analysis/StackLifetime.h"
  18. #include "llvm/IR/ConstantRange.h"
  19. #include "llvm/IR/DerivedTypes.h"
  20. #include "llvm/IR/GlobalValue.h"
  21. #include "llvm/IR/InstIterator.h"
  22. #include "llvm/IR/Instruction.h"
  23. #include "llvm/IR/Instructions.h"
  24. #include "llvm/IR/IntrinsicInst.h"
  25. #include "llvm/IR/ModuleSummaryIndex.h"
  26. #include "llvm/InitializePasses.h"
  27. #include "llvm/Support/Casting.h"
  28. #include "llvm/Support/CommandLine.h"
  29. #include "llvm/Support/FormatVariadic.h"
  30. #include "llvm/Support/raw_ostream.h"
  31. #include <algorithm>
  32. #include <memory>
  33. #include <tuple>
  34. using namespace llvm;
  35. #define DEBUG_TYPE "stack-safety"
  36. STATISTIC(NumAllocaStackSafe, "Number of safe allocas");
  37. STATISTIC(NumAllocaTotal, "Number of total allocas");
  38. STATISTIC(NumCombinedCalleeLookupTotal,
  39. "Number of total callee lookups on combined index.");
  40. STATISTIC(NumCombinedCalleeLookupFailed,
  41. "Number of failed callee lookups on combined index.");
  42. STATISTIC(NumModuleCalleeLookupTotal,
  43. "Number of total callee lookups on module index.");
  44. STATISTIC(NumModuleCalleeLookupFailed,
  45. "Number of failed callee lookups on module index.");
  46. STATISTIC(NumCombinedParamAccessesBefore,
  47. "Number of total param accesses before generateParamAccessSummary.");
  48. STATISTIC(NumCombinedParamAccessesAfter,
  49. "Number of total param accesses after generateParamAccessSummary.");
  50. STATISTIC(NumCombinedDataFlowNodes,
  51. "Number of total nodes in combined index for dataflow processing.");
  52. STATISTIC(NumIndexCalleeUnhandled, "Number of index callee which are unhandled.");
  53. STATISTIC(NumIndexCalleeMultipleWeak, "Number of index callee non-unique weak.");
  54. STATISTIC(NumIndexCalleeMultipleExternal, "Number of index callee non-unique external.");
  55. static cl::opt<int> StackSafetyMaxIterations("stack-safety-max-iterations",
  56. cl::init(20), cl::Hidden);
  57. static cl::opt<bool> StackSafetyPrint("stack-safety-print", cl::init(false),
  58. cl::Hidden);
  59. static cl::opt<bool> StackSafetyRun("stack-safety-run", cl::init(false),
  60. cl::Hidden);
  61. namespace {
  62. // Check if we should bailout for such ranges.
  63. bool isUnsafe(const ConstantRange &R) {
  64. return R.isEmptySet() || R.isFullSet() || R.isUpperSignWrapped();
  65. }
  66. ConstantRange addOverflowNever(const ConstantRange &L, const ConstantRange &R) {
  67. assert(!L.isSignWrappedSet());
  68. assert(!R.isSignWrappedSet());
  69. if (L.signedAddMayOverflow(R) !=
  70. ConstantRange::OverflowResult::NeverOverflows)
  71. return ConstantRange::getFull(L.getBitWidth());
  72. ConstantRange Result = L.add(R);
  73. assert(!Result.isSignWrappedSet());
  74. return Result;
  75. }
  76. ConstantRange unionNoWrap(const ConstantRange &L, const ConstantRange &R) {
  77. assert(!L.isSignWrappedSet());
  78. assert(!R.isSignWrappedSet());
  79. auto Result = L.unionWith(R);
  80. // Two non-wrapped sets can produce wrapped.
  81. if (Result.isSignWrappedSet())
  82. Result = ConstantRange::getFull(Result.getBitWidth());
  83. return Result;
  84. }
  85. /// Describes use of address in as a function call argument.
  86. template <typename CalleeTy> struct CallInfo {
  87. /// Function being called.
  88. const CalleeTy *Callee = nullptr;
  89. /// Index of argument which pass address.
  90. size_t ParamNo = 0;
  91. CallInfo(const CalleeTy *Callee, size_t ParamNo)
  92. : Callee(Callee), ParamNo(ParamNo) {}
  93. struct Less {
  94. bool operator()(const CallInfo &L, const CallInfo &R) const {
  95. return std::tie(L.ParamNo, L.Callee) < std::tie(R.ParamNo, R.Callee);
  96. }
  97. };
  98. };
  99. /// Describe uses of address (alloca or parameter) inside of the function.
  100. template <typename CalleeTy> struct UseInfo {
  101. // Access range if the address (alloca or parameters).
  102. // It is allowed to be empty-set when there are no known accesses.
  103. ConstantRange Range;
  104. std::set<const Instruction *> UnsafeAccesses;
  105. // List of calls which pass address as an argument.
  106. // Value is offset range of address from base address (alloca or calling
  107. // function argument). Range should never set to empty-set, that is an invalid
  108. // access range that can cause empty-set to be propagated with
  109. // ConstantRange::add
  110. using CallsTy = std::map<CallInfo<CalleeTy>, ConstantRange,
  111. typename CallInfo<CalleeTy>::Less>;
  112. CallsTy Calls;
  113. UseInfo(unsigned PointerSize) : Range{PointerSize, false} {}
  114. void updateRange(const ConstantRange &R) { Range = unionNoWrap(Range, R); }
  115. void addRange(const Instruction *I, const ConstantRange &R, bool IsSafe) {
  116. if (!IsSafe)
  117. UnsafeAccesses.insert(I);
  118. updateRange(R);
  119. }
  120. };
  121. template <typename CalleeTy>
  122. raw_ostream &operator<<(raw_ostream &OS, const UseInfo<CalleeTy> &U) {
  123. OS << U.Range;
  124. for (auto &Call : U.Calls)
  125. OS << ", "
  126. << "@" << Call.first.Callee->getName() << "(arg" << Call.first.ParamNo
  127. << ", " << Call.second << ")";
  128. return OS;
  129. }
  130. /// Calculate the allocation size of a given alloca. Returns empty range
  131. // in case of confution.
  132. ConstantRange getStaticAllocaSizeRange(const AllocaInst &AI) {
  133. const DataLayout &DL = AI.getModule()->getDataLayout();
  134. TypeSize TS = DL.getTypeAllocSize(AI.getAllocatedType());
  135. unsigned PointerSize = DL.getPointerTypeSizeInBits(AI.getType());
  136. // Fallback to empty range for alloca size.
  137. ConstantRange R = ConstantRange::getEmpty(PointerSize);
  138. if (TS.isScalable())
  139. return R;
  140. APInt APSize(PointerSize, TS.getFixedValue(), true);
  141. if (APSize.isNonPositive())
  142. return R;
  143. if (AI.isArrayAllocation()) {
  144. const auto *C = dyn_cast<ConstantInt>(AI.getArraySize());
  145. if (!C)
  146. return R;
  147. bool Overflow = false;
  148. APInt Mul = C->getValue();
  149. if (Mul.isNonPositive())
  150. return R;
  151. Mul = Mul.sextOrTrunc(PointerSize);
  152. APSize = APSize.smul_ov(Mul, Overflow);
  153. if (Overflow)
  154. return R;
  155. }
  156. R = ConstantRange(APInt::getZero(PointerSize), APSize);
  157. assert(!isUnsafe(R));
  158. return R;
  159. }
  160. template <typename CalleeTy> struct FunctionInfo {
  161. std::map<const AllocaInst *, UseInfo<CalleeTy>> Allocas;
  162. std::map<uint32_t, UseInfo<CalleeTy>> Params;
  163. // TODO: describe return value as depending on one or more of its arguments.
  164. // StackSafetyDataFlowAnalysis counter stored here for faster access.
  165. int UpdateCount = 0;
  166. void print(raw_ostream &O, StringRef Name, const Function *F) const {
  167. // TODO: Consider different printout format after
  168. // StackSafetyDataFlowAnalysis. Calls and parameters are irrelevant then.
  169. O << " @" << Name << ((F && F->isDSOLocal()) ? "" : " dso_preemptable")
  170. << ((F && F->isInterposable()) ? " interposable" : "") << "\n";
  171. O << " args uses:\n";
  172. for (auto &KV : Params) {
  173. O << " ";
  174. if (F)
  175. O << F->getArg(KV.first)->getName();
  176. else
  177. O << formatv("arg{0}", KV.first);
  178. O << "[]: " << KV.second << "\n";
  179. }
  180. O << " allocas uses:\n";
  181. if (F) {
  182. for (const auto &I : instructions(F)) {
  183. if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {
  184. auto &AS = Allocas.find(AI)->second;
  185. O << " " << AI->getName() << "["
  186. << getStaticAllocaSizeRange(*AI).getUpper() << "]: " << AS << "\n";
  187. }
  188. }
  189. } else {
  190. assert(Allocas.empty());
  191. }
  192. }
  193. };
  194. using GVToSSI = std::map<const GlobalValue *, FunctionInfo<GlobalValue>>;
  195. } // namespace
  196. struct StackSafetyInfo::InfoTy {
  197. FunctionInfo<GlobalValue> Info;
  198. };
  199. struct StackSafetyGlobalInfo::InfoTy {
  200. GVToSSI Info;
  201. SmallPtrSet<const AllocaInst *, 8> SafeAllocas;
  202. std::set<const Instruction *> UnsafeAccesses;
  203. };
  204. namespace {
  205. class StackSafetyLocalAnalysis {
  206. Function &F;
  207. const DataLayout &DL;
  208. ScalarEvolution &SE;
  209. unsigned PointerSize = 0;
  210. const ConstantRange UnknownRange;
  211. ConstantRange offsetFrom(Value *Addr, Value *Base);
  212. ConstantRange getAccessRange(Value *Addr, Value *Base,
  213. const ConstantRange &SizeRange);
  214. ConstantRange getAccessRange(Value *Addr, Value *Base, TypeSize Size);
  215. ConstantRange getMemIntrinsicAccessRange(const MemIntrinsic *MI, const Use &U,
  216. Value *Base);
  217. void analyzeAllUses(Value *Ptr, UseInfo<GlobalValue> &AS,
  218. const StackLifetime &SL);
  219. bool isSafeAccess(const Use &U, AllocaInst *AI, const SCEV *AccessSize);
  220. bool isSafeAccess(const Use &U, AllocaInst *AI, Value *V);
  221. bool isSafeAccess(const Use &U, AllocaInst *AI, TypeSize AccessSize);
  222. public:
  223. StackSafetyLocalAnalysis(Function &F, ScalarEvolution &SE)
  224. : F(F), DL(F.getParent()->getDataLayout()), SE(SE),
  225. PointerSize(DL.getPointerSizeInBits()),
  226. UnknownRange(PointerSize, true) {}
  227. // Run the transformation on the associated function.
  228. FunctionInfo<GlobalValue> run();
  229. };
  230. ConstantRange StackSafetyLocalAnalysis::offsetFrom(Value *Addr, Value *Base) {
  231. if (!SE.isSCEVable(Addr->getType()) || !SE.isSCEVable(Base->getType()))
  232. return UnknownRange;
  233. auto *PtrTy = IntegerType::getInt8PtrTy(SE.getContext());
  234. const SCEV *AddrExp = SE.getTruncateOrZeroExtend(SE.getSCEV(Addr), PtrTy);
  235. const SCEV *BaseExp = SE.getTruncateOrZeroExtend(SE.getSCEV(Base), PtrTy);
  236. const SCEV *Diff = SE.getMinusSCEV(AddrExp, BaseExp);
  237. if (isa<SCEVCouldNotCompute>(Diff))
  238. return UnknownRange;
  239. ConstantRange Offset = SE.getSignedRange(Diff);
  240. if (isUnsafe(Offset))
  241. return UnknownRange;
  242. return Offset.sextOrTrunc(PointerSize);
  243. }
  244. ConstantRange
  245. StackSafetyLocalAnalysis::getAccessRange(Value *Addr, Value *Base,
  246. const ConstantRange &SizeRange) {
  247. // Zero-size loads and stores do not access memory.
  248. if (SizeRange.isEmptySet())
  249. return ConstantRange::getEmpty(PointerSize);
  250. assert(!isUnsafe(SizeRange));
  251. ConstantRange Offsets = offsetFrom(Addr, Base);
  252. if (isUnsafe(Offsets))
  253. return UnknownRange;
  254. Offsets = addOverflowNever(Offsets, SizeRange);
  255. if (isUnsafe(Offsets))
  256. return UnknownRange;
  257. return Offsets;
  258. }
  259. ConstantRange StackSafetyLocalAnalysis::getAccessRange(Value *Addr, Value *Base,
  260. TypeSize Size) {
  261. if (Size.isScalable())
  262. return UnknownRange;
  263. APInt APSize(PointerSize, Size.getFixedValue(), true);
  264. if (APSize.isNegative())
  265. return UnknownRange;
  266. return getAccessRange(Addr, Base,
  267. ConstantRange(APInt::getZero(PointerSize), APSize));
  268. }
  269. ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
  270. const MemIntrinsic *MI, const Use &U, Value *Base) {
  271. if (const auto *MTI = dyn_cast<MemTransferInst>(MI)) {
  272. if (MTI->getRawSource() != U && MTI->getRawDest() != U)
  273. return ConstantRange::getEmpty(PointerSize);
  274. } else {
  275. if (MI->getRawDest() != U)
  276. return ConstantRange::getEmpty(PointerSize);
  277. }
  278. auto *CalculationTy = IntegerType::getIntNTy(SE.getContext(), PointerSize);
  279. if (!SE.isSCEVable(MI->getLength()->getType()))
  280. return UnknownRange;
  281. const SCEV *Expr =
  282. SE.getTruncateOrZeroExtend(SE.getSCEV(MI->getLength()), CalculationTy);
  283. ConstantRange Sizes = SE.getSignedRange(Expr);
  284. if (Sizes.getUpper().isNegative() || isUnsafe(Sizes))
  285. return UnknownRange;
  286. Sizes = Sizes.sextOrTrunc(PointerSize);
  287. ConstantRange SizeRange(APInt::getZero(PointerSize), Sizes.getUpper() - 1);
  288. return getAccessRange(U, Base, SizeRange);
  289. }
  290. bool StackSafetyLocalAnalysis::isSafeAccess(const Use &U, AllocaInst *AI,
  291. Value *V) {
  292. return isSafeAccess(U, AI, SE.getSCEV(V));
  293. }
  294. bool StackSafetyLocalAnalysis::isSafeAccess(const Use &U, AllocaInst *AI,
  295. TypeSize TS) {
  296. if (TS.isScalable())
  297. return false;
  298. auto *CalculationTy = IntegerType::getIntNTy(SE.getContext(), PointerSize);
  299. const SCEV *SV = SE.getConstant(CalculationTy, TS.getFixedValue());
  300. return isSafeAccess(U, AI, SV);
  301. }
  302. bool StackSafetyLocalAnalysis::isSafeAccess(const Use &U, AllocaInst *AI,
  303. const SCEV *AccessSize) {
  304. if (!AI)
  305. return true;
  306. if (isa<SCEVCouldNotCompute>(AccessSize))
  307. return false;
  308. const auto *I = cast<Instruction>(U.getUser());
  309. auto ToCharPtr = [&](const SCEV *V) {
  310. auto *PtrTy = IntegerType::getInt8PtrTy(SE.getContext());
  311. return SE.getTruncateOrZeroExtend(V, PtrTy);
  312. };
  313. const SCEV *AddrExp = ToCharPtr(SE.getSCEV(U.get()));
  314. const SCEV *BaseExp = ToCharPtr(SE.getSCEV(AI));
  315. const SCEV *Diff = SE.getMinusSCEV(AddrExp, BaseExp);
  316. if (isa<SCEVCouldNotCompute>(Diff))
  317. return false;
  318. auto Size = getStaticAllocaSizeRange(*AI);
  319. auto *CalculationTy = IntegerType::getIntNTy(SE.getContext(), PointerSize);
  320. auto ToDiffTy = [&](const SCEV *V) {
  321. return SE.getTruncateOrZeroExtend(V, CalculationTy);
  322. };
  323. const SCEV *Min = ToDiffTy(SE.getConstant(Size.getLower()));
  324. const SCEV *Max = SE.getMinusSCEV(ToDiffTy(SE.getConstant(Size.getUpper())),
  325. ToDiffTy(AccessSize));
  326. return SE.evaluatePredicateAt(ICmpInst::Predicate::ICMP_SGE, Diff, Min, I)
  327. .value_or(false) &&
  328. SE.evaluatePredicateAt(ICmpInst::Predicate::ICMP_SLE, Diff, Max, I)
  329. .value_or(false);
  330. }
  331. /// The function analyzes all local uses of Ptr (alloca or argument) and
  332. /// calculates local access range and all function calls where it was used.
  333. void StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr,
  334. UseInfo<GlobalValue> &US,
  335. const StackLifetime &SL) {
  336. SmallPtrSet<const Value *, 16> Visited;
  337. SmallVector<const Value *, 8> WorkList;
  338. WorkList.push_back(Ptr);
  339. AllocaInst *AI = dyn_cast<AllocaInst>(Ptr);
  340. // A DFS search through all uses of the alloca in bitcasts/PHI/GEPs/etc.
  341. while (!WorkList.empty()) {
  342. const Value *V = WorkList.pop_back_val();
  343. for (const Use &UI : V->uses()) {
  344. const auto *I = cast<Instruction>(UI.getUser());
  345. if (!SL.isReachable(I))
  346. continue;
  347. assert(V == UI.get());
  348. switch (I->getOpcode()) {
  349. case Instruction::Load: {
  350. if (AI && !SL.isAliveAfter(AI, I)) {
  351. US.addRange(I, UnknownRange, /*IsSafe=*/false);
  352. break;
  353. }
  354. auto TypeSize = DL.getTypeStoreSize(I->getType());
  355. auto AccessRange = getAccessRange(UI, Ptr, TypeSize);
  356. bool Safe = isSafeAccess(UI, AI, TypeSize);
  357. US.addRange(I, AccessRange, Safe);
  358. break;
  359. }
  360. case Instruction::VAArg:
  361. // "va-arg" from a pointer is safe.
  362. break;
  363. case Instruction::Store: {
  364. if (V == I->getOperand(0)) {
  365. // Stored the pointer - conservatively assume it may be unsafe.
  366. US.addRange(I, UnknownRange, /*IsSafe=*/false);
  367. break;
  368. }
  369. if (AI && !SL.isAliveAfter(AI, I)) {
  370. US.addRange(I, UnknownRange, /*IsSafe=*/false);
  371. break;
  372. }
  373. auto TypeSize = DL.getTypeStoreSize(I->getOperand(0)->getType());
  374. auto AccessRange = getAccessRange(UI, Ptr, TypeSize);
  375. bool Safe = isSafeAccess(UI, AI, TypeSize);
  376. US.addRange(I, AccessRange, Safe);
  377. break;
  378. }
  379. case Instruction::Ret:
  380. // Information leak.
  381. // FIXME: Process parameters correctly. This is a leak only if we return
  382. // alloca.
  383. US.addRange(I, UnknownRange, /*IsSafe=*/false);
  384. break;
  385. case Instruction::Call:
  386. case Instruction::Invoke: {
  387. if (I->isLifetimeStartOrEnd())
  388. break;
  389. if (AI && !SL.isAliveAfter(AI, I)) {
  390. US.addRange(I, UnknownRange, /*IsSafe=*/false);
  391. break;
  392. }
  393. if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
  394. auto AccessRange = getMemIntrinsicAccessRange(MI, UI, Ptr);
  395. bool Safe = false;
  396. if (const auto *MTI = dyn_cast<MemTransferInst>(MI)) {
  397. if (MTI->getRawSource() != UI && MTI->getRawDest() != UI)
  398. Safe = true;
  399. } else if (MI->getRawDest() != UI) {
  400. Safe = true;
  401. }
  402. Safe = Safe || isSafeAccess(UI, AI, MI->getLength());
  403. US.addRange(I, AccessRange, Safe);
  404. break;
  405. }
  406. const auto &CB = cast<CallBase>(*I);
  407. if (CB.getReturnedArgOperand() == V) {
  408. if (Visited.insert(I).second)
  409. WorkList.push_back(cast<const Instruction>(I));
  410. }
  411. if (!CB.isArgOperand(&UI)) {
  412. US.addRange(I, UnknownRange, /*IsSafe=*/false);
  413. break;
  414. }
  415. unsigned ArgNo = CB.getArgOperandNo(&UI);
  416. if (CB.isByValArgument(ArgNo)) {
  417. auto TypeSize = DL.getTypeStoreSize(CB.getParamByValType(ArgNo));
  418. auto AccessRange = getAccessRange(UI, Ptr, TypeSize);
  419. bool Safe = isSafeAccess(UI, AI, TypeSize);
  420. US.addRange(I, AccessRange, Safe);
  421. break;
  422. }
  423. // FIXME: consult devirt?
  424. // Do not follow aliases, otherwise we could inadvertently follow
  425. // dso_preemptable aliases or aliases with interposable linkage.
  426. const GlobalValue *Callee =
  427. dyn_cast<GlobalValue>(CB.getCalledOperand()->stripPointerCasts());
  428. if (!Callee) {
  429. US.addRange(I, UnknownRange, /*IsSafe=*/false);
  430. break;
  431. }
  432. assert(isa<Function>(Callee) || isa<GlobalAlias>(Callee));
  433. ConstantRange Offsets = offsetFrom(UI, Ptr);
  434. auto Insert =
  435. US.Calls.emplace(CallInfo<GlobalValue>(Callee, ArgNo), Offsets);
  436. if (!Insert.second)
  437. Insert.first->second = Insert.first->second.unionWith(Offsets);
  438. break;
  439. }
  440. default:
  441. if (Visited.insert(I).second)
  442. WorkList.push_back(cast<const Instruction>(I));
  443. }
  444. }
  445. }
  446. }
  447. FunctionInfo<GlobalValue> StackSafetyLocalAnalysis::run() {
  448. FunctionInfo<GlobalValue> Info;
  449. assert(!F.isDeclaration() &&
  450. "Can't run StackSafety on a function declaration");
  451. LLVM_DEBUG(dbgs() << "[StackSafety] " << F.getName() << "\n");
  452. SmallVector<AllocaInst *, 64> Allocas;
  453. for (auto &I : instructions(F))
  454. if (auto *AI = dyn_cast<AllocaInst>(&I))
  455. Allocas.push_back(AI);
  456. StackLifetime SL(F, Allocas, StackLifetime::LivenessType::Must);
  457. SL.run();
  458. for (auto *AI : Allocas) {
  459. auto &UI = Info.Allocas.emplace(AI, PointerSize).first->second;
  460. analyzeAllUses(AI, UI, SL);
  461. }
  462. for (Argument &A : F.args()) {
  463. // Non pointers and bypass arguments are not going to be used in any global
  464. // processing.
  465. if (A.getType()->isPointerTy() && !A.hasByValAttr()) {
  466. auto &UI = Info.Params.emplace(A.getArgNo(), PointerSize).first->second;
  467. analyzeAllUses(&A, UI, SL);
  468. }
  469. }
  470. LLVM_DEBUG(Info.print(dbgs(), F.getName(), &F));
  471. LLVM_DEBUG(dbgs() << "\n[StackSafety] done\n");
  472. return Info;
  473. }
  474. template <typename CalleeTy> class StackSafetyDataFlowAnalysis {
  475. using FunctionMap = std::map<const CalleeTy *, FunctionInfo<CalleeTy>>;
  476. FunctionMap Functions;
  477. const ConstantRange UnknownRange;
  478. // Callee-to-Caller multimap.
  479. DenseMap<const CalleeTy *, SmallVector<const CalleeTy *, 4>> Callers;
  480. SetVector<const CalleeTy *> WorkList;
  481. bool updateOneUse(UseInfo<CalleeTy> &US, bool UpdateToFullSet);
  482. void updateOneNode(const CalleeTy *Callee, FunctionInfo<CalleeTy> &FS);
  483. void updateOneNode(const CalleeTy *Callee) {
  484. updateOneNode(Callee, Functions.find(Callee)->second);
  485. }
  486. void updateAllNodes() {
  487. for (auto &F : Functions)
  488. updateOneNode(F.first, F.second);
  489. }
  490. void runDataFlow();
  491. #ifndef NDEBUG
  492. void verifyFixedPoint();
  493. #endif
  494. public:
  495. StackSafetyDataFlowAnalysis(uint32_t PointerBitWidth, FunctionMap Functions)
  496. : Functions(std::move(Functions)),
  497. UnknownRange(ConstantRange::getFull(PointerBitWidth)) {}
  498. const FunctionMap &run();
  499. ConstantRange getArgumentAccessRange(const CalleeTy *Callee, unsigned ParamNo,
  500. const ConstantRange &Offsets) const;
  501. };
  502. template <typename CalleeTy>
  503. ConstantRange StackSafetyDataFlowAnalysis<CalleeTy>::getArgumentAccessRange(
  504. const CalleeTy *Callee, unsigned ParamNo,
  505. const ConstantRange &Offsets) const {
  506. auto FnIt = Functions.find(Callee);
  507. // Unknown callee (outside of LTO domain or an indirect call).
  508. if (FnIt == Functions.end())
  509. return UnknownRange;
  510. auto &FS = FnIt->second;
  511. auto ParamIt = FS.Params.find(ParamNo);
  512. if (ParamIt == FS.Params.end())
  513. return UnknownRange;
  514. auto &Access = ParamIt->second.Range;
  515. if (Access.isEmptySet())
  516. return Access;
  517. if (Access.isFullSet())
  518. return UnknownRange;
  519. return addOverflowNever(Access, Offsets);
  520. }
  521. template <typename CalleeTy>
  522. bool StackSafetyDataFlowAnalysis<CalleeTy>::updateOneUse(UseInfo<CalleeTy> &US,
  523. bool UpdateToFullSet) {
  524. bool Changed = false;
  525. for (auto &KV : US.Calls) {
  526. assert(!KV.second.isEmptySet() &&
  527. "Param range can't be empty-set, invalid offset range");
  528. ConstantRange CalleeRange =
  529. getArgumentAccessRange(KV.first.Callee, KV.first.ParamNo, KV.second);
  530. if (!US.Range.contains(CalleeRange)) {
  531. Changed = true;
  532. if (UpdateToFullSet)
  533. US.Range = UnknownRange;
  534. else
  535. US.updateRange(CalleeRange);
  536. }
  537. }
  538. return Changed;
  539. }
  540. template <typename CalleeTy>
  541. void StackSafetyDataFlowAnalysis<CalleeTy>::updateOneNode(
  542. const CalleeTy *Callee, FunctionInfo<CalleeTy> &FS) {
  543. bool UpdateToFullSet = FS.UpdateCount > StackSafetyMaxIterations;
  544. bool Changed = false;
  545. for (auto &KV : FS.Params)
  546. Changed |= updateOneUse(KV.second, UpdateToFullSet);
  547. if (Changed) {
  548. LLVM_DEBUG(dbgs() << "=== update [" << FS.UpdateCount
  549. << (UpdateToFullSet ? ", full-set" : "") << "] " << &FS
  550. << "\n");
  551. // Callers of this function may need updating.
  552. for (auto &CallerID : Callers[Callee])
  553. WorkList.insert(CallerID);
  554. ++FS.UpdateCount;
  555. }
  556. }
  557. template <typename CalleeTy>
  558. void StackSafetyDataFlowAnalysis<CalleeTy>::runDataFlow() {
  559. SmallVector<const CalleeTy *, 16> Callees;
  560. for (auto &F : Functions) {
  561. Callees.clear();
  562. auto &FS = F.second;
  563. for (auto &KV : FS.Params)
  564. for (auto &CS : KV.second.Calls)
  565. Callees.push_back(CS.first.Callee);
  566. llvm::sort(Callees);
  567. Callees.erase(std::unique(Callees.begin(), Callees.end()), Callees.end());
  568. for (auto &Callee : Callees)
  569. Callers[Callee].push_back(F.first);
  570. }
  571. updateAllNodes();
  572. while (!WorkList.empty()) {
  573. const CalleeTy *Callee = WorkList.pop_back_val();
  574. updateOneNode(Callee);
  575. }
  576. }
  577. #ifndef NDEBUG
  578. template <typename CalleeTy>
  579. void StackSafetyDataFlowAnalysis<CalleeTy>::verifyFixedPoint() {
  580. WorkList.clear();
  581. updateAllNodes();
  582. assert(WorkList.empty());
  583. }
  584. #endif
  585. template <typename CalleeTy>
  586. const typename StackSafetyDataFlowAnalysis<CalleeTy>::FunctionMap &
  587. StackSafetyDataFlowAnalysis<CalleeTy>::run() {
  588. runDataFlow();
  589. LLVM_DEBUG(verifyFixedPoint());
  590. return Functions;
  591. }
  592. FunctionSummary *findCalleeFunctionSummary(ValueInfo VI, StringRef ModuleId) {
  593. if (!VI)
  594. return nullptr;
  595. auto SummaryList = VI.getSummaryList();
  596. GlobalValueSummary* S = nullptr;
  597. for (const auto& GVS : SummaryList) {
  598. if (!GVS->isLive())
  599. continue;
  600. if (const AliasSummary *AS = dyn_cast<AliasSummary>(GVS.get()))
  601. if (!AS->hasAliasee())
  602. continue;
  603. if (!isa<FunctionSummary>(GVS->getBaseObject()))
  604. continue;
  605. if (GlobalValue::isLocalLinkage(GVS->linkage())) {
  606. if (GVS->modulePath() == ModuleId) {
  607. S = GVS.get();
  608. break;
  609. }
  610. } else if (GlobalValue::isExternalLinkage(GVS->linkage())) {
  611. if (S) {
  612. ++NumIndexCalleeMultipleExternal;
  613. return nullptr;
  614. }
  615. S = GVS.get();
  616. } else if (GlobalValue::isWeakLinkage(GVS->linkage())) {
  617. if (S) {
  618. ++NumIndexCalleeMultipleWeak;
  619. return nullptr;
  620. }
  621. S = GVS.get();
  622. } else if (GlobalValue::isAvailableExternallyLinkage(GVS->linkage()) ||
  623. GlobalValue::isLinkOnceLinkage(GVS->linkage())) {
  624. if (SummaryList.size() == 1)
  625. S = GVS.get();
  626. // According thinLTOResolvePrevailingGUID these are unlikely prevailing.
  627. } else {
  628. ++NumIndexCalleeUnhandled;
  629. }
  630. };
  631. while (S) {
  632. if (!S->isLive() || !S->isDSOLocal())
  633. return nullptr;
  634. if (FunctionSummary *FS = dyn_cast<FunctionSummary>(S))
  635. return FS;
  636. AliasSummary *AS = dyn_cast<AliasSummary>(S);
  637. if (!AS || !AS->hasAliasee())
  638. return nullptr;
  639. S = AS->getBaseObject();
  640. if (S == AS)
  641. return nullptr;
  642. }
  643. return nullptr;
  644. }
  645. const Function *findCalleeInModule(const GlobalValue *GV) {
  646. while (GV) {
  647. if (GV->isDeclaration() || GV->isInterposable() || !GV->isDSOLocal())
  648. return nullptr;
  649. if (const Function *F = dyn_cast<Function>(GV))
  650. return F;
  651. const GlobalAlias *A = dyn_cast<GlobalAlias>(GV);
  652. if (!A)
  653. return nullptr;
  654. GV = A->getAliaseeObject();
  655. if (GV == A)
  656. return nullptr;
  657. }
  658. return nullptr;
  659. }
  660. const ConstantRange *findParamAccess(const FunctionSummary &FS,
  661. uint32_t ParamNo) {
  662. assert(FS.isLive());
  663. assert(FS.isDSOLocal());
  664. for (const auto &PS : FS.paramAccesses())
  665. if (ParamNo == PS.ParamNo)
  666. return &PS.Use;
  667. return nullptr;
  668. }
  669. void resolveAllCalls(UseInfo<GlobalValue> &Use,
  670. const ModuleSummaryIndex *Index) {
  671. ConstantRange FullSet(Use.Range.getBitWidth(), true);
  672. // Move Use.Calls to a temp storage and repopulate - don't use std::move as it
  673. // leaves Use.Calls in an undefined state.
  674. UseInfo<GlobalValue>::CallsTy TmpCalls;
  675. std::swap(TmpCalls, Use.Calls);
  676. for (const auto &C : TmpCalls) {
  677. const Function *F = findCalleeInModule(C.first.Callee);
  678. if (F) {
  679. Use.Calls.emplace(CallInfo<GlobalValue>(F, C.first.ParamNo), C.second);
  680. continue;
  681. }
  682. if (!Index)
  683. return Use.updateRange(FullSet);
  684. FunctionSummary *FS =
  685. findCalleeFunctionSummary(Index->getValueInfo(C.first.Callee->getGUID()),
  686. C.first.Callee->getParent()->getModuleIdentifier());
  687. ++NumModuleCalleeLookupTotal;
  688. if (!FS) {
  689. ++NumModuleCalleeLookupFailed;
  690. return Use.updateRange(FullSet);
  691. }
  692. const ConstantRange *Found = findParamAccess(*FS, C.first.ParamNo);
  693. if (!Found || Found->isFullSet())
  694. return Use.updateRange(FullSet);
  695. ConstantRange Access = Found->sextOrTrunc(Use.Range.getBitWidth());
  696. if (!Access.isEmptySet())
  697. Use.updateRange(addOverflowNever(Access, C.second));
  698. }
  699. }
  700. GVToSSI createGlobalStackSafetyInfo(
  701. std::map<const GlobalValue *, FunctionInfo<GlobalValue>> Functions,
  702. const ModuleSummaryIndex *Index) {
  703. GVToSSI SSI;
  704. if (Functions.empty())
  705. return SSI;
  706. // FIXME: Simplify printing and remove copying here.
  707. auto Copy = Functions;
  708. for (auto &FnKV : Copy)
  709. for (auto &KV : FnKV.second.Params) {
  710. resolveAllCalls(KV.second, Index);
  711. if (KV.second.Range.isFullSet())
  712. KV.second.Calls.clear();
  713. }
  714. uint32_t PointerSize =
  715. Copy.begin()->first->getParent()->getDataLayout().getPointerSizeInBits();
  716. StackSafetyDataFlowAnalysis<GlobalValue> SSDFA(PointerSize, std::move(Copy));
  717. for (const auto &F : SSDFA.run()) {
  718. auto FI = F.second;
  719. auto &SrcF = Functions[F.first];
  720. for (auto &KV : FI.Allocas) {
  721. auto &A = KV.second;
  722. resolveAllCalls(A, Index);
  723. for (auto &C : A.Calls) {
  724. A.updateRange(SSDFA.getArgumentAccessRange(C.first.Callee,
  725. C.first.ParamNo, C.second));
  726. }
  727. // FIXME: This is needed only to preserve calls in print() results.
  728. A.Calls = SrcF.Allocas.find(KV.first)->second.Calls;
  729. }
  730. for (auto &KV : FI.Params) {
  731. auto &P = KV.second;
  732. P.Calls = SrcF.Params.find(KV.first)->second.Calls;
  733. }
  734. SSI[F.first] = std::move(FI);
  735. }
  736. return SSI;
  737. }
  738. } // end anonymous namespace
  739. StackSafetyInfo::StackSafetyInfo() = default;
  740. StackSafetyInfo::StackSafetyInfo(Function *F,
  741. std::function<ScalarEvolution &()> GetSE)
  742. : F(F), GetSE(GetSE) {}
  743. StackSafetyInfo::StackSafetyInfo(StackSafetyInfo &&) = default;
  744. StackSafetyInfo &StackSafetyInfo::operator=(StackSafetyInfo &&) = default;
  745. StackSafetyInfo::~StackSafetyInfo() = default;
  746. const StackSafetyInfo::InfoTy &StackSafetyInfo::getInfo() const {
  747. if (!Info) {
  748. StackSafetyLocalAnalysis SSLA(*F, GetSE());
  749. Info.reset(new InfoTy{SSLA.run()});
  750. }
  751. return *Info;
  752. }
  753. void StackSafetyInfo::print(raw_ostream &O) const {
  754. getInfo().Info.print(O, F->getName(), dyn_cast<Function>(F));
  755. O << "\n";
  756. }
  757. const StackSafetyGlobalInfo::InfoTy &StackSafetyGlobalInfo::getInfo() const {
  758. if (!Info) {
  759. std::map<const GlobalValue *, FunctionInfo<GlobalValue>> Functions;
  760. for (auto &F : M->functions()) {
  761. if (!F.isDeclaration()) {
  762. auto FI = GetSSI(F).getInfo().Info;
  763. Functions.emplace(&F, std::move(FI));
  764. }
  765. }
  766. Info.reset(new InfoTy{
  767. createGlobalStackSafetyInfo(std::move(Functions), Index), {}, {}});
  768. for (auto &FnKV : Info->Info) {
  769. for (auto &KV : FnKV.second.Allocas) {
  770. ++NumAllocaTotal;
  771. const AllocaInst *AI = KV.first;
  772. auto AIRange = getStaticAllocaSizeRange(*AI);
  773. if (AIRange.contains(KV.second.Range)) {
  774. Info->SafeAllocas.insert(AI);
  775. ++NumAllocaStackSafe;
  776. }
  777. Info->UnsafeAccesses.insert(KV.second.UnsafeAccesses.begin(),
  778. KV.second.UnsafeAccesses.end());
  779. }
  780. }
  781. if (StackSafetyPrint)
  782. print(errs());
  783. }
  784. return *Info;
  785. }
  786. std::vector<FunctionSummary::ParamAccess>
  787. StackSafetyInfo::getParamAccesses(ModuleSummaryIndex &Index) const {
  788. // Implementation transforms internal representation of parameter information
  789. // into FunctionSummary format.
  790. std::vector<FunctionSummary::ParamAccess> ParamAccesses;
  791. for (const auto &KV : getInfo().Info.Params) {
  792. auto &PS = KV.second;
  793. // Parameter accessed by any or unknown offset, represented as FullSet by
  794. // StackSafety, is handled as the parameter for which we have no
  795. // StackSafety info at all. So drop it to reduce summary size.
  796. if (PS.Range.isFullSet())
  797. continue;
  798. ParamAccesses.emplace_back(KV.first, PS.Range);
  799. FunctionSummary::ParamAccess &Param = ParamAccesses.back();
  800. Param.Calls.reserve(PS.Calls.size());
  801. for (const auto &C : PS.Calls) {
  802. // Parameter forwarded into another function by any or unknown offset
  803. // will make ParamAccess::Range as FullSet anyway. So we can drop the
  804. // entire parameter like we did above.
  805. // TODO(vitalybuka): Return already filtered parameters from getInfo().
  806. if (C.second.isFullSet()) {
  807. ParamAccesses.pop_back();
  808. break;
  809. }
  810. Param.Calls.emplace_back(C.first.ParamNo,
  811. Index.getOrInsertValueInfo(C.first.Callee),
  812. C.second);
  813. }
  814. }
  815. for (FunctionSummary::ParamAccess &Param : ParamAccesses) {
  816. sort(Param.Calls, [](const FunctionSummary::ParamAccess::Call &L,
  817. const FunctionSummary::ParamAccess::Call &R) {
  818. return std::tie(L.ParamNo, L.Callee) < std::tie(R.ParamNo, R.Callee);
  819. });
  820. }
  821. return ParamAccesses;
  822. }
  823. StackSafetyGlobalInfo::StackSafetyGlobalInfo() = default;
  824. StackSafetyGlobalInfo::StackSafetyGlobalInfo(
  825. Module *M, std::function<const StackSafetyInfo &(Function &F)> GetSSI,
  826. const ModuleSummaryIndex *Index)
  827. : M(M), GetSSI(GetSSI), Index(Index) {
  828. if (StackSafetyRun)
  829. getInfo();
  830. }
  831. StackSafetyGlobalInfo::StackSafetyGlobalInfo(StackSafetyGlobalInfo &&) =
  832. default;
  833. StackSafetyGlobalInfo &
  834. StackSafetyGlobalInfo::operator=(StackSafetyGlobalInfo &&) = default;
  835. StackSafetyGlobalInfo::~StackSafetyGlobalInfo() = default;
  836. bool StackSafetyGlobalInfo::isSafe(const AllocaInst &AI) const {
  837. const auto &Info = getInfo();
  838. return Info.SafeAllocas.count(&AI);
  839. }
  840. bool StackSafetyGlobalInfo::stackAccessIsSafe(const Instruction &I) const {
  841. const auto &Info = getInfo();
  842. return Info.UnsafeAccesses.find(&I) == Info.UnsafeAccesses.end();
  843. }
  844. void StackSafetyGlobalInfo::print(raw_ostream &O) const {
  845. auto &SSI = getInfo().Info;
  846. if (SSI.empty())
  847. return;
  848. const Module &M = *SSI.begin()->first->getParent();
  849. for (const auto &F : M.functions()) {
  850. if (!F.isDeclaration()) {
  851. SSI.find(&F)->second.print(O, F.getName(), &F);
  852. O << " safe accesses:"
  853. << "\n";
  854. for (const auto &I : instructions(F)) {
  855. const CallInst *Call = dyn_cast<CallInst>(&I);
  856. if ((isa<StoreInst>(I) || isa<LoadInst>(I) || isa<MemIntrinsic>(I) ||
  857. (Call && Call->hasByValArgument())) &&
  858. stackAccessIsSafe(I)) {
  859. O << " " << I << "\n";
  860. }
  861. }
  862. O << "\n";
  863. }
  864. }
  865. }
  866. LLVM_DUMP_METHOD void StackSafetyGlobalInfo::dump() const { print(dbgs()); }
  867. AnalysisKey StackSafetyAnalysis::Key;
  868. StackSafetyInfo StackSafetyAnalysis::run(Function &F,
  869. FunctionAnalysisManager &AM) {
  870. return StackSafetyInfo(&F, [&AM, &F]() -> ScalarEvolution & {
  871. return AM.getResult<ScalarEvolutionAnalysis>(F);
  872. });
  873. }
  874. PreservedAnalyses StackSafetyPrinterPass::run(Function &F,
  875. FunctionAnalysisManager &AM) {
  876. OS << "'Stack Safety Local Analysis' for function '" << F.getName() << "'\n";
  877. AM.getResult<StackSafetyAnalysis>(F).print(OS);
  878. return PreservedAnalyses::all();
  879. }
  880. char StackSafetyInfoWrapperPass::ID = 0;
  881. StackSafetyInfoWrapperPass::StackSafetyInfoWrapperPass() : FunctionPass(ID) {
  882. initializeStackSafetyInfoWrapperPassPass(*PassRegistry::getPassRegistry());
  883. }
  884. void StackSafetyInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
  885. AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
  886. AU.setPreservesAll();
  887. }
  888. void StackSafetyInfoWrapperPass::print(raw_ostream &O, const Module *M) const {
  889. SSI.print(O);
  890. }
  891. bool StackSafetyInfoWrapperPass::runOnFunction(Function &F) {
  892. auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
  893. SSI = {&F, [SE]() -> ScalarEvolution & { return *SE; }};
  894. return false;
  895. }
  896. AnalysisKey StackSafetyGlobalAnalysis::Key;
  897. StackSafetyGlobalInfo
  898. StackSafetyGlobalAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
  899. // FIXME: Lookup Module Summary.
  900. FunctionAnalysisManager &FAM =
  901. AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
  902. return {&M,
  903. [&FAM](Function &F) -> const StackSafetyInfo & {
  904. return FAM.getResult<StackSafetyAnalysis>(F);
  905. },
  906. nullptr};
  907. }
  908. PreservedAnalyses StackSafetyGlobalPrinterPass::run(Module &M,
  909. ModuleAnalysisManager &AM) {
  910. OS << "'Stack Safety Analysis' for module '" << M.getName() << "'\n";
  911. AM.getResult<StackSafetyGlobalAnalysis>(M).print(OS);
  912. return PreservedAnalyses::all();
  913. }
  914. char StackSafetyGlobalInfoWrapperPass::ID = 0;
  915. StackSafetyGlobalInfoWrapperPass::StackSafetyGlobalInfoWrapperPass()
  916. : ModulePass(ID) {
  917. initializeStackSafetyGlobalInfoWrapperPassPass(
  918. *PassRegistry::getPassRegistry());
  919. }
  920. StackSafetyGlobalInfoWrapperPass::~StackSafetyGlobalInfoWrapperPass() = default;
  921. void StackSafetyGlobalInfoWrapperPass::print(raw_ostream &O,
  922. const Module *M) const {
  923. SSGI.print(O);
  924. }
  925. void StackSafetyGlobalInfoWrapperPass::getAnalysisUsage(
  926. AnalysisUsage &AU) const {
  927. AU.setPreservesAll();
  928. AU.addRequired<StackSafetyInfoWrapperPass>();
  929. }
  930. bool StackSafetyGlobalInfoWrapperPass::runOnModule(Module &M) {
  931. const ModuleSummaryIndex *ImportSummary = nullptr;
  932. if (auto *IndexWrapperPass =
  933. getAnalysisIfAvailable<ImmutableModuleSummaryIndexWrapperPass>())
  934. ImportSummary = IndexWrapperPass->getIndex();
  935. SSGI = {&M,
  936. [this](Function &F) -> const StackSafetyInfo & {
  937. return getAnalysis<StackSafetyInfoWrapperPass>(F).getResult();
  938. },
  939. ImportSummary};
  940. return false;
  941. }
  942. bool llvm::needsParamAccessSummary(const Module &M) {
  943. if (StackSafetyRun)
  944. return true;
  945. for (const auto &F : M.functions())
  946. if (F.hasFnAttribute(Attribute::SanitizeMemTag))
  947. return true;
  948. return false;
  949. }
  950. void llvm::generateParamAccessSummary(ModuleSummaryIndex &Index) {
  951. if (!Index.hasParamAccess())
  952. return;
  953. const ConstantRange FullSet(FunctionSummary::ParamAccess::RangeWidth, true);
  954. auto CountParamAccesses = [&](auto &Stat) {
  955. if (!AreStatisticsEnabled())
  956. return;
  957. for (auto &GVS : Index)
  958. for (auto &GV : GVS.second.SummaryList)
  959. if (FunctionSummary *FS = dyn_cast<FunctionSummary>(GV.get()))
  960. Stat += FS->paramAccesses().size();
  961. };
  962. CountParamAccesses(NumCombinedParamAccessesBefore);
  963. std::map<const FunctionSummary *, FunctionInfo<FunctionSummary>> Functions;
  964. // Convert the ModuleSummaryIndex to a FunctionMap
  965. for (auto &GVS : Index) {
  966. for (auto &GV : GVS.second.SummaryList) {
  967. FunctionSummary *FS = dyn_cast<FunctionSummary>(GV.get());
  968. if (!FS || FS->paramAccesses().empty())
  969. continue;
  970. if (FS->isLive() && FS->isDSOLocal()) {
  971. FunctionInfo<FunctionSummary> FI;
  972. for (const auto &PS : FS->paramAccesses()) {
  973. auto &US =
  974. FI.Params
  975. .emplace(PS.ParamNo, FunctionSummary::ParamAccess::RangeWidth)
  976. .first->second;
  977. US.Range = PS.Use;
  978. for (const auto &Call : PS.Calls) {
  979. assert(!Call.Offsets.isFullSet());
  980. FunctionSummary *S =
  981. findCalleeFunctionSummary(Call.Callee, FS->modulePath());
  982. ++NumCombinedCalleeLookupTotal;
  983. if (!S) {
  984. ++NumCombinedCalleeLookupFailed;
  985. US.Range = FullSet;
  986. US.Calls.clear();
  987. break;
  988. }
  989. US.Calls.emplace(CallInfo<FunctionSummary>(S, Call.ParamNo),
  990. Call.Offsets);
  991. }
  992. }
  993. Functions.emplace(FS, std::move(FI));
  994. }
  995. // Reset data for all summaries. Alive and DSO local will be set back from
  996. // of data flow results below. Anything else will not be accessed
  997. // by ThinLTO backend, so we can save on bitcode size.
  998. FS->setParamAccesses({});
  999. }
  1000. }
  1001. NumCombinedDataFlowNodes += Functions.size();
  1002. StackSafetyDataFlowAnalysis<FunctionSummary> SSDFA(
  1003. FunctionSummary::ParamAccess::RangeWidth, std::move(Functions));
  1004. for (const auto &KV : SSDFA.run()) {
  1005. std::vector<FunctionSummary::ParamAccess> NewParams;
  1006. NewParams.reserve(KV.second.Params.size());
  1007. for (const auto &Param : KV.second.Params) {
  1008. // It's not needed as FullSet is processed the same as a missing value.
  1009. if (Param.second.Range.isFullSet())
  1010. continue;
  1011. NewParams.emplace_back();
  1012. FunctionSummary::ParamAccess &New = NewParams.back();
  1013. New.ParamNo = Param.first;
  1014. New.Use = Param.second.Range; // Only range is needed.
  1015. }
  1016. const_cast<FunctionSummary *>(KV.first)->setParamAccesses(
  1017. std::move(NewParams));
  1018. }
  1019. CountParamAccesses(NumCombinedParamAccessesAfter);
  1020. }
  1021. static const char LocalPassArg[] = "stack-safety-local";
  1022. static const char LocalPassName[] = "Stack Safety Local Analysis";
  1023. INITIALIZE_PASS_BEGIN(StackSafetyInfoWrapperPass, LocalPassArg, LocalPassName,
  1024. false, true)
  1025. INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
  1026. INITIALIZE_PASS_END(StackSafetyInfoWrapperPass, LocalPassArg, LocalPassName,
  1027. false, true)
  1028. static const char GlobalPassName[] = "Stack Safety Analysis";
  1029. INITIALIZE_PASS_BEGIN(StackSafetyGlobalInfoWrapperPass, DEBUG_TYPE,
  1030. GlobalPassName, false, true)
  1031. INITIALIZE_PASS_DEPENDENCY(StackSafetyInfoWrapperPass)
  1032. INITIALIZE_PASS_DEPENDENCY(ImmutableModuleSummaryIndexWrapperPass)
  1033. INITIALIZE_PASS_END(StackSafetyGlobalInfoWrapperPass, DEBUG_TYPE,
  1034. GlobalPassName, false, true)