StackSafetyAnalysis.cpp 40 KB

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