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 
11 #include "llvm/Analysis/StackSafetyAnalysis.h"
12 #include "llvm/ADT/APInt.h"
13 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
14 #include "llvm/IR/ConstantRange.h"
15 #include "llvm/IR/DerivedTypes.h"
16 #include "llvm/IR/GlobalValue.h"
17 #include "llvm/IR/InstIterator.h"
18 #include "llvm/IR/Instructions.h"
19 #include "llvm/IR/IntrinsicInst.h"
20 #include "llvm/InitializePasses.h"
21 #include "llvm/Support/Casting.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include <algorithm>
25 #include <memory>
26 
27 using namespace llvm;
28 
29 #define DEBUG_TYPE "stack-safety"
30 
31 static cl::opt<int> StackSafetyMaxIterations("stack-safety-max-iterations",
32                                              cl::init(20), cl::Hidden);
33 
34 namespace {
35 
36 /// Rewrite an SCEV expression for a memory access address to an expression that
37 /// represents offset from the given alloca.
38 class AllocaOffsetRewriter : public SCEVRewriteVisitor<AllocaOffsetRewriter> {
39   const Value *AllocaPtr;
40 
41 public:
42   AllocaOffsetRewriter(ScalarEvolution &SE, const Value *AllocaPtr)
43       : SCEVRewriteVisitor(SE), AllocaPtr(AllocaPtr) {}
44 
45   const SCEV *visitUnknown(const SCEVUnknown *Expr) {
46     // FIXME: look through one or several levels of definitions?
47     // This can be inttoptr(AllocaPtr) and SCEV would not unwrap
48     // it for us.
49     if (Expr->getValue() == AllocaPtr)
50       return SE.getZero(Expr->getType());
51     return Expr;
52   }
53 };
54 
55 /// Describes use of address in as a function call argument.
56 struct PassAsArgInfo {
57   /// Function being called.
58   const GlobalValue *Callee = nullptr;
59   /// Index of argument which pass address.
60   size_t ParamNo = 0;
61   // Offset range of address from base address (alloca or calling function
62   // argument).
63   // Range should never set to empty-set, that is an invalid access range
64   // that can cause empty-set to be propagated with ConstantRange::add
65   ConstantRange Offset;
66   PassAsArgInfo(const GlobalValue *Callee, size_t ParamNo, ConstantRange Offset)
67       : Callee(Callee), ParamNo(ParamNo), Offset(Offset) {}
68 
69   StringRef getName() const { return Callee->getName(); }
70 };
71 
72 raw_ostream &operator<<(raw_ostream &OS, const PassAsArgInfo &P) {
73   return OS << "@" << P.getName() << "(arg" << P.ParamNo << ", " << P.Offset
74             << ")";
75 }
76 
77 /// Describe uses of address (alloca or parameter) inside of the function.
78 struct UseInfo {
79   // Access range if the address (alloca or parameters).
80   // It is allowed to be empty-set when there are no known accesses.
81   ConstantRange Range;
82 
83   // List of calls which pass address as an argument.
84   SmallVector<PassAsArgInfo, 4> Calls;
85 
86   explicit UseInfo(unsigned PointerSize) : Range{PointerSize, false} {}
87 
88   void updateRange(const ConstantRange &R) {
89     assert(!R.isUpperSignWrapped());
90     Range = Range.unionWith(R);
91     assert(!Range.isUpperSignWrapped());
92   }
93 };
94 
95 raw_ostream &operator<<(raw_ostream &OS, const UseInfo &U) {
96   OS << U.Range;
97   for (auto &Call : U.Calls)
98     OS << ", " << Call;
99   return OS;
100 }
101 
102 // Check if we should bailout for such ranges.
103 bool isUnsafe(const ConstantRange &R) {
104   return R.isEmptySet() || R.isFullSet() || R.isUpperSignWrapped();
105 }
106 
107 /// Calculate the allocation size of a given alloca. Returns empty range
108 // in case of confution.
109 ConstantRange getStaticAllocaSizeRange(const AllocaInst &AI) {
110   const DataLayout &DL = AI.getModule()->getDataLayout();
111   TypeSize TS = DL.getTypeAllocSize(AI.getAllocatedType());
112   unsigned PointerSize = DL.getMaxPointerSizeInBits();
113   // Fallback to empty range for alloca size.
114   ConstantRange R = ConstantRange::getEmpty(PointerSize);
115   if (TS.isScalable())
116     return R;
117   APInt APSize(PointerSize, TS.getFixedSize(), true);
118   if (APSize.isNonPositive())
119     return R;
120   if (AI.isArrayAllocation()) {
121     const auto *C = dyn_cast<ConstantInt>(AI.getArraySize());
122     if (!C)
123       return R;
124     bool Overflow = false;
125     APInt Mul = C->getValue();
126     if (Mul.isNonPositive())
127       return R;
128     Mul = Mul.sextOrTrunc(PointerSize);
129     APSize = APSize.smul_ov(Mul, Overflow);
130     if (Overflow)
131       return R;
132   }
133   R = ConstantRange(APInt::getNullValue(PointerSize), APSize);
134   assert(!isUnsafe(R));
135   return R;
136 }
137 
138 struct FunctionInfo {
139   SmallVector<UseInfo, 4> Allocas;
140   SmallVector<UseInfo, 4> Params;
141   // TODO: describe return value as depending on one or more of its arguments.
142 
143   // StackSafetyDataFlowAnalysis counter stored here for faster access.
144   int UpdateCount = 0;
145 
146   void print(raw_ostream &O, StringRef Name, const Function *F) const {
147     // TODO: Consider different printout format after
148     // StackSafetyDataFlowAnalysis. Calls and parameters are irrelevant then.
149     O << "  @" << Name << ((F && F->isDSOLocal()) ? "" : " dso_preemptable")
150       << ((F && F->isInterposable()) ? " interposable" : "") << "\n";
151 
152     O << "    args uses:\n";
153     size_t Pos = 0;
154     for (auto &P : Params) {
155       StringRef Name = "<N/A>";
156       if (F)
157         Name = F->getArg(Pos)->getName();
158       O << "      " << Name << "[]: " << P << "\n";
159       ++Pos;
160     }
161 
162     O << "    allocas uses:\n";
163     if (F) {
164       size_t Pos = 0;
165       for (auto &I : instructions(F)) {
166         if (const auto *AI = dyn_cast<AllocaInst>(&I)) {
167           auto &AS = Allocas[Pos];
168           O << "      " << AI->getName() << "["
169             << getStaticAllocaSizeRange(*AI).getUpper() << "]: " << AS << "\n";
170           ++Pos;
171         }
172       }
173     } else {
174       assert(Allocas.empty());
175     }
176   }
177 };
178 
179 using GVToSSI = std::map<const GlobalValue *, FunctionInfo>;
180 
181 } // namespace
182 
183 struct StackSafetyInfo::InfoTy {
184   FunctionInfo Info;
185 };
186 
187 struct StackSafetyGlobalInfo::InfoTy {
188   GVToSSI Info;
189 };
190 
191 namespace {
192 
193 class StackSafetyLocalAnalysis {
194   Function &F;
195   const DataLayout &DL;
196   ScalarEvolution &SE;
197   unsigned PointerSize = 0;
198 
199   const ConstantRange UnknownRange;
200 
201   ConstantRange offsetFrom(Value *Addr, Value *Base);
202   ConstantRange getAccessRange(Value *Addr, Value *Base,
203                                ConstantRange SizeRange);
204   ConstantRange getAccessRange(Value *Addr, Value *Base, TypeSize Size);
205   ConstantRange getMemIntrinsicAccessRange(const MemIntrinsic *MI, const Use &U,
206                                            Value *Base);
207 
208   bool analyzeAllUses(Value *Ptr, UseInfo &AS);
209 
210 public:
211   StackSafetyLocalAnalysis(Function &F, ScalarEvolution &SE)
212       : F(F), DL(F.getParent()->getDataLayout()), SE(SE),
213         PointerSize(DL.getPointerSizeInBits()),
214         UnknownRange(PointerSize, true) {}
215 
216   // Run the transformation on the associated function.
217   FunctionInfo run();
218 };
219 
220 ConstantRange StackSafetyLocalAnalysis::offsetFrom(Value *Addr, Value *Base) {
221   if (!SE.isSCEVable(Addr->getType()))
222     return UnknownRange;
223 
224   AllocaOffsetRewriter Rewriter(SE, Base);
225   const SCEV *Expr = Rewriter.visit(SE.getSCEV(Addr));
226   ConstantRange Offset = SE.getSignedRange(Expr);
227   if (isUnsafe(Offset))
228     return UnknownRange;
229   return Offset.sextOrTrunc(PointerSize);
230 }
231 
232 ConstantRange
233 StackSafetyLocalAnalysis::getAccessRange(Value *Addr, Value *Base,
234                                          ConstantRange SizeRange) {
235   // Zero-size loads and stores do not access memory.
236   if (SizeRange.isEmptySet())
237     return ConstantRange::getEmpty(PointerSize);
238   assert(!isUnsafe(SizeRange));
239 
240   ConstantRange Offsets = offsetFrom(Addr, Base);
241   if (isUnsafe(Offsets))
242     return UnknownRange;
243 
244   if (Offsets.signedAddMayOverflow(SizeRange) !=
245       ConstantRange::OverflowResult::NeverOverflows)
246     return UnknownRange;
247   Offsets = Offsets.add(SizeRange);
248   if (isUnsafe(Offsets))
249     return UnknownRange;
250   return Offsets;
251 }
252 
253 ConstantRange StackSafetyLocalAnalysis::getAccessRange(Value *Addr, Value *Base,
254                                                        TypeSize Size) {
255   if (Size.isScalable())
256     return UnknownRange;
257   APInt APSize(PointerSize, Size.getFixedSize(), true);
258   if (APSize.isNegative())
259     return UnknownRange;
260   return getAccessRange(
261       Addr, Base, ConstantRange(APInt::getNullValue(PointerSize), APSize));
262 }
263 
264 ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
265     const MemIntrinsic *MI, const Use &U, Value *Base) {
266   if (const auto *MTI = dyn_cast<MemTransferInst>(MI)) {
267     if (MTI->getRawSource() != U && MTI->getRawDest() != U)
268       return ConstantRange::getEmpty(PointerSize);
269   } else {
270     if (MI->getRawDest() != U)
271       return ConstantRange::getEmpty(PointerSize);
272   }
273 
274   auto *CalculationTy = IntegerType::getIntNTy(SE.getContext(), PointerSize);
275   if (!SE.isSCEVable(MI->getLength()->getType()))
276     return UnknownRange;
277 
278   const SCEV *Expr =
279       SE.getTruncateOrZeroExtend(SE.getSCEV(MI->getLength()), CalculationTy);
280   ConstantRange Sizes = SE.getSignedRange(Expr);
281   if (Sizes.getUpper().isNegative() || isUnsafe(Sizes))
282     return UnknownRange;
283   Sizes = Sizes.sextOrTrunc(PointerSize);
284   ConstantRange SizeRange(APInt::getNullValue(PointerSize),
285                           Sizes.getUpper() - 1);
286   return getAccessRange(U, Base, SizeRange);
287 }
288 
289 /// The function analyzes all local uses of Ptr (alloca or argument) and
290 /// calculates local access range and all function calls where it was used.
291 bool StackSafetyLocalAnalysis::analyzeAllUses(Value *Ptr, UseInfo &US) {
292   SmallPtrSet<const Value *, 16> Visited;
293   SmallVector<const Value *, 8> WorkList;
294   WorkList.push_back(Ptr);
295 
296   // A DFS search through all uses of the alloca in bitcasts/PHI/GEPs/etc.
297   while (!WorkList.empty()) {
298     const Value *V = WorkList.pop_back_val();
299     for (const Use &UI : V->uses()) {
300       const auto *I = cast<const Instruction>(UI.getUser());
301       assert(V == UI.get());
302 
303       switch (I->getOpcode()) {
304       case Instruction::Load: {
305         US.updateRange(
306             getAccessRange(UI, Ptr, DL.getTypeStoreSize(I->getType())));
307         break;
308       }
309 
310       case Instruction::VAArg:
311         // "va-arg" from a pointer is safe.
312         break;
313       case Instruction::Store: {
314         if (V == I->getOperand(0)) {
315           // Stored the pointer - conservatively assume it may be unsafe.
316           US.updateRange(UnknownRange);
317           return false;
318         }
319         US.updateRange(getAccessRange(
320             UI, Ptr, DL.getTypeStoreSize(I->getOperand(0)->getType())));
321         break;
322       }
323 
324       case Instruction::Ret:
325         // Information leak.
326         // FIXME: Process parameters correctly. This is a leak only if we return
327         // alloca.
328         US.updateRange(UnknownRange);
329         return false;
330 
331       case Instruction::Call:
332       case Instruction::Invoke: {
333         const auto &CB = cast<CallBase>(*I);
334 
335         if (I->isLifetimeStartOrEnd())
336           break;
337 
338         if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
339           US.updateRange(getMemIntrinsicAccessRange(MI, UI, Ptr));
340           break;
341         }
342 
343         // FIXME: consult devirt?
344         // Do not follow aliases, otherwise we could inadvertently follow
345         // dso_preemptable aliases or aliases with interposable linkage.
346         const GlobalValue *Callee =
347             dyn_cast<GlobalValue>(CB.getCalledOperand()->stripPointerCasts());
348         if (!Callee) {
349           US.updateRange(UnknownRange);
350           return false;
351         }
352 
353         assert(isa<Function>(Callee) || isa<GlobalAlias>(Callee));
354 
355         int Found = 0;
356         for (size_t ArgNo = 0; ArgNo < CB.getNumArgOperands(); ++ArgNo) {
357           if (CB.getArgOperand(ArgNo) == V) {
358             ++Found;
359             US.Calls.emplace_back(Callee, ArgNo, offsetFrom(UI, Ptr));
360           }
361         }
362         if (!Found) {
363           US.updateRange(UnknownRange);
364           return false;
365         }
366 
367         break;
368       }
369 
370       default:
371         if (Visited.insert(I).second)
372           WorkList.push_back(cast<const Instruction>(I));
373       }
374     }
375   }
376 
377   return true;
378 }
379 
380 FunctionInfo StackSafetyLocalAnalysis::run() {
381   FunctionInfo Info;
382   assert(!F.isDeclaration() &&
383          "Can't run StackSafety on a function declaration");
384 
385   LLVM_DEBUG(dbgs() << "[StackSafety] " << F.getName() << "\n");
386 
387   for (auto &I : instructions(F)) {
388     if (auto *AI = dyn_cast<AllocaInst>(&I)) {
389       Info.Allocas.emplace_back(PointerSize);
390       UseInfo &AS = Info.Allocas.back();
391       analyzeAllUses(AI, AS);
392     }
393   }
394 
395   for (Argument &A : make_range(F.arg_begin(), F.arg_end())) {
396     Info.Params.emplace_back(PointerSize);
397     UseInfo &PS = Info.Params.back();
398     analyzeAllUses(&A, PS);
399   }
400 
401   LLVM_DEBUG(Info.print(dbgs(), F.getName(), &F));
402   LLVM_DEBUG(dbgs() << "[StackSafety] done\n");
403   return Info;
404 }
405 
406 class StackSafetyDataFlowAnalysis {
407   using FunctionMap = std::map<const GlobalValue *, FunctionInfo>;
408 
409   FunctionMap Functions;
410   const ConstantRange UnknownRange;
411 
412   // Callee-to-Caller multimap.
413   DenseMap<const GlobalValue *, SmallVector<const GlobalValue *, 4>> Callers;
414   SetVector<const GlobalValue *> WorkList;
415 
416 
417   bool updateOneUse(UseInfo &US, bool UpdateToFullSet);
418   void updateOneNode(const GlobalValue *Callee, FunctionInfo &FS);
419   void updateOneNode(const GlobalValue *Callee) {
420     updateOneNode(Callee, Functions.find(Callee)->second);
421   }
422   void updateAllNodes() {
423     for (auto &F : Functions)
424       updateOneNode(F.first, F.second);
425   }
426   void runDataFlow();
427 #ifndef NDEBUG
428   void verifyFixedPoint();
429 #endif
430 
431 public:
432   StackSafetyDataFlowAnalysis(uint32_t PointerBitWidth, FunctionMap Functions)
433       : Functions(std::move(Functions)),
434         UnknownRange(ConstantRange::getFull(PointerBitWidth)) {}
435 
436   const FunctionMap &run();
437 
438   ConstantRange getArgumentAccessRange(const GlobalValue *Callee,
439                                        unsigned ParamNo,
440                                        const ConstantRange &Offsets) const;
441 };
442 
443 ConstantRange StackSafetyDataFlowAnalysis::getArgumentAccessRange(
444     const GlobalValue *Callee, unsigned ParamNo,
445     const ConstantRange &Offsets) const {
446   auto IT = Functions.find(Callee);
447   // Unknown callee (outside of LTO domain or an indirect call).
448   if (IT == Functions.end())
449     return UnknownRange;
450   const FunctionInfo &FS = IT->second;
451   if (ParamNo >= FS.Params.size()) // possibly vararg
452     return UnknownRange;
453   auto &Access = FS.Params[ParamNo].Range;
454   if (Access.isEmptySet())
455     return Access;
456   if (Access.isFullSet() || Offsets.isFullSet())
457     return UnknownRange;
458   if (Offsets.signedAddMayOverflow(Access) !=
459       ConstantRange::OverflowResult::NeverOverflows)
460     return UnknownRange;
461   return Access.add(Offsets);
462 }
463 
464 bool StackSafetyDataFlowAnalysis::updateOneUse(UseInfo &US,
465                                                bool UpdateToFullSet) {
466   bool Changed = false;
467   for (auto &CS : US.Calls) {
468     assert(!CS.Offset.isEmptySet() &&
469            "Param range can't be empty-set, invalid offset range");
470 
471     ConstantRange CalleeRange =
472         getArgumentAccessRange(CS.Callee, CS.ParamNo, CS.Offset);
473     if (!US.Range.contains(CalleeRange)) {
474       Changed = true;
475       if (UpdateToFullSet)
476         US.Range = UnknownRange;
477       else
478         US.Range = US.Range.unionWith(CalleeRange);
479     }
480   }
481   return Changed;
482 }
483 
484 void StackSafetyDataFlowAnalysis::updateOneNode(const GlobalValue *Callee,
485                                                 FunctionInfo &FS) {
486   bool UpdateToFullSet = FS.UpdateCount > StackSafetyMaxIterations;
487   bool Changed = false;
488   for (auto &PS : FS.Params)
489     Changed |= updateOneUse(PS, UpdateToFullSet);
490 
491   if (Changed) {
492     LLVM_DEBUG(dbgs() << "=== update [" << FS.UpdateCount
493                       << (UpdateToFullSet ? ", full-set" : "") << "] " << &FS
494                       << "\n");
495     // Callers of this function may need updating.
496     for (auto &CallerID : Callers[Callee])
497       WorkList.insert(CallerID);
498 
499     ++FS.UpdateCount;
500   }
501 }
502 
503 void StackSafetyDataFlowAnalysis::runDataFlow() {
504   Callers.clear();
505   WorkList.clear();
506 
507   SmallVector<const GlobalValue *, 16> Callees;
508   for (auto &F : Functions) {
509     Callees.clear();
510     FunctionInfo &FS = F.second;
511     for (auto &PS : FS.Params)
512       for (auto &CS : PS.Calls)
513         Callees.push_back(CS.Callee);
514 
515     llvm::sort(Callees);
516     Callees.erase(std::unique(Callees.begin(), Callees.end()), Callees.end());
517 
518     for (auto &Callee : Callees)
519       Callers[Callee].push_back(F.first);
520   }
521 
522   updateAllNodes();
523 
524   while (!WorkList.empty()) {
525     const GlobalValue *Callee = WorkList.back();
526     WorkList.pop_back();
527     updateOneNode(Callee);
528   }
529 }
530 
531 #ifndef NDEBUG
532 void StackSafetyDataFlowAnalysis::verifyFixedPoint() {
533   WorkList.clear();
534   updateAllNodes();
535   assert(WorkList.empty());
536 }
537 #endif
538 
539 const StackSafetyDataFlowAnalysis::FunctionMap &
540 StackSafetyDataFlowAnalysis::run() {
541   runDataFlow();
542   LLVM_DEBUG(verifyFixedPoint());
543   return Functions;
544 }
545 
546 bool setStackSafetyMetadata(Module &M, const GVToSSI &SSGI) {
547   bool Changed = false;
548   for (auto &F : M.functions()) {
549     if (F.isDeclaration() || F.hasOptNone())
550       continue;
551     auto Iter = SSGI.find(&F);
552     if (Iter == SSGI.end())
553       continue;
554     const FunctionInfo &Summary = Iter->second;
555     size_t Pos = 0;
556     for (auto &I : instructions(F)) {
557       if (auto *AI = dyn_cast<AllocaInst>(&I)) {
558         auto &AS = Summary.Allocas[Pos];
559         if (getStaticAllocaSizeRange(*AI).contains(AS.Range)) {
560           AI->setMetadata(M.getMDKindID("stack-safe"),
561                           MDNode::get(M.getContext(), None));
562           Changed = true;
563         }
564         ++Pos;
565       }
566     }
567   }
568   return Changed;
569 }
570 
571 const Function *findCalleeInModule(const GlobalValue *GV) {
572   while (GV) {
573     if (GV->isInterposable() || !GV->isDSOLocal())
574       return nullptr;
575     if (const Function *F = dyn_cast<Function>(GV))
576       return F;
577     const GlobalAlias *A = dyn_cast<GlobalAlias>(GV);
578     if (!A)
579       return nullptr;
580     GV = A->getBaseObject();
581     if (GV == A)
582       return nullptr;
583   }
584   return nullptr;
585 }
586 
587 void resolveAllCalls(UseInfo &Use) {
588   ConstantRange FullSet(Use.Range.getBitWidth(), true);
589   for (auto &C : Use.Calls) {
590     const Function *F = findCalleeInModule(C.Callee);
591     if (F) {
592       C.Callee = F;
593       continue;
594     }
595 
596     return Use.updateRange(FullSet);
597   }
598 }
599 
600 void resolveAllCalls(SmallVectorImpl<UseInfo> &Values) {
601   for (auto &V : Values)
602     resolveAllCalls(V);
603 }
604 
605 GVToSSI createGlobalStackSafetyInfo(
606     std::map<const GlobalValue *, FunctionInfo> Functions) {
607   GVToSSI SSI;
608   if (Functions.empty())
609     return SSI;
610 
611   // FIXME: Simplify printing and remove copying here.
612   auto Copy = Functions;
613 
614   for (auto &FI : Copy)
615     resolveAllCalls(FI.second.Params);
616 
617   uint32_t PointerSize = Copy.begin()
618                              ->first->getParent()
619                              ->getDataLayout()
620                              .getMaxPointerSizeInBits();
621   StackSafetyDataFlowAnalysis SSDFA(PointerSize, std::move(Copy));
622 
623   for (auto &F : SSDFA.run()) {
624     auto FI = F.second;
625     size_t Pos = 0;
626     auto &SrcF = Functions[F.first];
627     for (auto &A : FI.Allocas) {
628       resolveAllCalls(A);
629       for (auto &C : A.Calls) {
630         A.updateRange(
631             SSDFA.getArgumentAccessRange(C.Callee, C.ParamNo, C.Offset));
632       }
633       // FIXME: This is needed only to preserve calls in print() results.
634       A.Calls = SrcF.Allocas[Pos].Calls;
635       ++Pos;
636     }
637     Pos = 0;
638     for (auto &P : FI.Params) {
639       P.Calls = SrcF.Params[Pos].Calls;
640       ++Pos;
641     }
642     SSI[F.first] = std::move(FI);
643   }
644 
645   return SSI;
646 }
647 
648 } // end anonymous namespace
649 
650 StackSafetyInfo::StackSafetyInfo() = default;
651 
652 StackSafetyInfo::StackSafetyInfo(Function *F,
653                                  std::function<ScalarEvolution &()> GetSE)
654     : F(F), GetSE(GetSE) {}
655 
656 StackSafetyInfo::StackSafetyInfo(StackSafetyInfo &&) = default;
657 
658 StackSafetyInfo &StackSafetyInfo::operator=(StackSafetyInfo &&) = default;
659 
660 StackSafetyInfo::~StackSafetyInfo() = default;
661 
662 const StackSafetyInfo::InfoTy &StackSafetyInfo::getInfo() const {
663   if (!Info) {
664     StackSafetyLocalAnalysis SSLA(*F, GetSE());
665     Info.reset(new InfoTy{SSLA.run()});
666   }
667   return *Info;
668 }
669 
670 void StackSafetyInfo::print(raw_ostream &O) const {
671   getInfo().Info.print(O, F->getName(), dyn_cast<Function>(F));
672 }
673 
674 const StackSafetyGlobalInfo::InfoTy &StackSafetyGlobalInfo::getInfo() const {
675   if (!Info) {
676     std::map<const GlobalValue *, FunctionInfo> Functions;
677     for (auto &F : M->functions()) {
678       if (!F.isDeclaration()) {
679         auto FI = GetSSI(F).getInfo().Info;
680         Functions.emplace(&F, std::move(FI));
681       }
682     }
683     Info.reset(new InfoTy{createGlobalStackSafetyInfo(std::move(Functions))});
684   }
685   return *Info;
686 }
687 
688 StackSafetyGlobalInfo::StackSafetyGlobalInfo() = default;
689 
690 StackSafetyGlobalInfo::StackSafetyGlobalInfo(
691     Module *M, std::function<const StackSafetyInfo &(Function &F)> GetSSI)
692     : M(M), GetSSI(GetSSI) {}
693 
694 StackSafetyGlobalInfo::StackSafetyGlobalInfo(StackSafetyGlobalInfo &&) =
695     default;
696 
697 StackSafetyGlobalInfo &
698 StackSafetyGlobalInfo::operator=(StackSafetyGlobalInfo &&) = default;
699 
700 StackSafetyGlobalInfo::~StackSafetyGlobalInfo() = default;
701 
702 bool StackSafetyGlobalInfo::setMetadata(Module &M) const {
703   return setStackSafetyMetadata(M, getInfo().Info);
704 }
705 
706 void StackSafetyGlobalInfo::print(raw_ostream &O) const {
707   auto &SSI = getInfo().Info;
708   if (SSI.empty())
709     return;
710   const Module &M = *SSI.begin()->first->getParent();
711   for (auto &F : M.functions()) {
712     if (!F.isDeclaration()) {
713       SSI.find(&F)->second.print(O, F.getName(), &F);
714       O << "\n";
715     }
716   }
717 }
718 
719 LLVM_DUMP_METHOD void StackSafetyGlobalInfo::dump() const { print(dbgs()); }
720 
721 AnalysisKey StackSafetyAnalysis::Key;
722 
723 StackSafetyInfo StackSafetyAnalysis::run(Function &F,
724                                          FunctionAnalysisManager &AM) {
725   return StackSafetyInfo(&F, [&AM, &F]() -> ScalarEvolution & {
726     return AM.getResult<ScalarEvolutionAnalysis>(F);
727   });
728 }
729 
730 PreservedAnalyses StackSafetyPrinterPass::run(Function &F,
731                                               FunctionAnalysisManager &AM) {
732   OS << "'Stack Safety Local Analysis' for function '" << F.getName() << "'\n";
733   AM.getResult<StackSafetyAnalysis>(F).print(OS);
734   return PreservedAnalyses::all();
735 }
736 
737 char StackSafetyInfoWrapperPass::ID = 0;
738 
739 StackSafetyInfoWrapperPass::StackSafetyInfoWrapperPass() : FunctionPass(ID) {
740   initializeStackSafetyInfoWrapperPassPass(*PassRegistry::getPassRegistry());
741 }
742 
743 void StackSafetyInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
744   AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
745   AU.setPreservesAll();
746 }
747 
748 void StackSafetyInfoWrapperPass::print(raw_ostream &O, const Module *M) const {
749   SSI.print(O);
750 }
751 
752 bool StackSafetyInfoWrapperPass::runOnFunction(Function &F) {
753   auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
754   SSI = {&F, [SE]() -> ScalarEvolution & { return *SE; }};
755   return false;
756 }
757 
758 AnalysisKey StackSafetyGlobalAnalysis::Key;
759 
760 StackSafetyGlobalInfo
761 StackSafetyGlobalAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
762   FunctionAnalysisManager &FAM =
763       AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
764   return {&M, [&FAM](Function &F) -> const StackSafetyInfo & {
765             return FAM.getResult<StackSafetyAnalysis>(F);
766           }};
767 }
768 
769 PreservedAnalyses StackSafetyGlobalPrinterPass::run(Module &M,
770                                                     ModuleAnalysisManager &AM) {
771   OS << "'Stack Safety Analysis' for module '" << M.getName() << "'\n";
772   AM.getResult<StackSafetyGlobalAnalysis>(M).print(OS);
773   return PreservedAnalyses::all();
774 }
775 
776 PreservedAnalyses
777 StackSafetyGlobalAnnotatorPass::run(Module &M, ModuleAnalysisManager &AM) {
778   auto &SSGI = AM.getResult<StackSafetyGlobalAnalysis>(M);
779   SSGI.setMetadata(M);
780   return PreservedAnalyses::all();
781 }
782 
783 char StackSafetyGlobalInfoWrapperPass::ID = 0;
784 
785 StackSafetyGlobalInfoWrapperPass::StackSafetyGlobalInfoWrapperPass()
786     : ModulePass(ID) {
787   initializeStackSafetyGlobalInfoWrapperPassPass(
788       *PassRegistry::getPassRegistry());
789 }
790 
791 StackSafetyGlobalInfoWrapperPass::~StackSafetyGlobalInfoWrapperPass() = default;
792 
793 void StackSafetyGlobalInfoWrapperPass::print(raw_ostream &O,
794                                              const Module *M) const {
795   SSGI.print(O);
796 }
797 
798 void StackSafetyGlobalInfoWrapperPass::getAnalysisUsage(
799     AnalysisUsage &AU) const {
800   AU.addRequired<StackSafetyInfoWrapperPass>();
801 }
802 
803 bool StackSafetyGlobalInfoWrapperPass::runOnModule(Module &M) {
804   SSGI = {&M, [this](Function &F) -> const StackSafetyInfo & {
805             return getAnalysis<StackSafetyInfoWrapperPass>(F).getResult();
806           }};
807   return SSGI.setMetadata(M);
808 }
809 
810 ModulePass *llvm::createStackSafetyGlobalInfoWrapperPass() {
811   return new StackSafetyGlobalInfoWrapperPass();
812 }
813 
814 static const char LocalPassArg[] = "stack-safety-local";
815 static const char LocalPassName[] = "Stack Safety Local Analysis";
816 INITIALIZE_PASS_BEGIN(StackSafetyInfoWrapperPass, LocalPassArg, LocalPassName,
817                       false, true)
818 INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
819 INITIALIZE_PASS_END(StackSafetyInfoWrapperPass, LocalPassArg, LocalPassName,
820                     false, true)
821 
822 static const char GlobalPassName[] = "Stack Safety Analysis";
823 INITIALIZE_PASS_BEGIN(StackSafetyGlobalInfoWrapperPass, DEBUG_TYPE,
824                       GlobalPassName, false, false)
825 INITIALIZE_PASS_DEPENDENCY(StackSafetyInfoWrapperPass)
826 INITIALIZE_PASS_END(StackSafetyGlobalInfoWrapperPass, DEBUG_TYPE,
827                     GlobalPassName, false, false)
828