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     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 (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 (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       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         auto B = CB.arg_begin(), E = CB.arg_end();
356         int Found = 0;
357         for (auto A = B; A != E; ++A) {
358           if (A->get() == V) {
359             ++Found;
360             ConstantRange Offset = offsetFrom(UI, Ptr);
361             US.Calls.emplace_back(Callee, A - B, Offset);
362           }
363         }
364         if (!Found) {
365           US.updateRange(UnknownRange);
366           return false;
367         }
368 
369         break;
370       }
371 
372       default:
373         if (Visited.insert(I).second)
374           WorkList.push_back(cast<const Instruction>(I));
375       }
376     }
377   }
378 
379   return true;
380 }
381 
382 FunctionInfo StackSafetyLocalAnalysis::run() {
383   FunctionInfo Info;
384   assert(!F.isDeclaration() &&
385          "Can't run StackSafety on a function declaration");
386 
387   LLVM_DEBUG(dbgs() << "[StackSafety] " << F.getName() << "\n");
388 
389   for (auto &I : instructions(F)) {
390     if (auto AI = dyn_cast<AllocaInst>(&I)) {
391       Info.Allocas.emplace_back(PointerSize);
392       UseInfo &AS = Info.Allocas.back();
393       analyzeAllUses(AI, AS);
394     }
395   }
396 
397   for (Argument &A : make_range(F.arg_begin(), F.arg_end())) {
398     Info.Params.emplace_back(PointerSize);
399     UseInfo &PS = Info.Params.back();
400     analyzeAllUses(&A, PS);
401   }
402 
403   LLVM_DEBUG(Info.print(dbgs(), F.getName(), &F));
404   LLVM_DEBUG(dbgs() << "[StackSafety] done\n");
405   return Info;
406 }
407 
408 class StackSafetyDataFlowAnalysis {
409   using FunctionMap = std::map<const GlobalValue *, FunctionInfo>;
410 
411   FunctionMap Functions;
412   const ConstantRange UnknownRange;
413 
414   // Callee-to-Caller multimap.
415   DenseMap<const GlobalValue *, SmallVector<const GlobalValue *, 4>> Callers;
416   SetVector<const GlobalValue *> WorkList;
417 
418 
419   bool updateOneUse(UseInfo &US, bool UpdateToFullSet);
420   void updateOneNode(const GlobalValue *Callee, FunctionInfo &FS);
421   void updateOneNode(const GlobalValue *Callee) {
422     updateOneNode(Callee, Functions.find(Callee)->second);
423   }
424   void updateAllNodes() {
425     for (auto &F : Functions)
426       updateOneNode(F.first, F.second);
427   }
428   void runDataFlow();
429 #ifndef NDEBUG
430   void verifyFixedPoint();
431 #endif
432 
433 public:
434   StackSafetyDataFlowAnalysis(uint32_t PointerBitWidth, FunctionMap Functions)
435       : Functions(std::move(Functions)),
436         UnknownRange(ConstantRange::getFull(PointerBitWidth)) {}
437 
438   const FunctionMap &run();
439 
440   ConstantRange getArgumentAccessRange(const GlobalValue *Callee,
441                                        unsigned ParamNo,
442                                        const ConstantRange &Offsets) const;
443 };
444 
445 ConstantRange StackSafetyDataFlowAnalysis::getArgumentAccessRange(
446     const GlobalValue *Callee, unsigned ParamNo,
447     const ConstantRange &Offsets) const {
448   auto IT = Functions.find(Callee);
449   // Unknown callee (outside of LTO domain or an indirect call).
450   if (IT == Functions.end())
451     return UnknownRange;
452   const FunctionInfo &FS = IT->second;
453   if (ParamNo >= FS.Params.size()) // possibly vararg
454     return UnknownRange;
455   auto &Access = FS.Params[ParamNo].Range;
456   if (Access.isEmptySet())
457     return Access;
458   if (Access.isFullSet() || Offsets.isFullSet())
459     return UnknownRange;
460   if (Offsets.signedAddMayOverflow(Access) !=
461       ConstantRange::OverflowResult::NeverOverflows)
462     return UnknownRange;
463   return Access.add(Offsets);
464 }
465 
466 bool StackSafetyDataFlowAnalysis::updateOneUse(UseInfo &US,
467                                                bool UpdateToFullSet) {
468   bool Changed = false;
469   for (auto &CS : US.Calls) {
470     assert(!CS.Offset.isEmptySet() &&
471            "Param range can't be empty-set, invalid offset range");
472 
473     ConstantRange CalleeRange =
474         getArgumentAccessRange(CS.Callee, CS.ParamNo, CS.Offset);
475     if (!US.Range.contains(CalleeRange)) {
476       Changed = true;
477       if (UpdateToFullSet)
478         US.Range = UnknownRange;
479       else
480         US.Range = US.Range.unionWith(CalleeRange);
481     }
482   }
483   return Changed;
484 }
485 
486 void StackSafetyDataFlowAnalysis::updateOneNode(const GlobalValue *Callee,
487                                                 FunctionInfo &FS) {
488   bool UpdateToFullSet = FS.UpdateCount > StackSafetyMaxIterations;
489   bool Changed = false;
490   for (auto &PS : FS.Params)
491     Changed |= updateOneUse(PS, UpdateToFullSet);
492 
493   if (Changed) {
494     LLVM_DEBUG(dbgs() << "=== update [" << FS.UpdateCount
495                       << (UpdateToFullSet ? ", full-set" : "") << "] " << &FS
496                       << "\n");
497     // Callers of this function may need updating.
498     for (auto &CallerID : Callers[Callee])
499       WorkList.insert(CallerID);
500 
501     ++FS.UpdateCount;
502   }
503 }
504 
505 void StackSafetyDataFlowAnalysis::runDataFlow() {
506   Callers.clear();
507   WorkList.clear();
508 
509   SmallVector<const GlobalValue *, 16> Callees;
510   for (auto &F : Functions) {
511     Callees.clear();
512     FunctionInfo &FS = F.second;
513     for (auto &PS : FS.Params)
514       for (auto &CS : PS.Calls)
515         Callees.push_back(CS.Callee);
516 
517     llvm::sort(Callees);
518     Callees.erase(std::unique(Callees.begin(), Callees.end()), Callees.end());
519 
520     for (auto &Callee : Callees)
521       Callers[Callee].push_back(F.first);
522   }
523 
524   updateAllNodes();
525 
526   while (!WorkList.empty()) {
527     const GlobalValue *Callee = WorkList.back();
528     WorkList.pop_back();
529     updateOneNode(Callee);
530   }
531 }
532 
533 #ifndef NDEBUG
534 void StackSafetyDataFlowAnalysis::verifyFixedPoint() {
535   WorkList.clear();
536   updateAllNodes();
537   assert(WorkList.empty());
538 }
539 #endif
540 
541 const StackSafetyDataFlowAnalysis::FunctionMap &
542 StackSafetyDataFlowAnalysis::run() {
543   runDataFlow();
544   LLVM_DEBUG(verifyFixedPoint());
545   return Functions;
546 }
547 
548 bool setStackSafetyMetadata(Module &M, const GVToSSI &SSGI) {
549   bool Changed = false;
550   for (auto &F : M.functions()) {
551     if (F.isDeclaration() || F.hasOptNone())
552       continue;
553     auto Iter = SSGI.find(&F);
554     if (Iter == SSGI.end())
555       continue;
556     const FunctionInfo &Summary = Iter->second;
557     size_t Pos = 0;
558     for (auto &I : instructions(F)) {
559       if (auto AI = dyn_cast<AllocaInst>(&I)) {
560         auto &AS = Summary.Allocas[Pos];
561         if (getStaticAllocaSizeRange(*AI).contains(AS.Range)) {
562           AI->setMetadata(M.getMDKindID("stack-safe"),
563                           MDNode::get(M.getContext(), None));
564           Changed = true;
565         }
566         ++Pos;
567       }
568     }
569   }
570   return Changed;
571 }
572 
573 const Function *FindCalleeInModule(const GlobalValue *GV) {
574   while (GV) {
575     if (GV->isInterposable() || !GV->isDSOLocal())
576       return nullptr;
577     if (const Function *F = dyn_cast<Function>(GV))
578       return F;
579     const GlobalAlias *A = dyn_cast<GlobalAlias>(GV);
580     if (!A)
581       return nullptr;
582     GV = A->getBaseObject();
583     if (GV == A)
584       return nullptr;
585   }
586   return nullptr;
587 }
588 
589 void ResolveAllCalls(UseInfo &Use) {
590   ConstantRange FullSet(Use.Range.getBitWidth(), true);
591   for (auto &C : Use.Calls) {
592     const Function *F = FindCalleeInModule(C.Callee);
593     if (F) {
594       C.Callee = F;
595       continue;
596     }
597 
598     return Use.updateRange(FullSet);
599   }
600 }
601 
602 void ResolveAllCalls(SmallVectorImpl<UseInfo> &Values) {
603   for (auto &V : Values)
604     ResolveAllCalls(V);
605 }
606 
607 GVToSSI createGlobalStackSafetyInfo(
608     std::map<const GlobalValue *, FunctionInfo> Functions) {
609   GVToSSI SSI;
610   if (Functions.empty())
611     return SSI;
612 
613   // FIXME: Simplify printing and remove copying here.
614   auto Copy = Functions;
615 
616   for (auto &FI : Copy)
617     ResolveAllCalls(FI.second.Params);
618 
619   uint32_t PointerSize = Copy.begin()
620                              ->first->getParent()
621                              ->getDataLayout()
622                              .getMaxPointerSizeInBits();
623   StackSafetyDataFlowAnalysis SSDFA(PointerSize, std::move(Copy));
624 
625   for (auto &F : SSDFA.run()) {
626     auto FI = F.second;
627     size_t Pos = 0;
628     auto &SrcF = Functions[F.first];
629     for (auto &A : FI.Allocas) {
630       ResolveAllCalls(A);
631       for (auto &C : A.Calls) {
632         A.updateRange(
633             SSDFA.getArgumentAccessRange(C.Callee, C.ParamNo, C.Offset));
634       }
635       // FIXME: This is needed only to preserve calls in print() results.
636       A.Calls = SrcF.Allocas[Pos].Calls;
637       ++Pos;
638     }
639     Pos = 0;
640     for (auto &P : FI.Params) {
641       P.Calls = SrcF.Params[Pos].Calls;
642       ++Pos;
643     }
644     SSI[F.first] = std::move(FI);
645   }
646 
647   return SSI;
648 }
649 
650 } // end anonymous namespace
651 
652 StackSafetyInfo::StackSafetyInfo() = default;
653 
654 StackSafetyInfo::StackSafetyInfo(Function *F,
655                                  std::function<ScalarEvolution &()> GetSE)
656     : F(F), GetSE(GetSE) {}
657 
658 StackSafetyInfo::StackSafetyInfo(StackSafetyInfo &&) = default;
659 
660 StackSafetyInfo &StackSafetyInfo::operator=(StackSafetyInfo &&) = default;
661 
662 StackSafetyInfo::~StackSafetyInfo() = default;
663 
664 const StackSafetyInfo::InfoTy &StackSafetyInfo::getInfo() const {
665   if (!Info) {
666     StackSafetyLocalAnalysis SSLA(*F, GetSE());
667     Info.reset(new InfoTy{SSLA.run()});
668   }
669   return *Info;
670 }
671 
672 void StackSafetyInfo::print(raw_ostream &O) const {
673   getInfo().Info.print(O, F->getName(), dyn_cast<Function>(F));
674 }
675 
676 const StackSafetyGlobalInfo::InfoTy &StackSafetyGlobalInfo::getInfo() const {
677   if (!Info) {
678     std::map<const GlobalValue *, FunctionInfo> Functions;
679     for (auto &F : M->functions()) {
680       if (!F.isDeclaration()) {
681         auto FI = GetSSI(F).getInfo().Info;
682         Functions.emplace(&F, std::move(FI));
683       }
684     }
685     Info.reset(new InfoTy{createGlobalStackSafetyInfo(std::move(Functions))});
686   }
687   return *Info;
688 }
689 
690 StackSafetyGlobalInfo::StackSafetyGlobalInfo() = default;
691 
692 StackSafetyGlobalInfo::StackSafetyGlobalInfo(
693     Module *M, std::function<const StackSafetyInfo &(Function &F)> GetSSI)
694     : M(M), GetSSI(GetSSI) {}
695 
696 StackSafetyGlobalInfo::StackSafetyGlobalInfo(StackSafetyGlobalInfo &&) =
697     default;
698 
699 StackSafetyGlobalInfo &
700 StackSafetyGlobalInfo::operator=(StackSafetyGlobalInfo &&) = default;
701 
702 StackSafetyGlobalInfo::~StackSafetyGlobalInfo() = default;
703 
704 bool StackSafetyGlobalInfo::setMetadata(Module &M) const {
705   return setStackSafetyMetadata(M, getInfo().Info);
706 }
707 
708 void StackSafetyGlobalInfo::print(raw_ostream &O) const {
709   auto &SSI = getInfo().Info;
710   if (SSI.empty())
711     return;
712   const Module &M = *SSI.begin()->first->getParent();
713   for (auto &F : M.functions()) {
714     if (!F.isDeclaration()) {
715       SSI.find(&F)->second.print(O, F.getName(), &F);
716       O << "\n";
717     }
718   }
719 }
720 
721 LLVM_DUMP_METHOD void StackSafetyGlobalInfo::dump() const { print(dbgs()); }
722 
723 AnalysisKey StackSafetyAnalysis::Key;
724 
725 StackSafetyInfo StackSafetyAnalysis::run(Function &F,
726                                          FunctionAnalysisManager &AM) {
727   return StackSafetyInfo(&F, [&AM, &F]() -> ScalarEvolution & {
728     return AM.getResult<ScalarEvolutionAnalysis>(F);
729   });
730 }
731 
732 PreservedAnalyses StackSafetyPrinterPass::run(Function &F,
733                                               FunctionAnalysisManager &AM) {
734   OS << "'Stack Safety Local Analysis' for function '" << F.getName() << "'\n";
735   AM.getResult<StackSafetyAnalysis>(F).print(OS);
736   return PreservedAnalyses::all();
737 }
738 
739 char StackSafetyInfoWrapperPass::ID = 0;
740 
741 StackSafetyInfoWrapperPass::StackSafetyInfoWrapperPass() : FunctionPass(ID) {
742   initializeStackSafetyInfoWrapperPassPass(*PassRegistry::getPassRegistry());
743 }
744 
745 void StackSafetyInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
746   AU.addRequiredTransitive<ScalarEvolutionWrapperPass>();
747   AU.setPreservesAll();
748 }
749 
750 void StackSafetyInfoWrapperPass::print(raw_ostream &O, const Module *M) const {
751   SSI.print(O);
752 }
753 
754 bool StackSafetyInfoWrapperPass::runOnFunction(Function &F) {
755   auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
756   SSI = {&F, [SE]() -> ScalarEvolution & { return *SE; }};
757   return false;
758 }
759 
760 AnalysisKey StackSafetyGlobalAnalysis::Key;
761 
762 StackSafetyGlobalInfo
763 StackSafetyGlobalAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
764   FunctionAnalysisManager &FAM =
765       AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
766   return {&M, [&FAM](Function &F) -> const StackSafetyInfo & {
767             return FAM.getResult<StackSafetyAnalysis>(F);
768           }};
769 }
770 
771 PreservedAnalyses StackSafetyGlobalPrinterPass::run(Module &M,
772                                                     ModuleAnalysisManager &AM) {
773   OS << "'Stack Safety Analysis' for module '" << M.getName() << "'\n";
774   AM.getResult<StackSafetyGlobalAnalysis>(M).print(OS);
775   return PreservedAnalyses::all();
776 }
777 
778 PreservedAnalyses
779 StackSafetyGlobalAnnotatorPass::run(Module &M, ModuleAnalysisManager &AM) {
780   auto &SSGI = AM.getResult<StackSafetyGlobalAnalysis>(M);
781   SSGI.setMetadata(M);
782   return PreservedAnalyses::all();
783 }
784 
785 char StackSafetyGlobalInfoWrapperPass::ID = 0;
786 
787 StackSafetyGlobalInfoWrapperPass::StackSafetyGlobalInfoWrapperPass()
788     : ModulePass(ID) {
789   initializeStackSafetyGlobalInfoWrapperPassPass(
790       *PassRegistry::getPassRegistry());
791 }
792 
793 StackSafetyGlobalInfoWrapperPass::~StackSafetyGlobalInfoWrapperPass() = default;
794 
795 void StackSafetyGlobalInfoWrapperPass::print(raw_ostream &O,
796                                              const Module *M) const {
797   SSGI.print(O);
798 }
799 
800 void StackSafetyGlobalInfoWrapperPass::getAnalysisUsage(
801     AnalysisUsage &AU) const {
802   AU.addRequired<StackSafetyInfoWrapperPass>();
803 }
804 
805 bool StackSafetyGlobalInfoWrapperPass::runOnModule(Module &M) {
806   SSGI = {&M, [this](Function &F) -> const StackSafetyInfo & {
807             return getAnalysis<StackSafetyInfoWrapperPass>(F).getResult();
808           }};
809   return SSGI.setMetadata(M);
810 }
811 
812 ModulePass *llvm::createStackSafetyGlobalInfoWrapperPass() {
813   return new StackSafetyGlobalInfoWrapperPass();
814 }
815 
816 static const char LocalPassArg[] = "stack-safety-local";
817 static const char LocalPassName[] = "Stack Safety Local Analysis";
818 INITIALIZE_PASS_BEGIN(StackSafetyInfoWrapperPass, LocalPassArg, LocalPassName,
819                       false, true)
820 INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
821 INITIALIZE_PASS_END(StackSafetyInfoWrapperPass, LocalPassArg, LocalPassName,
822                     false, true)
823 
824 static const char GlobalPassName[] = "Stack Safety Analysis";
825 INITIALIZE_PASS_BEGIN(StackSafetyGlobalInfoWrapperPass, DEBUG_TYPE,
826                       GlobalPassName, false, false)
827 INITIALIZE_PASS_DEPENDENCY(StackSafetyInfoWrapperPass)
828 INITIALIZE_PASS_END(StackSafetyGlobalInfoWrapperPass, DEBUG_TYPE,
829                     GlobalPassName, false, false)
830