37#define DEBUG_TYPE "stack-safety"
39STATISTIC(NumAllocaStackSafe,
"Number of safe allocas");
40STATISTIC(NumAllocaTotal,
"Number of total allocas");
43 "Number of total callee lookups on combined index.");
45 "Number of failed callee lookups on combined index.");
47 "Number of total callee lookups on module index.");
49 "Number of failed callee lookups on module index.");
51 "Number of total param accesses before generateParamAccessSummary.");
53 "Number of total param accesses after generateParamAccessSummary.");
55 "Number of total nodes in combined index for dataflow processing.");
56STATISTIC(NumIndexCalleeUnhandled,
"Number of index callee which are unhandled.");
57STATISTIC(NumIndexCalleeMultipleWeak,
"Number of index callee non-unique weak.");
58STATISTIC(NumIndexCalleeMultipleExternal,
"Number of index callee non-unique external.");
74 return R.isEmptySet() || R.isFullSet() || R.isUpperSignWrapped();
80 if (
L.signedAddMayOverflow(R) !=
82 return ConstantRange::getFull(
L.getBitWidth());
93 if (
Result.isSignWrappedSet())
99template <
typename CalleeTy>
struct CallInfo {
101 const CalleeTy *Callee =
nullptr;
105 CallInfo(
const CalleeTy *Callee,
size_t ParamNo)
106 : Callee(Callee), ParamNo(ParamNo) {}
109 bool operator()(
const CallInfo &L,
const CallInfo &R)
const {
110 return std::tie(
L.ParamNo,
L.Callee) < std::tie(
R.ParamNo,
R.Callee);
116template <
typename CalleeTy>
struct UseInfo {
120 std::set<const Instruction *> UnsafeAccesses;
127 using CallsTy = std::map<CallInfo<CalleeTy>, ConstantRange,
128 typename CallInfo<CalleeTy>::Less>;
133 void updateRange(
const ConstantRange &R) { Range = unionNoWrap(Range, R); }
134 void addRange(
const Instruction *
I,
const ConstantRange &R,
bool IsSafe) {
136 UnsafeAccesses.insert(
I);
141template <
typename CalleeTy>
144 for (
auto &
Call : U.Calls)
146 <<
"@" <<
Call.first.Callee->getName() <<
"(arg" <<
Call.first.ParamNo
147 <<
", " <<
Call.second <<
")";
162 if (APSize.isNonPositive())
168 bool Overflow =
false;
170 if (
Mul.isNonPositive())
172 Mul =
Mul.sextOrTrunc(PointerSize);
173 APSize = APSize.smul_ov(
Mul, Overflow);
182template <
typename CalleeTy>
struct FunctionInfo {
183 std::map<const AllocaInst *, UseInfo<CalleeTy>> Allocas;
184 std::map<uint32_t, UseInfo<CalleeTy>> Params;
190 void print(raw_ostream &O, StringRef Name,
const Function *
F)
const {
193 O <<
" @" <<
Name << ((
F &&
F->isDSOLocal()) ?
"" :
" dso_preemptable")
194 << ((
F &&
F->isInterposable()) ?
" interposable" :
"") <<
"\n";
196 O <<
" args uses:\n";
197 for (
auto &KV : Params) {
200 O <<
F->getArg(KV.first)->getName();
203 O <<
"[]: " << KV.second <<
"\n";
206 O <<
" allocas uses:\n";
210 auto &AS = Allocas.find(AI)->second;
212 << getStaticAllocaSizeRange(*AI).getUpper() <<
"]: " << AS <<
"\n";
221using GVToSSI = std::map<const GlobalValue *, FunctionInfo<GlobalValue>>;
226 FunctionInfo<GlobalValue>
Info;
237class StackSafetyLocalAnalysis {
241 unsigned PointerSize = 0;
251 const SCEV *getSCEVAsPointer(
Value *Val);
260 void analyzeAllUses(
Value *Ptr, UseInfo<GlobalValue> &AS,
270 :
F(
F),
DL(
F.getDataLayout()), SE(SE),
271 PointerSize(
DL.getPointerSizeInBits()),
272 UnknownRange(PointerSize,
true) {}
275 FunctionInfo<GlobalValue> run();
278const SCEV *StackSafetyLocalAnalysis::getSCEVAsPointer(
Value *Val) {
282 if (!ValTy->isPointerTy()) {
287 if (ValTy->getPointerAddressSpace() != 0)
292ConstantRange StackSafetyLocalAnalysis::offsetFrom(
Value *Addr,
Value *
Base) {
296 const SCEV *AddrExp = getSCEVAsPointer(Addr);
297 const SCEV *BaseExp = getSCEVAsPointer(
Base);
298 if (!AddrExp || !BaseExp)
313 const ConstantRange &SizeRange) {
316 return ConstantRange::getEmpty(PointerSize);
317 assert(!isUnsafe(SizeRange));
320 if (isUnsafe(Offsets))
323 Offsets = addOverflowNever(Offsets, SizeRange);
324 if (isUnsafe(Offsets))
329ConstantRange StackSafetyLocalAnalysis::getAccessRange(
Value *Addr,
Value *
Base,
331 if (
Size.isScalable())
333 APInt APSize(PointerSize,
Size.getFixedValue(),
true);
334 if (APSize.isNegative())
336 return getAccessRange(Addr,
Base,
340ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
341 const MemIntrinsic *
MI,
const Use &U,
Value *
Base) {
343 if (MTI->getRawSource() != U && MTI->getRawDest() != U)
344 return ConstantRange::getEmpty(PointerSize);
346 if (
MI->getRawDest() != U)
347 return ConstantRange::getEmpty(PointerSize);
350 auto *CalculationTy = IntegerType::getIntNTy(SE.
getContext(), PointerSize);
357 if (!
Sizes.getUpper().isStrictlyPositive() || isUnsafe(Sizes))
361 return getAccessRange(U,
Base, SizeRange);
364bool StackSafetyLocalAnalysis::isSafeAccess(
const Use &U, AllocaInst *AI,
366 return isSafeAccess(U, AI, SE.
getSCEV(V));
369bool StackSafetyLocalAnalysis::isSafeAccess(
const Use &U, AllocaInst *AI,
373 auto *CalculationTy = IntegerType::getIntNTy(SE.
getContext(), PointerSize);
375 return isSafeAccess(U, AI, SV);
378bool StackSafetyLocalAnalysis::isSafeAccess(
const Use &U, AllocaInst *AI,
379 const SCEV *AccessSize) {
388 const SCEV *AddrExp = getSCEVAsPointer(
U.get());
389 const SCEV *BaseExp = getSCEVAsPointer(AI);
390 if (!AddrExp || !BaseExp)
397 auto Size = getStaticAllocaSizeRange(*AI);
399 auto *CalculationTy = IntegerType::getIntNTy(SE.
getContext(), PointerSize);
400 auto ToDiffTy = [&](
const SCEV *
V) {
405 ToDiffTy(AccessSize));
414void StackSafetyLocalAnalysis::analyzeAllUses(
Value *Ptr,
415 UseInfo<GlobalValue> &US,
416 const StackLifetime &SL) {
417 SmallPtrSet<const Value *, 16> Visited;
418 SmallVector<const Value *, 8> WorkList;
423 while (!WorkList.
empty()) {
425 for (
const Use &UI :
V->uses()) {
432 auto RecordStore = [&](
const Value* StoredVal) {
433 if (V == StoredVal) {
435 US.addRange(
I, UnknownRange,
false);
439 US.addRange(
I, UnknownRange,
false);
442 auto TypeSize =
DL.getTypeStoreSize(StoredVal->getType());
443 auto AccessRange = getAccessRange(UI, Ptr, TypeSize);
444 bool Safe = isSafeAccess(UI, AI, TypeSize);
445 US.addRange(
I, AccessRange, Safe);
449 switch (
I->getOpcode()) {
450 case Instruction::Load: {
452 US.addRange(
I, UnknownRange,
false);
455 auto TypeSize =
DL.getTypeStoreSize(
I->getType());
456 auto AccessRange = getAccessRange(UI, Ptr, TypeSize);
457 bool Safe = isSafeAccess(UI, AI, TypeSize);
458 US.addRange(
I, AccessRange, Safe);
462 case Instruction::VAArg:
465 case Instruction::Store:
468 case Instruction::AtomicCmpXchg:
471 case Instruction::AtomicRMW:
475 case Instruction::Ret:
479 US.addRange(
I, UnknownRange,
false);
482 case Instruction::Call:
483 case Instruction::Invoke: {
484 if (
I->isLifetimeStartOrEnd())
488 US.addRange(
I, UnknownRange,
false);
492 auto AccessRange = getMemIntrinsicAccessRange(
MI, UI, Ptr);
495 if (MTI->getRawSource() != UI && MTI->getRawDest() != UI)
497 }
else if (
MI->getRawDest() != UI) {
500 Safe = Safe || isSafeAccess(UI, AI,
MI->getLength());
501 US.addRange(
I, AccessRange, Safe);
506 if (CB.getReturnedArgOperand() == V) {
511 if (!CB.isArgOperand(&UI)) {
512 US.addRange(
I, UnknownRange,
false);
516 unsigned ArgNo = CB.getArgOperandNo(&UI);
517 if (CB.isByValArgument(ArgNo)) {
518 auto TypeSize =
DL.getTypeStoreSize(CB.getParamByValType(ArgNo));
519 auto AccessRange = getAccessRange(UI, Ptr, TypeSize);
520 bool Safe = isSafeAccess(UI, AI, TypeSize);
521 US.addRange(
I, AccessRange, Safe);
528 const GlobalValue *
Callee =
531 US.addRange(
I, UnknownRange,
false);
536 ConstantRange
Offsets = offsetFrom(UI, Ptr);
538 US.Calls.emplace(CallInfo<GlobalValue>(Callee, ArgNo), Offsets);
540 Insert.first->second =
Insert.first->second.unionWith(Offsets);
552FunctionInfo<GlobalValue> StackSafetyLocalAnalysis::run() {
553 FunctionInfo<GlobalValue>
Info;
555 "Can't run StackSafety on a function declaration");
563 StackLifetime SL(
F, Allocas, StackLifetime::LivenessType::Must);
566 for (
auto *AI : Allocas) {
567 auto &UI =
Info.Allocas.emplace(AI, PointerSize).first->second;
568 analyzeAllUses(AI, UI, SL);
571 for (Argument &
A :
F.args()) {
574 if (
A.getType()->isPointerTy() && !
A.hasByValAttr()) {
575 auto &UI =
Info.Params.emplace(
A.getArgNo(), PointerSize).first->second;
576 analyzeAllUses(&
A, UI, SL);
585template <
typename CalleeTy>
class StackSafetyDataFlowAnalysis {
586 using FunctionMap = std::map<const CalleeTy *, FunctionInfo<CalleeTy>>;
588 FunctionMap Functions;
589 const ConstantRange UnknownRange;
592 DenseMap<const CalleeTy *, SmallVector<const CalleeTy *, 4>> Callers;
593 SetVector<const CalleeTy *> WorkList;
595 bool updateOneUse(UseInfo<CalleeTy> &US,
bool UpdateToFullSet);
596 void updateOneNode(
const CalleeTy *Callee, FunctionInfo<CalleeTy> &FS);
597 void updateOneNode(
const CalleeTy *Callee) {
598 updateOneNode(Callee, Functions.find(Callee)->second);
600 void updateAllNodes() {
601 for (
auto &
F : Functions)
602 updateOneNode(
F.first,
F.second);
606 void verifyFixedPoint();
610 StackSafetyDataFlowAnalysis(uint32_t PointerBitWidth, FunctionMap Functions)
611 : Functions(std::
move(Functions)),
612 UnknownRange(ConstantRange::getFull(PointerBitWidth)) {}
614 const FunctionMap &
run();
616 ConstantRange getArgumentAccessRange(
const CalleeTy *Callee,
unsigned ParamNo,
617 const ConstantRange &Offsets)
const;
620template <
typename CalleeTy>
621ConstantRange StackSafetyDataFlowAnalysis<CalleeTy>::getArgumentAccessRange(
622 const CalleeTy *Callee,
unsigned ParamNo,
623 const ConstantRange &Offsets)
const {
624 auto FnIt = Functions.find(Callee);
626 if (FnIt == Functions.end())
628 auto &
FS = FnIt->second;
629 auto ParamIt =
FS.Params.find(ParamNo);
630 if (ParamIt ==
FS.Params.end())
632 auto &
Access = ParamIt->second.Range;
637 return addOverflowNever(
Access, Offsets);
640template <
typename CalleeTy>
641bool StackSafetyDataFlowAnalysis<CalleeTy>::updateOneUse(UseInfo<CalleeTy> &US,
642 bool UpdateToFullSet) {
644 for (
auto &KV : US.Calls) {
645 assert(!KV.second.isEmptySet() &&
646 "Param range can't be empty-set, invalid offset range");
648 ConstantRange CalleeRange =
649 getArgumentAccessRange(KV.first.Callee, KV.first.ParamNo, KV.second);
650 if (!US.Range.
contains(CalleeRange)) {
653 US.Range = UnknownRange;
655 US.updateRange(CalleeRange);
661template <
typename CalleeTy>
662void StackSafetyDataFlowAnalysis<CalleeTy>::updateOneNode(
663 const CalleeTy *Callee, FunctionInfo<CalleeTy> &FS) {
666 for (
auto &KV :
FS.Params)
667 Changed |= updateOneUse(KV.second, UpdateToFullSet);
671 << (UpdateToFullSet ?
", full-set" :
"") <<
"] " << &FS
680template <
typename CalleeTy>
681void StackSafetyDataFlowAnalysis<CalleeTy>::runDataFlow() {
683 for (
auto &
F : Functions) {
686 for (
auto &KV :
FS.Params)
687 for (
auto &CS : KV.second.Calls)
693 for (
auto &Callee : Callees)
694 Callers[
Callee].push_back(
F.first);
699 while (!WorkList.
empty()) {
701 updateOneNode(Callee);
706template <
typename CalleeTy>
707void StackSafetyDataFlowAnalysis<CalleeTy>::verifyFixedPoint() {
714template <
typename CalleeTy>
715const typename StackSafetyDataFlowAnalysis<CalleeTy>::FunctionMap &
716StackSafetyDataFlowAnalysis<CalleeTy>::run() {
722FunctionSummary *findCalleeFunctionSummary(ValueInfo VI, StringRef ModuleId) {
725 auto SummaryList =
VI.getSummaryList();
726 GlobalValueSummary* S =
nullptr;
727 for (
const auto& GVS : SummaryList) {
731 if (!AS->hasAliasee())
736 if (GVS->modulePath() == ModuleId) {
742 ++NumIndexCalleeMultipleExternal;
748 ++NumIndexCalleeMultipleWeak;
754 if (SummaryList.size() == 1)
758 ++NumIndexCalleeUnhandled;
776const Function *findCalleeInModule(
const GlobalValue *GV) {
792const ConstantRange *findParamAccess(
const FunctionSummary &FS,
796 for (
const auto &PS :
FS.paramAccesses())
797 if (ParamNo == PS.ParamNo)
802void resolveAllCalls(UseInfo<GlobalValue> &Use,
803 const ModuleSummaryIndex *Index) {
804 ConstantRange FullSet(
Use.Range.getBitWidth(),
true);
807 UseInfo<GlobalValue>::CallsTy TmpCalls;
809 for (
const auto &
C : TmpCalls) {
810 const Function *
F = findCalleeInModule(
C.first.Callee);
812 Use.Calls.emplace(CallInfo<GlobalValue>(
F,
C.first.ParamNo),
C.second);
817 return Use.updateRange(FullSet);
818 FunctionSummary *
FS =
819 findCalleeFunctionSummary(
Index->getValueInfo(
C.first.Callee->getGUID()),
820 C.first.Callee->getParent()->getModuleIdentifier());
821 ++NumModuleCalleeLookupTotal;
823 ++NumModuleCalleeLookupFailed;
824 return Use.updateRange(FullSet);
826 const ConstantRange *Found = findParamAccess(*FS,
C.first.ParamNo);
828 return Use.updateRange(FullSet);
831 Use.updateRange(addOverflowNever(
Access,
C.second));
835GVToSSI createGlobalStackSafetyInfo(
836 std::map<
const GlobalValue *, FunctionInfo<GlobalValue>> Functions,
837 const ModuleSummaryIndex *Index) {
839 if (Functions.empty())
843 auto Copy = Functions;
845 for (
auto &FnKV : Copy)
846 for (
auto &KV : FnKV.second.Params) {
847 resolveAllCalls(KV.second, Index);
848 if (KV.second.Range.isFullSet())
849 KV.second.Calls.clear();
853 Copy.begin()->first->getDataLayout().getPointerSizeInBits();
854 StackSafetyDataFlowAnalysis<GlobalValue> SSDFA(PointerSize, std::move(Copy));
856 for (
const auto &
F : SSDFA.run()) {
858 auto &SrcF = Functions[
F.first];
859 for (
auto &KV : FI.Allocas) {
861 resolveAllCalls(
A, Index);
862 for (
auto &
C :
A.Calls) {
863 A.updateRange(SSDFA.getArgumentAccessRange(
C.first.Callee,
864 C.first.ParamNo,
C.second));
867 A.Calls = SrcF.Allocas.find(KV.first)->second.Calls;
869 for (
auto &KV : FI.Params) {
871 P.Calls = SrcF.Params.find(KV.first)->second.Calls;
873 SSI[
F.first] = std::move(FI);
885 : F(F), GetSE(GetSE) {}
895 StackSafetyLocalAnalysis SSLA(*F, GetSE());
896 Info.reset(
new InfoTy{SSLA.run()});
908 std::map<const GlobalValue *, FunctionInfo<GlobalValue>> Functions;
909 for (
auto &
F : M->functions()) {
910 if (!
F.isDeclaration()) {
911 auto FI = GetSSI(
F).getInfo().Info;
912 Functions.emplace(&
F, std::move(FI));
916 createGlobalStackSafetyInfo(std::move(Functions), Index), {}, {}});
918 for (
auto &FnKV : Info->Info) {
919 for (
auto &KV : FnKV.second.Allocas) {
921 const AllocaInst *AI = KV.first;
922 auto AIRange = getStaticAllocaSizeRange(*AI);
923 if (AIRange.contains(KV.second.Range)) {
924 Info->SafeAllocas.insert(AI);
925 ++NumAllocaStackSafe;
927 Info->UnsafeAccesses.insert(KV.second.UnsafeAccesses.begin(),
928 KV.second.UnsafeAccesses.end());
938std::vector<FunctionSummary::ParamAccess>
942 std::vector<FunctionSummary::ParamAccess> ParamAccesses;
943 for (
const auto &KV :
getInfo().Info.Params) {
944 auto &PS = KV.second;
948 if (PS.Range.isFullSet())
951 ParamAccesses.emplace_back(KV.first, PS.Range);
954 Param.Calls.reserve(PS.Calls.size());
955 for (
const auto &
C : PS.Calls) {
960 if (
C.second.isFullSet()) {
961 ParamAccesses.pop_back();
964 Param.Calls.emplace_back(
C.first.ParamNo,
965 Index.getOrInsertValueInfo(
C.first.Callee),
972 return std::tie(L.ParamNo, L.Callee) < std::tie(R.ParamNo, R.Callee);
975 return ParamAccesses;
983 : M(M), GetSSI(GetSSI), Index(Index) {
997 const auto &Info = getInfo();
998 return Info.SafeAllocas.count(&AI);
1002 const auto &Info = getInfo();
1003 return Info.UnsafeAccesses.find(&
I) == Info.UnsafeAccesses.end();
1007 auto &SSI = getInfo().Info;
1010 const Module &M = *SSI.begin()->first->getParent();
1011 for (
const auto &
F : M.functions()) {
1012 if (!
F.isDeclaration()) {
1013 SSI.find(&
F)->second.print(O,
F.getName(), &
F);
1014 O <<
" safe accesses:"
1020 (
Call &&
Call->hasByValArgument())) &&
1022 O <<
" " <<
I <<
"\n";
1043 OS <<
"'Stack Safety Local Analysis' for function '" <<
F.getName() <<
"'\n";
1083 OS <<
"'Stack Safety Analysis' for module '" << M.getName() <<
"'\n";
1108 if (
auto *IndexWrapperPass =
1110 ImportSummary = IndexWrapperPass->getIndex();
1123 for (
const auto &
F : M.functions())
1124 if (
F.hasFnAttribute(Attribute::SanitizeMemTag))
1130 if (!Index.hasParamAccess())
1134 auto CountParamAccesses = [&](
auto &Stat) {
1137 for (
auto &GVS : Index)
1138 for (
auto &GV : GVS.second.getSummaryList())
1140 Stat += FS->paramAccesses().size();
1143 CountParamAccesses(NumCombinedParamAccessesBefore);
1145 std::map<const FunctionSummary *, FunctionInfo<FunctionSummary>> Functions;
1148 for (
auto &GVS : Index) {
1149 for (
auto &GV : GVS.second.getSummaryList()) {
1151 if (!FS || FS->paramAccesses().empty())
1153 if (FS->isLive() && FS->isDSOLocal()) {
1154 FunctionInfo<FunctionSummary> FI;
1155 for (
const auto &PS : FS->paramAccesses()) {
1161 for (
const auto &
Call : PS.Calls) {
1164 findCalleeFunctionSummary(
Call.Callee, FS->modulePath());
1165 ++NumCombinedCalleeLookupTotal;
1167 ++NumCombinedCalleeLookupFailed;
1176 Functions.emplace(FS, std::move(FI));
1181 FS->setParamAccesses({});
1184 NumCombinedDataFlowNodes += Functions.size();
1185 StackSafetyDataFlowAnalysis<FunctionSummary> SSDFA(
1187 for (
const auto &KV : SSDFA.run()) {
1188 std::vector<FunctionSummary::ParamAccess> NewParams;
1189 NewParams.reserve(KV.second.Params.size());
1190 for (
const auto &Param : KV.second.Params) {
1192 if (Param.second.Range.isFullSet())
1194 NewParams.emplace_back();
1196 New.ParamNo = Param.first;
1197 New.Use = Param.second.Range;
1200 std::move(NewParams));
1203 CountParamAccesses(NumCombinedParamAccessesAfter);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This is the interface to build a ModuleSummaryIndex for a module.
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static const char LocalPassArg[]
static const char LocalPassName[]
static true const char GlobalPassName[]
static cl::opt< int > StackSafetyMaxIterations("stack-safety-max-iterations", cl::init(20), cl::Hidden)
static cl::opt< bool > StackSafetyRun("stack-safety-run", cl::init(false), cl::Hidden)
static cl::opt< bool > StackSafetyPrint("stack-safety-print", cl::init(false), cl::Hidden)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
an instruction to allocate memory on the stack
PointerType * getType() const
Overload to return most specific pointer type.
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
LLVM_ABI bool isArrayAllocation() const
Return true if there is an allocation size parameter to the allocation instruction that is not 1.
const Value * getArraySize() const
Get the number of elements allocated.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
AnalysisUsage & addRequiredTransitive()
This class represents a function call, abstracting a target machine's calling convention.
This class represents a range of values.
LLVM_ABI bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
LLVM_ABI bool contains(const APInt &Val) const
Return true if the specified value is in the set.
@ NeverOverflows
Never overflows.
LLVM_ABI ConstantRange sextOrTrunc(uint32_t BitWidth) const
Make this range have the bit width given by BitWidth.
A parsed version of the target data layout string in and methods for querying it.
Function summary information to aid decisions and implementation of importing.
GlobalValueSummary * getBaseObject()
If this is an alias summary, returns the summary of the aliased object (a global variable or function...
static bool isLocalLinkage(LinkageTypes Linkage)
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
static bool isLinkOnceLinkage(LinkageTypes Linkage)
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
LLVM_ABI const GlobalObject * getAliaseeObject() const
static bool isExternalLinkage(LinkageTypes Linkage)
LLVM_ABI bool isInterposable() const
Return true if this global's definition can be substituted with an arbitrary definition at link time ...
static bool isWeakLinkage(LinkageTypes Linkage)
Legacy wrapper pass to provide the ModuleSummaryIndex object.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
This is the common base class for memset/memcpy/memmove.
Class to hold module path string table and global value map, and encapsulate methods for operating on...
A Module instance is used to store all the information related to an LLVM module.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to get analysis information tha...
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This class represents an analyzed expression in the program.
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
LLVM_ABI const SCEV * getConstant(ConstantInt *V)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
ConstantRange getSignedRange(const SCEV *S)
Determine the signed range for a particular SCEV.
LLVM_ABI std::optional< bool > evaluatePredicateAt(CmpPredicate Pred, const SCEV *LHS, const SCEV *RHS, const Instruction *CtxI)
Check whether the condition described by Pred, LHS, and RHS is true or false in the given Context.
LLVM_ABI bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getTruncateOrZeroExtend(const SCEV *V, Type *Ty, unsigned Depth=0)
Return a SCEV corresponding to a conversion of the input value to the specified type.
LLVMContext & getContext() const
void insert_range(Range &&R)
void clear()
Completely clear the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
value_type pop_back_val()
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
iterator erase(const_iterator CI)
void push_back(const T &Elt)
Compute live ranges of allocas.
bool isReachable(const Instruction *I) const
Returns true if instruction is reachable from entry.
bool isAliveAfter(const AllocaInst *AI, const Instruction *I) const
Returns true if the alloca is alive after the instruction.
StackSafetyInfo wrapper for the new pass manager.
StackSafetyInfo run(Function &F, FunctionAnalysisManager &AM)
This pass performs the global (interprocedural) stack safety analysis (new pass manager).
Result run(Module &M, ModuleAnalysisManager &AM)
This pass performs the global (interprocedural) stack safety analysis (legacy pass manager).
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
StackSafetyGlobalInfoWrapperPass()
~StackSafetyGlobalInfoWrapperPass() override
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
void print(raw_ostream &O, const Module *M) const override
print - Print out the internal state of the pass.
void print(raw_ostream &O) const
bool stackAccessIsSafe(const Instruction &I) const
bool isSafe(const AllocaInst &AI) const
StackSafetyGlobalInfo & operator=(StackSafetyGlobalInfo &&)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
StackSafetyInfo wrapper for the legacy pass manager.
void print(raw_ostream &O, const Module *M) const override
print - Print out the internal state of the pass.
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
StackSafetyInfoWrapperPass()
Interface to access stack safety analysis results for single function.
void print(raw_ostream &O) const
const InfoTy & getInfo() const
StackSafetyInfo & operator=(StackSafetyInfo &&)
std::vector< FunctionSummary::ParamAccess > getParamAccesses(ModuleSummaryIndex &Index) const
Parameters use for a FunctionSummary.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
The instances of the Type class are immutable: once they are created, they are never changed.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
This class implements an extremely fast bulk output stream that can only output to a stream.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
constexpr uint64_t PointerSize
aarch64 pointer size.
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void generateParamAccessSummary(ModuleSummaryIndex &Index)
bool needsParamAccessSummary(const Module &M)
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
auto unique(Range &&R, Predicate P)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI bool AreStatisticsEnabled()
Check if statistics are enabled.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
std::set< const Instruction * > UnsafeAccesses
SmallPtrSet< const AllocaInst *, 8 > SafeAllocas
FunctionInfo< GlobalValue > Info
A special type used by analysis passes to provide an address that identifies that particular analysis...
Describes the use of a value in a call instruction, specifying the call's target, the value's paramet...
Describes the uses of a parameter by the function.
static constexpr uint32_t RangeWidth