38#define DEBUG_TYPE "stack-safety"
40STATISTIC(NumAllocaStackSafe,
"Number of safe allocas");
41STATISTIC(NumAllocaTotal,
"Number of total allocas");
44 "Number of total callee lookups on combined index.");
46 "Number of failed callee lookups on combined index.");
48 "Number of total callee lookups on module index.");
50 "Number of failed callee lookups on module index.");
52 "Number of total param accesses before generateParamAccessSummary.");
54 "Number of total param accesses after generateParamAccessSummary.");
56 "Number of total nodes in combined index for dataflow processing.");
57STATISTIC(NumIndexCalleeUnhandled,
"Number of index callee which are unhandled.");
58STATISTIC(NumIndexCalleeMultipleWeak,
"Number of index callee non-unique weak.");
59STATISTIC(NumIndexCalleeMultipleExternal,
"Number of index callee non-unique external.");
75 return R.isEmptySet() || R.isFullSet() || R.isUpperSignWrapped();
81 if (
L.signedAddMayOverflow(R) !=
83 return ConstantRange::getFull(
L.getBitWidth());
94 if (
Result.isSignWrappedSet())
100template <
typename CalleeTy>
struct CallInfo {
102 const CalleeTy *Callee =
nullptr;
106 CallInfo(
const CalleeTy *Callee,
size_t ParamNo)
107 : Callee(Callee), ParamNo(ParamNo) {}
110 bool operator()(
const CallInfo &L,
const CallInfo &R)
const {
111 return std::tie(
L.ParamNo,
L.Callee) < std::tie(
R.ParamNo,
R.Callee);
117template <
typename CalleeTy>
struct UseInfo {
121 std::set<const Instruction *> UnsafeAccesses;
128 using CallsTy = std::map<CallInfo<CalleeTy>, ConstantRange,
129 typename CallInfo<CalleeTy>::Less>;
134 void updateRange(
const ConstantRange &R) { Range = unionNoWrap(Range, R); }
135 void addRange(
const Instruction *
I,
const ConstantRange &R,
bool IsSafe) {
137 UnsafeAccesses.insert(
I);
142template <
typename CalleeTy>
145 for (
auto &
Call : U.Calls)
147 <<
"@" <<
Call.first.Callee->getName() <<
"(arg" <<
Call.first.ParamNo
148 <<
", " <<
Call.second <<
")";
163 if (APSize.isNonPositive())
169 bool Overflow =
false;
171 if (
Mul.isNonPositive())
173 Mul =
Mul.sextOrTrunc(PointerSize);
174 APSize = APSize.smul_ov(
Mul, Overflow);
183template <
typename CalleeTy>
struct FunctionInfo {
184 std::map<const AllocaInst *, UseInfo<CalleeTy>> Allocas;
185 std::map<uint32_t, UseInfo<CalleeTy>> Params;
191 void print(raw_ostream &O, StringRef Name,
const Function *
F)
const {
194 O <<
" @" <<
Name << ((
F &&
F->isDSOLocal()) ?
"" :
" dso_preemptable")
195 << ((
F &&
F->isInterposable()) ?
" interposable" :
"") <<
"\n";
197 O <<
" args uses:\n";
198 for (
auto &KV : Params) {
201 O <<
F->getArg(KV.first)->getName();
204 O <<
"[]: " << KV.second <<
"\n";
207 O <<
" allocas uses:\n";
211 auto &AS = Allocas.find(AI)->second;
213 << getStaticAllocaSizeRange(*AI).getUpper() <<
"]: " << AS <<
"\n";
222using GVToSSI = std::map<const GlobalValue *, FunctionInfo<GlobalValue>>;
227 FunctionInfo<GlobalValue>
Info;
238class StackSafetyLocalAnalysis {
242 unsigned PointerSize = 0;
252 const SCEV *getSCEVAsPointer(
Value *Val);
261 void analyzeAllUses(
Value *
Ptr, UseInfo<GlobalValue> &AS,
271 :
F(
F),
DL(
F.getDataLayout()), SE(SE),
272 PointerSize(
DL.getPointerSizeInBits()),
273 UnknownRange(PointerSize,
true) {}
276 FunctionInfo<GlobalValue> run();
279const SCEV *StackSafetyLocalAnalysis::getSCEVAsPointer(
Value *Val) {
283 if (!ValTy->isPointerTy()) {
288 if (ValTy->getPointerAddressSpace() != 0)
293ConstantRange StackSafetyLocalAnalysis::offsetFrom(
Value *Addr,
Value *
Base) {
297 const SCEV *AddrExp = getSCEVAsPointer(Addr);
298 const SCEV *BaseExp = getSCEVAsPointer(
Base);
299 if (!AddrExp || !BaseExp)
314 const ConstantRange &SizeRange) {
317 return ConstantRange::getEmpty(PointerSize);
318 assert(!isUnsafe(SizeRange));
321 if (isUnsafe(Offsets))
324 Offsets = addOverflowNever(Offsets, SizeRange);
325 if (isUnsafe(Offsets))
330ConstantRange StackSafetyLocalAnalysis::getAccessRange(
Value *Addr,
Value *
Base,
332 if (
Size.isScalable())
334 APInt APSize(PointerSize,
Size.getFixedValue(),
true);
335 if (APSize.isNegative())
337 return getAccessRange(Addr,
Base,
341ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
342 const MemIntrinsic *
MI,
const Use &U,
Value *
Base) {
344 if (MTI->getRawSource() != U && MTI->getRawDest() != U)
345 return ConstantRange::getEmpty(PointerSize);
347 if (
MI->getRawDest() != U)
348 return ConstantRange::getEmpty(PointerSize);
351 auto *CalculationTy = IntegerType::getIntNTy(SE.
getContext(), PointerSize);
358 if (!
Sizes.getUpper().isStrictlyPositive() || isUnsafe(Sizes))
362 return getAccessRange(U,
Base, SizeRange);
365bool StackSafetyLocalAnalysis::isSafeAccess(
const Use &U, AllocaInst *AI,
367 return isSafeAccess(U, AI, SE.
getSCEV(V));
370bool StackSafetyLocalAnalysis::isSafeAccess(
const Use &U, AllocaInst *AI,
374 auto *CalculationTy = IntegerType::getIntNTy(SE.
getContext(), PointerSize);
376 return isSafeAccess(U, AI, SV);
379bool StackSafetyLocalAnalysis::isSafeAccess(
const Use &U, AllocaInst *AI,
380 const SCEV *AccessSize) {
389 const SCEV *AddrExp = getSCEVAsPointer(
U.get());
390 const SCEV *BaseExp = getSCEVAsPointer(AI);
391 if (!AddrExp || !BaseExp)
398 auto Size = getStaticAllocaSizeRange(*AI);
400 auto *CalculationTy = IntegerType::getIntNTy(SE.
getContext(), PointerSize);
401 auto ToDiffTy = [&](
const SCEV *
V) {
406 ToDiffTy(AccessSize));
415void StackSafetyLocalAnalysis::analyzeAllUses(
Value *
Ptr,
416 UseInfo<GlobalValue> &US,
417 const StackLifetime &SL) {
418 SmallPtrSet<const Value *, 16> Visited;
419 SmallVector<const Value *, 8> WorkList;
424 while (!WorkList.
empty()) {
426 for (
const Use &UI :
V->uses()) {
433 auto RecordStore = [&](
const Value* StoredVal) {
434 if (V == StoredVal) {
436 US.addRange(
I, UnknownRange,
false);
440 US.addRange(
I, UnknownRange,
false);
443 auto TypeSize =
DL.getTypeStoreSize(StoredVal->getType());
444 auto AccessRange = getAccessRange(UI,
Ptr, TypeSize);
445 bool Safe = isSafeAccess(UI, AI, TypeSize);
446 US.addRange(
I, AccessRange, Safe);
450 switch (
I->getOpcode()) {
451 case Instruction::Load: {
453 US.addRange(
I, UnknownRange,
false);
456 auto TypeSize =
DL.getTypeStoreSize(
I->getType());
457 auto AccessRange = getAccessRange(UI,
Ptr, TypeSize);
458 bool Safe = isSafeAccess(UI, AI, TypeSize);
459 US.addRange(
I, AccessRange, Safe);
463 case Instruction::VAArg:
466 case Instruction::Store:
469 case Instruction::AtomicCmpXchg:
472 case Instruction::AtomicRMW:
476 case Instruction::Ret:
480 US.addRange(
I, UnknownRange,
false);
483 case Instruction::Call:
484 case Instruction::Invoke: {
485 if (
I->isLifetimeStartOrEnd())
489 US.addRange(
I, UnknownRange,
false);
493 auto AccessRange = getMemIntrinsicAccessRange(
MI, UI,
Ptr);
496 if (MTI->getRawSource() != UI && MTI->getRawDest() != UI)
498 }
else if (
MI->getRawDest() != UI) {
501 Safe = Safe || isSafeAccess(UI, AI,
MI->getLength());
502 US.addRange(
I, AccessRange, Safe);
507 if (CB.getReturnedArgOperand() == V) {
512 if (!CB.isArgOperand(&UI)) {
513 US.addRange(
I, UnknownRange,
false);
517 unsigned ArgNo = CB.getArgOperandNo(&UI);
518 if (CB.isByValArgument(ArgNo)) {
519 auto TypeSize =
DL.getTypeStoreSize(CB.getParamByValType(ArgNo));
520 auto AccessRange = getAccessRange(UI,
Ptr, TypeSize);
521 bool Safe = isSafeAccess(UI, AI, TypeSize);
522 US.addRange(
I, AccessRange, Safe);
529 const GlobalValue *
Callee =
532 US.addRange(
I, UnknownRange,
false);
539 US.Calls.emplace(CallInfo<GlobalValue>(Callee, ArgNo), Offsets);
541 Insert.first->second =
Insert.first->second.unionWith(Offsets);
553FunctionInfo<GlobalValue> StackSafetyLocalAnalysis::run() {
554 FunctionInfo<GlobalValue>
Info;
556 "Can't run StackSafety on a function declaration");
564 StackLifetime SL(
F, Allocas, StackLifetime::LivenessType::Must);
567 for (
auto *AI : Allocas) {
568 auto &UI =
Info.Allocas.emplace(AI, PointerSize).first->second;
569 analyzeAllUses(AI, UI, SL);
572 for (Argument &
A :
F.args()) {
575 if (
A.getType()->isPointerTy() && !
A.hasByValAttr()) {
576 auto &UI =
Info.Params.emplace(
A.getArgNo(), PointerSize).first->second;
577 analyzeAllUses(&
A, UI, SL);
586template <
typename CalleeTy>
class StackSafetyDataFlowAnalysis {
587 using FunctionMap = std::map<const CalleeTy *, FunctionInfo<CalleeTy>>;
589 FunctionMap Functions;
590 const ConstantRange UnknownRange;
593 DenseMap<const CalleeTy *, SmallVector<const CalleeTy *, 4>> Callers;
594 SetVector<const CalleeTy *> WorkList;
596 bool updateOneUse(UseInfo<CalleeTy> &US,
bool UpdateToFullSet);
597 void updateOneNode(
const CalleeTy *Callee, FunctionInfo<CalleeTy> &FS);
598 void updateOneNode(
const CalleeTy *Callee) {
599 updateOneNode(Callee, Functions.find(Callee)->second);
601 void updateAllNodes() {
602 for (
auto &
F : Functions)
603 updateOneNode(
F.first,
F.second);
607 void verifyFixedPoint();
611 StackSafetyDataFlowAnalysis(uint32_t PointerBitWidth, FunctionMap Functions)
612 : Functions(std::
move(Functions)),
613 UnknownRange(ConstantRange::getFull(PointerBitWidth)) {}
615 const FunctionMap &
run();
617 ConstantRange getArgumentAccessRange(
const CalleeTy *Callee,
unsigned ParamNo,
618 const ConstantRange &Offsets)
const;
621template <
typename CalleeTy>
622ConstantRange StackSafetyDataFlowAnalysis<CalleeTy>::getArgumentAccessRange(
623 const CalleeTy *Callee,
unsigned ParamNo,
624 const ConstantRange &Offsets)
const {
625 auto FnIt = Functions.find(Callee);
627 if (FnIt == Functions.end())
629 auto &
FS = FnIt->second;
630 auto ParamIt =
FS.Params.find(ParamNo);
631 if (ParamIt ==
FS.Params.end())
633 auto &
Access = ParamIt->second.Range;
638 return addOverflowNever(
Access, Offsets);
641template <
typename CalleeTy>
642bool StackSafetyDataFlowAnalysis<CalleeTy>::updateOneUse(UseInfo<CalleeTy> &US,
643 bool UpdateToFullSet) {
645 for (
auto &KV : US.Calls) {
646 assert(!KV.second.isEmptySet() &&
647 "Param range can't be empty-set, invalid offset range");
649 ConstantRange CalleeRange =
650 getArgumentAccessRange(KV.first.Callee, KV.first.ParamNo, KV.second);
651 if (!US.Range.
contains(CalleeRange)) {
654 US.Range = UnknownRange;
656 US.updateRange(CalleeRange);
662template <
typename CalleeTy>
663void StackSafetyDataFlowAnalysis<CalleeTy>::updateOneNode(
664 const CalleeTy *Callee, FunctionInfo<CalleeTy> &FS) {
667 for (
auto &KV :
FS.Params)
668 Changed |= updateOneUse(KV.second, UpdateToFullSet);
672 << (UpdateToFullSet ?
", full-set" :
"") <<
"] " << &FS
681template <
typename CalleeTy>
682void StackSafetyDataFlowAnalysis<CalleeTy>::runDataFlow() {
684 for (
auto &
F : Functions) {
687 for (
auto &KV :
FS.Params)
688 for (
auto &CS : KV.second.Calls)
694 for (
auto &Callee : Callees)
695 Callers[
Callee].push_back(
F.first);
700 while (!WorkList.
empty()) {
702 updateOneNode(Callee);
707template <
typename CalleeTy>
708void StackSafetyDataFlowAnalysis<CalleeTy>::verifyFixedPoint() {
715template <
typename CalleeTy>
716const typename StackSafetyDataFlowAnalysis<CalleeTy>::FunctionMap &
717StackSafetyDataFlowAnalysis<CalleeTy>::run() {
723FunctionSummary *findCalleeFunctionSummary(ValueInfo VI, StringRef ModuleId) {
726 auto SummaryList =
VI.getSummaryList();
727 GlobalValueSummary* S =
nullptr;
728 for (
const auto& GVS : SummaryList) {
732 if (!AS->hasAliasee())
737 if (GVS->modulePath() == ModuleId) {
743 ++NumIndexCalleeMultipleExternal;
749 ++NumIndexCalleeMultipleWeak;
755 if (SummaryList.size() == 1)
759 ++NumIndexCalleeUnhandled;
777const Function *findCalleeInModule(
const GlobalValue *GV) {
793const ConstantRange *findParamAccess(
const FunctionSummary &FS,
797 for (
const auto &PS :
FS.paramAccesses())
798 if (ParamNo == PS.ParamNo)
803void resolveAllCalls(UseInfo<GlobalValue> &Use,
804 const ModuleSummaryIndex *Index) {
805 ConstantRange FullSet(
Use.Range.getBitWidth(),
true);
808 UseInfo<GlobalValue>::CallsTy TmpCalls;
810 for (
const auto &
C : TmpCalls) {
811 const Function *
F = findCalleeInModule(
C.first.Callee);
813 Use.Calls.emplace(CallInfo<GlobalValue>(
F,
C.first.ParamNo),
C.second);
818 return Use.updateRange(FullSet);
819 FunctionSummary *
FS =
820 findCalleeFunctionSummary(
Index->getValueInfo(
C.first.Callee->getGUID()),
821 C.first.Callee->getParent()->getModuleIdentifier());
822 ++NumModuleCalleeLookupTotal;
824 ++NumModuleCalleeLookupFailed;
825 return Use.updateRange(FullSet);
827 const ConstantRange *Found = findParamAccess(*FS,
C.first.ParamNo);
829 return Use.updateRange(FullSet);
832 Use.updateRange(addOverflowNever(
Access,
C.second));
836GVToSSI createGlobalStackSafetyInfo(
837 std::map<
const GlobalValue *, FunctionInfo<GlobalValue>> Functions,
838 const ModuleSummaryIndex *Index) {
840 if (Functions.empty())
844 auto Copy = Functions;
846 for (
auto &FnKV : Copy)
847 for (
auto &KV : FnKV.second.Params) {
848 resolveAllCalls(KV.second, Index);
849 if (KV.second.Range.isFullSet())
850 KV.second.Calls.clear();
854 Copy.begin()->first->getDataLayout().getPointerSizeInBits();
855 StackSafetyDataFlowAnalysis<GlobalValue> SSDFA(PointerSize, std::move(Copy));
857 for (
const auto &
F : SSDFA.run()) {
859 auto &SrcF = Functions[
F.first];
860 for (
auto &KV : FI.Allocas) {
862 resolveAllCalls(
A, Index);
863 for (
auto &
C :
A.Calls) {
864 A.updateRange(SSDFA.getArgumentAccessRange(
C.first.Callee,
865 C.first.ParamNo,
C.second));
868 A.Calls = SrcF.Allocas.find(KV.first)->second.Calls;
870 for (
auto &KV : FI.Params) {
872 P.Calls = SrcF.Params.find(KV.first)->second.Calls;
874 SSI[
F.first] = std::move(FI);
886 : F(F), GetSE(GetSE) {}
896 StackSafetyLocalAnalysis SSLA(*F, GetSE());
897 Info.reset(
new InfoTy{SSLA.run()});
909 std::map<const GlobalValue *, FunctionInfo<GlobalValue>> Functions;
910 for (
auto &
F : M->functions()) {
911 if (!
F.isDeclaration()) {
912 auto FI = GetSSI(
F).getInfo().Info;
913 Functions.emplace(&
F, std::move(FI));
917 createGlobalStackSafetyInfo(std::move(Functions), Index), {}, {}});
919 for (
auto &FnKV : Info->Info) {
920 for (
auto &KV : FnKV.second.Allocas) {
922 const AllocaInst *AI = KV.first;
923 auto AIRange = getStaticAllocaSizeRange(*AI);
924 if (AIRange.contains(KV.second.Range)) {
925 Info->SafeAllocas.insert(AI);
926 ++NumAllocaStackSafe;
928 Info->UnsafeAccesses.insert(KV.second.UnsafeAccesses.begin(),
929 KV.second.UnsafeAccesses.end());
939std::vector<FunctionSummary::ParamAccess>
943 std::vector<FunctionSummary::ParamAccess> ParamAccesses;
944 for (
const auto &KV :
getInfo().Info.Params) {
945 auto &PS = KV.second;
949 if (PS.Range.isFullSet())
952 ParamAccesses.emplace_back(KV.first, PS.Range);
955 Param.Calls.reserve(PS.Calls.size());
956 for (
const auto &
C : PS.Calls) {
961 if (
C.second.isFullSet()) {
962 ParamAccesses.pop_back();
965 Param.Calls.emplace_back(
C.first.ParamNo,
966 Index.getOrInsertValueInfo(
C.first.Callee),
973 return std::tie(L.ParamNo, L.Callee) < std::tie(R.ParamNo, R.Callee);
976 return ParamAccesses;
984 : M(M), GetSSI(GetSSI), Index(Index) {
998 const auto &Info = getInfo();
999 return Info.SafeAllocas.count(&AI);
1003 const auto &Info = getInfo();
1004 return Info.UnsafeAccesses.find(&
I) == Info.UnsafeAccesses.end();
1008 auto &SSI = getInfo().Info;
1011 const Module &M = *SSI.begin()->first->getParent();
1012 for (
const auto &
F : M.functions()) {
1013 if (!
F.isDeclaration()) {
1014 SSI.find(&
F)->second.print(O,
F.getName(), &
F);
1015 O <<
" safe accesses:"
1021 (
Call &&
Call->hasByValArgument())) &&
1023 O <<
" " <<
I <<
"\n";
1044 OS <<
"'Stack Safety Local Analysis' for function '" <<
F.getName() <<
"'\n";
1084 OS <<
"'Stack Safety Analysis' for module '" << M.getName() <<
"'\n";
1109 if (
auto *IndexWrapperPass =
1111 ImportSummary = IndexWrapperPass->getIndex();
1124 for (
const auto &
F : M.functions())
1125 if (
F.hasFnAttribute(Attribute::SanitizeMemTag))
1131 if (!Index.hasParamAccess())
1135 auto CountParamAccesses = [&](
auto &Stat) {
1138 for (
auto &GVS : Index)
1139 for (
auto &GV : GVS.second.SummaryList)
1141 Stat += FS->paramAccesses().size();
1144 CountParamAccesses(NumCombinedParamAccessesBefore);
1146 std::map<const FunctionSummary *, FunctionInfo<FunctionSummary>> Functions;
1149 for (
auto &GVS : Index) {
1150 for (
auto &GV : GVS.second.SummaryList) {
1152 if (!FS || FS->paramAccesses().empty())
1154 if (FS->isLive() && FS->isDSOLocal()) {
1155 FunctionInfo<FunctionSummary> FI;
1156 for (
const auto &PS : FS->paramAccesses()) {
1162 for (
const auto &
Call : PS.Calls) {
1165 findCalleeFunctionSummary(
Call.Callee, FS->modulePath());
1166 ++NumCombinedCalleeLookupTotal;
1168 ++NumCombinedCalleeLookupFailed;
1177 Functions.emplace(FS, std::move(FI));
1182 FS->setParamAccesses({});
1185 NumCombinedDataFlowNodes += Functions.size();
1186 StackSafetyDataFlowAnalysis<FunctionSummary> SSDFA(
1188 for (
const auto &KV : SSDFA.run()) {
1189 std::vector<FunctionSummary::ParamAccess> NewParams;
1190 NewParams.reserve(KV.second.Params.size());
1191 for (
const auto &Param : KV.second.Params) {
1193 if (Param.second.Range.isFullSet())
1195 NewParams.emplace_back();
1197 New.ParamNo = Param.first;
1198 New.Use = Param.second.Range;
1201 std::move(NewParams));
1204 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()
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.
~StackSafetyGlobalInfoWrapperPass()
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