36 #define DEBUG_TYPE "stack-safety" 38 STATISTIC(NumAllocaStackSafe,
"Number of safe allocas");
39 STATISTIC(NumAllocaTotal,
"Number of total allocas");
42 "Number of total callee lookups on combined index.");
44 "Number of failed callee lookups on combined index.");
46 "Number of total callee lookups on module index.");
48 "Number of failed callee lookups on module index.");
50 "Number of total param accesses before generateParamAccessSummary.");
52 "Number of total param accesses after generateParamAccessSummary.");
54 "Number of total nodes in combined index for dataflow processing.");
55 STATISTIC(NumIndexCalleeUnhandled,
"Number of index callee which are unhandled.");
56 STATISTIC(NumIndexCalleeMultipleWeak,
"Number of index callee non-unique weak.");
57 STATISTIC(NumIndexCalleeMultipleExternal,
"Number of index callee non-unique external.");
73 return R.isEmptySet() || R.isFullSet() || R.isUpperSignWrapped();
92 if (
Result.isSignWrappedSet())
93 Result = ConstantRange::getFull(
Result.getBitWidth());
98 template <
typename CalleeTy>
struct CallInfo {
100 const CalleeTy *
Callee =
nullptr;
104 CallInfo(
const CalleeTy *Callee,
size_t ParamNo)
109 return std::tie(L.ParamNo, L.Callee) < std::tie(
R.ParamNo,
R.Callee);
115 template <
typename CalleeTy>
struct UseInfo {
129 UseInfo(
unsigned PointerSize) : Range{PointerSize,
false} {}
131 void updateRange(
const ConstantRange &R) { Range = unionNoWrap(Range, R); }
134 template <
typename CalleeTy>
137 for (
auto &Call : U.Calls)
139 <<
"@" <<
Call.first.Callee->getName() <<
"(arg" <<
Call.first.ParamNo
140 <<
", " <<
Call.second <<
")";
149 unsigned PointerSize =
DL.getMaxPointerSizeInBits();
155 if (APSize.isNonPositive())
161 bool Overflow =
false;
163 if (
Mul.isNonPositive())
165 Mul =
Mul.sextOrTrunc(PointerSize);
166 APSize = APSize.smul_ov(Mul, Overflow);
175 template <
typename CalleeTy>
struct FunctionInfo {
176 std::map<const AllocaInst *, UseInfo<CalleeTy>> Allocas;
177 std::map<uint32_t, UseInfo<CalleeTy>> Params;
186 O <<
" @" <<
Name << ((
F &&
F->isDSOLocal()) ?
"" :
" dso_preemptable")
187 << ((
F &&
F->isInterposable()) ?
" interposable" :
"") <<
"\n";
189 O <<
" args uses:\n";
190 for (
auto &KV : Params) {
193 O <<
F->getArg(KV.first)->getName();
196 O <<
"[]: " << KV.second <<
"\n";
199 O <<
" allocas uses:\n";
202 if (
const AllocaInst *AI = dyn_cast<AllocaInst>(&
I)) {
203 auto &AS = Allocas.find(AI)->second;
205 << getStaticAllocaSizeRange(*AI).getUpper() <<
"]: " << AS <<
"\n";
215 using GVToSSI = std::map<const GlobalValue *, FunctionInfo<GlobalValue>>;
220 FunctionInfo<GlobalValue>
Info;
230 class StackSafetyLocalAnalysis {
234 unsigned PointerSize = 0;
245 bool analyzeAllUses(
Value *Ptr, UseInfo<GlobalValue> &AS,
250 :
F(
F),
DL(
F.getParent()->getDataLayout()), SE(SE),
251 PointerSize(
DL.getPointerSizeInBits()),
252 UnknownRange(PointerSize,
true) {}
255 FunctionInfo<GlobalValue> run();
259 if (!SE.isSCEVable(
Addr->getType()) || !SE.isSCEVable(
Base->getType()))
263 const SCEV *AddrExp = SE.getTruncateOrZeroExtend(SE.getSCEV(
Addr), PtrTy);
264 const SCEV *BaseExp = SE.getTruncateOrZeroExtend(SE.getSCEV(
Base), PtrTy);
265 const SCEV *Diff = SE.getMinusSCEV(AddrExp, BaseExp);
270 return Offset.sextOrTrunc(PointerSize);
278 return ConstantRange::getEmpty(PointerSize);
279 assert(!isUnsafe(SizeRange));
293 if (
Size.isScalable())
295 APInt APSize(PointerSize,
Size.getFixedSize(),
true);
296 if (APSize.isNegative())
298 return getAccessRange(
302 ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
304 if (
const auto *MTI = dyn_cast<MemTransferInst>(
MI)) {
305 if (MTI->getRawSource() != U && MTI->getRawDest() != U)
306 return ConstantRange::getEmpty(PointerSize);
308 if (
MI->getRawDest() != U)
309 return ConstantRange::getEmpty(PointerSize);
313 if (!SE.isSCEVable(
MI->getLength()->getType()))
317 SE.getTruncateOrZeroExtend(SE.getSCEV(
MI->getLength()), CalculationTy);
324 return getAccessRange(U,
Base, SizeRange);
329 bool StackSafetyLocalAnalysis::analyzeAllUses(
Value *Ptr,
330 UseInfo<GlobalValue> &US,
335 const AllocaInst *AI = dyn_cast<AllocaInst>(Ptr);
338 while (!WorkList.
empty()) {
340 for (
const Use &UI : V->
uses()) {
341 const auto *
I = cast<Instruction>(UI.getUser());
347 switch (
I->getOpcode()) {
350 US.updateRange(UnknownRange);
354 getAccessRange(UI, Ptr,
DL.getTypeStoreSize(
I->getType())));
358 case Instruction::VAArg:
362 if (V ==
I->getOperand(0)) {
364 US.updateRange(UnknownRange);
368 US.updateRange(UnknownRange);
371 US.updateRange(getAccessRange(
372 UI, Ptr,
DL.getTypeStoreSize(
I->getOperand(0)->getType())));
380 US.updateRange(UnknownRange);
384 case Instruction::Invoke: {
385 if (
I->isLifetimeStartOrEnd())
389 US.updateRange(UnknownRange);
394 US.updateRange(getMemIntrinsicAccessRange(
MI, UI, Ptr));
398 const auto &CB = cast<CallBase>(*
I);
399 if (!CB.isArgOperand(&UI)) {
400 US.updateRange(UnknownRange);
404 unsigned ArgNo = CB.getArgOperandNo(&UI);
405 if (CB.isByValArgument(ArgNo)) {
406 US.updateRange(getAccessRange(
407 UI, Ptr,
DL.getTypeStoreSize(CB.getParamByValType(ArgNo))));
415 dyn_cast<GlobalValue>(CB.getCalledOperand()->stripPointerCasts());
417 US.updateRange(UnknownRange);
421 assert(isa<Function>(Callee) || isa<GlobalAlias>(Callee));
432 WorkList.
push_back(cast<const Instruction>(
I));
440 FunctionInfo<GlobalValue> StackSafetyLocalAnalysis::run() {
441 FunctionInfo<GlobalValue>
Info;
443 "Can't run StackSafety on a function declaration");
449 if (
auto *AI = dyn_cast<AllocaInst>(&
I))
454 for (
auto *AI : Allocas) {
455 auto &UI =
Info.Allocas.emplace(AI, PointerSize).first->second;
456 analyzeAllUses(AI, UI, SL);
462 if (
A.getType()->isPointerTy() && !
A.hasByValAttr()) {
463 auto &UI =
Info.Params.emplace(
A.getArgNo(), PointerSize).first->second;
464 analyzeAllUses(&A, UI, SL);
473 template <
typename CalleeTy>
class StackSafetyDataFlowAnalysis {
474 using FunctionMap = std::map<const CalleeTy *, FunctionInfo<CalleeTy>>;
476 FunctionMap Functions;
483 bool updateOneUse(UseInfo<CalleeTy> &US,
bool UpdateToFullSet);
484 void updateOneNode(
const CalleeTy *Callee, FunctionInfo<CalleeTy> &
FS);
485 void updateOneNode(
const CalleeTy *Callee) {
486 updateOneNode(Callee, Functions.find(Callee)->second);
488 void updateAllNodes() {
489 for (
auto &
F : Functions)
490 updateOneNode(
F.first,
F.second);
494 void verifyFixedPoint();
498 StackSafetyDataFlowAnalysis(
uint32_t PointerBitWidth, FunctionMap Functions)
499 : Functions(
std::
move(Functions)),
502 const FunctionMap &run();
504 ConstantRange getArgumentAccessRange(
const CalleeTy *Callee,
unsigned ParamNo,
508 template <
typename CalleeTy>
509 ConstantRange StackSafetyDataFlowAnalysis<CalleeTy>::getArgumentAccessRange(
510 const CalleeTy *Callee,
unsigned ParamNo,
512 auto FnIt = Functions.find(Callee);
514 if (FnIt == Functions.end())
516 auto &
FS = FnIt->second;
517 auto ParamIt =
FS.Params.find(ParamNo);
518 if (ParamIt ==
FS.Params.end())
520 auto &Access = ParamIt->second.Range;
521 if (Access.isEmptySet())
523 if (Access.isFullSet())
525 return addOverflowNever(Access,
Offsets);
528 template <
typename CalleeTy>
529 bool StackSafetyDataFlowAnalysis<CalleeTy>::updateOneUse(UseInfo<CalleeTy> &US,
530 bool UpdateToFullSet) {
531 bool Changed =
false;
532 for (
auto &KV : US.Calls) {
533 assert(!KV.second.isEmptySet() &&
534 "Param range can't be empty-set, invalid offset range");
537 getArgumentAccessRange(KV.first.Callee, KV.first.ParamNo, KV.second);
538 if (!US.Range.contains(CalleeRange)) {
541 US.Range = UnknownRange;
543 US.updateRange(CalleeRange);
549 template <
typename CalleeTy>
550 void StackSafetyDataFlowAnalysis<CalleeTy>::updateOneNode(
551 const CalleeTy *Callee, FunctionInfo<CalleeTy> &
FS) {
553 bool Changed =
false;
554 for (
auto &KV :
FS.Params)
555 Changed |= updateOneUse(KV.second, UpdateToFullSet);
559 << (UpdateToFullSet ?
", full-set" :
"") <<
"] " << &
FS 562 for (
auto &CallerID : Callers[Callee])
563 WorkList.
insert(CallerID);
569 template <
typename CalleeTy>
570 void StackSafetyDataFlowAnalysis<CalleeTy>::runDataFlow() {
572 for (
auto &
F : Functions) {
575 for (
auto &KV :
FS.Params)
576 for (
auto &CS : KV.second.Calls)
582 for (
auto &Callee : Callees)
583 Callers[
Callee].push_back(
F.first);
588 while (!WorkList.
empty()) {
591 updateOneNode(Callee);
596 template <
typename CalleeTy>
597 void StackSafetyDataFlowAnalysis<CalleeTy>::verifyFixedPoint() {
604 template <
typename CalleeTy>
605 const typename StackSafetyDataFlowAnalysis<CalleeTy>::FunctionMap &
606 StackSafetyDataFlowAnalysis<CalleeTy>::run() {
615 auto SummaryList =
VI.getSummaryList();
617 for (
const auto& GVS : SummaryList) {
620 if (
const AliasSummary *AS = dyn_cast<AliasSummary>(GVS.get()))
621 if (!AS->hasAliasee())
623 if (!isa<FunctionSummary>(GVS->getBaseObject()))
626 if (GVS->modulePath() == ModuleId) {
632 ++NumIndexCalleeMultipleExternal;
638 ++NumIndexCalleeMultipleWeak;
644 if (SummaryList.size() == 1)
648 ++NumIndexCalleeUnhandled;
670 if (
const Function *
F = dyn_cast<Function>(GV))
675 GV =
A->getBaseObject();
686 for (
auto &PS :
FS.paramAccesses())
687 if (ParamNo == PS.ParamNo)
692 void resolveAllCalls(UseInfo<GlobalValue> &
Use,
697 UseInfo<GlobalValue>::CallsTy TmpCalls;
699 for (
const auto &
C : TmpCalls) {
700 const Function *
F = findCalleeInModule(
C.first.Callee);
707 return Use.updateRange(FullSet);
709 findCalleeFunctionSummary(
Index->getValueInfo(
C.first.Callee->getGUID()),
710 C.first.Callee->
getParent()->getModuleIdentifier());
711 ++NumModuleCalleeLookupTotal;
713 ++NumModuleCalleeLookupFailed;
714 return Use.updateRange(FullSet);
718 return Use.updateRange(FullSet);
721 Use.updateRange(addOverflowNever(Access,
C.second));
725 GVToSSI createGlobalStackSafetyInfo(
726 std::map<
const GlobalValue *, FunctionInfo<GlobalValue>> Functions,
729 if (Functions.empty())
733 auto Copy = Functions;
735 for (
auto &FnKV : Copy)
736 for (
auto &KV : FnKV.second.Params) {
737 resolveAllCalls(KV.second,
Index);
738 if (KV.second.Range.isFullSet())
739 KV.second.Calls.clear();
745 .getMaxPointerSizeInBits();
746 StackSafetyDataFlowAnalysis<GlobalValue> SSDFA(PointerSize,
std::move(Copy));
748 for (
auto &
F : SSDFA.run()) {
750 auto &SrcF = Functions[
F.first];
751 for (
auto &KV : FI.Allocas) {
753 resolveAllCalls(A,
Index);
754 for (
auto &
C :
A.Calls) {
755 A.updateRange(SSDFA.getArgumentAccessRange(
C.first.Callee,
756 C.first.ParamNo,
C.second));
759 A.Calls = SrcF.Allocas.find(KV.first)->second.Calls;
761 for (
auto &KV : FI.Params) {
763 P.Calls = SrcF.Params.find(KV.first)->second.Calls;
777 :
F(
F), GetSE(GetSE) {}
787 StackSafetyLocalAnalysis SSLA(*
F, GetSE());
799 std::map<const GlobalValue *, FunctionInfo<GlobalValue>> Functions;
801 if (!
F.isDeclaration()) {
802 auto FI = GetSSI(
F).getInfo().Info;
806 Info.reset(
new InfoTy{
807 createGlobalStackSafetyInfo(
std::move(Functions), Index), {}});
808 for (
auto &FnKV :
Info->Info) {
809 for (
auto &KV : FnKV.second.Allocas) {
812 if (getStaticAllocaSizeRange(*AI).contains(KV.second.Range)) {
813 Info->SafeAllocas.insert(AI);
814 ++NumAllocaStackSafe;
824 std::vector<FunctionSummary::ParamAccess>
828 std::vector<FunctionSummary::ParamAccess> ParamAccesses;
830 auto &PS = KV.second;
834 if (PS.Range.isFullSet())
837 ParamAccesses.emplace_back(KV.first, PS.Range);
840 Param.Calls.reserve(PS.Calls.size());
841 for (
auto &
C : PS.Calls) {
846 if (
C.second.isFullSet()) {
847 ParamAccesses.pop_back();
850 Param.Calls.emplace_back(
C.first.ParamNo,
851 Index.getOrInsertValueInfo(
C.first.Callee),
858 return std::tie(L.ParamNo, L.Callee) < std::tie(R.ParamNo, R.Callee);
861 return ParamAccesses;
883 const auto &
Info = getInfo();
884 return Info.SafeAllocas.count(&AI);
888 auto &SSI = getInfo().
Info;
891 const Module &M = *SSI.begin()->first->getParent();
892 for (
auto &
F : M.functions()) {
893 if (!
F.isDeclaration()) {
894 SSI.find(&
F)->second.print(
O,
F.getName(), &
F);
913 OS <<
"'Stack Safety Local Analysis' for function '" <<
F.getName() <<
"'\n";
934 auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
955 OS <<
"'Stack Safety Analysis' for module '" << M.getName() <<
"'\n";
983 if (
auto *IndexWrapperPass =
984 getAnalysisIfAvailable<ImmutableModuleSummaryIndexWrapperPass>())
985 ImportSummary = IndexWrapperPass->getIndex();
989 return getAnalysis<StackSafetyInfoWrapperPass>(
F).getResult();
998 for (
auto &
F : M.functions())
999 if (
F.hasFnAttribute(Attribute::SanitizeMemTag))
1005 if (!
Index.hasParamAccess())
1009 auto CountParamAccesses = [&](
auto &Stat) {
1012 for (
auto &GVS :
Index)
1013 for (
auto &GV : GVS.second.SummaryList)
1015 Stat +=
FS->paramAccesses().size();
1018 CountParamAccesses(NumCombinedParamAccessesBefore);
1020 std::map<const FunctionSummary *, FunctionInfo<FunctionSummary>> Functions;
1023 for (
auto &GVS :
Index) {
1024 for (
auto &GV : GVS.second.SummaryList) {
1026 if (!
FS ||
FS->paramAccesses().empty())
1028 if (
FS->isLive() &&
FS->isDSOLocal()) {
1029 FunctionInfo<FunctionSummary> FI;
1030 for (
auto &PS :
FS->paramAccesses()) {
1036 for (
auto &Call : PS.Calls) {
1037 assert(!Call.Offsets.isFullSet());
1039 findCalleeFunctionSummary(Call.Callee,
FS->modulePath());
1040 ++NumCombinedCalleeLookupTotal;
1042 ++NumCombinedCalleeLookupFailed;
1056 FS->setParamAccesses({});
1059 NumCombinedDataFlowNodes += Functions.size();
1060 StackSafetyDataFlowAnalysis<FunctionSummary> SSDFA(
1062 for (
auto &KV : SSDFA.run()) {
1063 std::vector<FunctionSummary::ParamAccess> NewParams;
1064 NewParams.reserve(KV.second.Params.size());
1065 for (
auto &Param : KV.second.Params) {
1067 if (Param.second.Range.isFullSet())
1069 NewParams.emplace_back();
1071 New.ParamNo = Param.first;
1072 New.Use = Param.second.Range;
1074 const_cast<FunctionSummary *>(KV.first)->setParamAccesses(
1078 CountParamAccesses(NumCombinedParamAccessesAfter);
static cl::opt< bool > StackSafetyPrint("stack-safety-print", cl::init(false), cl::Hidden)
A parsed version of the target data layout string in and methods for querying it.
Result run(Module &M, ModuleAnalysisManager &AM)
bool isInterposable() const
Return true if this global's definition can be substituted with an arbitrary definition at link time ...
Legacy wrapper pass to provide the ModuleSummaryIndex object.
iterator_range< use_iterator > uses()
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents an incoming formal argument to a Function.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
const APInt & getUpper() const
Return the upper value for this range.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
A Module instance is used to store all the information related to an LLVM module.
LLVM_NODISCARD bool empty() const
static bool isExternalLinkage(LinkageTypes Linkage)
This is the interface to build a ModuleSummaryIndex for a module.
void print(raw_ostream &O, const Module *M) const override
print - Print out the internal state of the pass.
void push_back(const T &Elt)
The main scalar evolution driver.
ScalarTy getFixedSize() const
StackSafetyGlobalInfoWrapperPass()
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
STATISTIC(NumFunctions, "Total number of functions")
OverflowResult signedAddMayOverflow(const ConstantRange &Other) const
Return whether signed add of the two ranges always/never overflows.
const T & back() const
Return the last element of the SetVector.
std::vector< FunctionSummary::ParamAccess > getParamAccesses(ModuleSummaryIndex &Index) const
Parameters use for a FunctionSummary.
static cl::opt< bool > StackSafetyRun("stack-safety-run", cl::init(false), cl::Hidden)
static bool isLocalLinkage(LinkageTypes Linkage)
static bool isLinkOnceLinkage(LinkageTypes Linkage)
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
StackSafetyInfo & operator=(StackSafetyInfo &&)
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
AnalysisUsage & addRequired()
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
static constexpr uint32_t RangeWidth
A Use represents the edge between a Value definition and its users.
void print(raw_ostream &O, const Module *M) const override
print - Print out the internal state of the pass.
static const char LocalPassArg[]
void pop_back()
Remove the last element of the SetVector.
This file implements a class to represent arbitrary precision integral constant values and operations...
bool insert(const value_type &X)
Insert a new element into the SetVector.
INITIALIZE_PASS_BEGIN(StackSafetyInfoWrapperPass, LocalPassArg, LocalPassName, false, true) INITIALIZE_PASS_END(StackSafetyInfoWrapperPass
This pass performs the global (interprocedural) stack safety analysis (legacy pass manager).
Class to hold module path string table and global value map, and encapsulate methods for operating on...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Analysis containing CSE Info
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.
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
bool isNegative() const
Determine sign of this APInt.
initializer< Ty > init(const Ty &Val)
void print(raw_ostream &O) const
A set of analyses that are preserved following a run of a transformation pass.
iterator_range< iterator > functions()
StackSafetyGlobalInfo & operator=(StackSafetyGlobalInfo &&)
StackSafetyInfo run(Function &F, FunctionAnalysisManager &AM)
void generateParamAccessSummary(ModuleSummaryIndex &Index)
~StackSafetyGlobalInfoWrapperPass()
bool isSignWrappedSet() const
Return true if this set wraps around the signed domain.
Interface to access stack safety analysis results for single function.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
ConstantRange add(const ConstantRange &Other) const
Return a new range representing the possible values resulting from an addition of a value in this ran...
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type.
void sort(IteratorTy Start, IteratorTy End)
Function and variable summary information to aid decisions and implementation of importing.
iterator erase(const_iterator CI)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This pass performs the global (interprocedural) stack safety analysis (new pass manager).
const Value * getArraySize() const
Get the number of elements allocated.
StackSafetyInfo wrapper for the legacy pass manager.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Describes the use of a value in a call instruction, specifying the call's target, the value's paramet...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
FunctionInfo< GlobalValue > Info
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static cl::opt< int > StackSafetyMaxIterations("stack-safety-max-iterations", cl::init(20), cl::Hidden)
Struct that holds a reference to a particular GUID in a global value summary.
bool isEmptySet() const
Return true if this set contains no members.
This is the common base class for memset/memcpy/memmove.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
static const char LocalPassName[]
GlobalValueSummary * getBaseObject()
If this is an alias summary, returns the summary of the aliased object (a global variable or function...
void print(raw_ostream &O) const
bool isSafe(const AllocaInst &AI) const
static bool isWeakLinkage(LinkageTypes Linkage)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class represents a range of values.
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
LLVM_NODISCARD T pop_back_val()
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Alias summary information.
static true const char GlobalPassName[]
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
void clear()
Completely clear the SetVector.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Class for arbitrary precision integers.
amdgpu Simplify well known AMD library false FunctionCallee Callee
void setPreservesAll()
Set by analyses that do not transform their input at all.
Analysis pass that exposes the ScalarEvolution for a function.
This class represents an analyzed expression in the program.
StringRef getName() const
Return a constant reference to the value's name.
StackSafetyInfoWrapperPass()
bool empty() const
Determine if the SetVector is empty or not.
Describes the uses of a parameter by the function.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
void initializeStackSafetyGlobalInfoWrapperPassPass(PassRegistry &)
AnalysisUsage & addRequiredTransitive()
bool needsParamAccessSummary(const Module &M)
Function summary information to aid decisions and implementation of importing.
const InfoTy & getInfo() const
bool isReachable(const Instruction *I) const
Returns true if instruction is reachable from entry.
ConstantRange unionWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the union of this range with another range.
bool isScalable() const
Returns whether the size is scaled by a runtime quantity (vscale).
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
ConstantRange sextOrTrunc(uint32_t BitWidth) const
Make this range have the bit width given by BitWidth.
bool isArrayAllocation() const
Return true if there is an allocation size parameter to the allocation instruction that is not 1.
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void initializeStackSafetyInfoWrapperPassPass(PassRegistry &)
LLVM Value Representation.
A vector that has set insertion semantics.
Compute live ranges of allocas.
This class implements an extremely fast bulk output stream that can only output to a stream.
print Print MemDeps of function
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
StringRef - Represent a constant reference to a string, i.e.
inst_range instructions(Function *F)
A container for analyses that lazily runs them and caches their results.
static APInt getNullValue(unsigned numBits)
Get the '0' value.
bool AreStatisticsEnabled()
Check if statistics are enabled.
A special type used by analysis passes to provide an address that identifies that particular analysis...
SmallPtrSet< const AllocaInst *, 8 > SafeAllocas
const BasicBlock * getParent() const
an instruction to allocate memory on the stack
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...