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