31 #define DEBUG_TYPE "memcpyopt"
33 STATISTIC(NumMemCpyInstr,
"Number of memcpy instructions deleted");
34 STATISTIC(NumMemSetInfer,
"Number of memsets inferred");
35 STATISTIC(NumMoveToCpy,
"Number of memmoves converted to memcpy");
36 STATISTIC(NumCpyToSet,
"Number of memcpys converted to memset");
39 bool &VariableIdxFound,
43 for (
unsigned i = 1;
i != Idx; ++
i, ++GTI)
51 return VariableIdxFound =
true;
52 if (OpC->
isZero())
continue;
86 bool VariableIdxFound =
false;
92 return !VariableIdxFound;
97 return !VariableIdxFound;
105 if (!GEP1 || !GEP2 || GEP1->
getOperand(0) != GEP2->getOperand(0))
110 for (; Idx != GEP1->
getNumOperands() && Idx != GEP2->getNumOperands(); ++Idx)
111 if (GEP1->
getOperand(Idx) != GEP2->getOperand(Idx))
116 if (VariableIdxFound)
return false;
118 Offset = Offset2-Offset1;
149 bool isProfitableToUseMemset(
const DataLayout &DL)
const;
153 bool MemsetRange::isProfitableToUseMemset(
const DataLayout &DL)
const {
155 if (TheStores.size() >= 4 ||
End-Start >= 16)
return true;
158 if (TheStores.size() < 2)
return false;
163 if (!isa<StoreInst>(SI))
168 if (TheStores.size() == 2)
return false;
184 unsigned NumPointerStores = Bytes / MaxIntSize;
187 unsigned NumByteStores = Bytes % MaxIntSize;
192 return TheStores.size() > NumPointerStores+NumByteStores;
203 MemsetRanges(
const DataLayout &DL) : DL(DL) {}
206 const_iterator
begin()
const {
return Ranges.
begin(); }
207 const_iterator
end()
const {
return Ranges.
end(); }
208 bool empty()
const {
return Ranges.empty(); }
210 void addInst(int64_t OffsetFromFirst,
Instruction *Inst) {
211 if (
StoreInst *SI = dyn_cast<StoreInst>(Inst))
212 addStore(OffsetFromFirst, SI);
214 addMemSet(OffsetFromFirst, cast<MemSetInst>(Inst));
217 void addStore(int64_t OffsetFromFirst,
StoreInst *SI) {
220 addRange(OffsetFromFirst, StoreSize,
224 void addMemSet(int64_t OffsetFromFirst,
MemSetInst *MSI) {
225 int64_t Size = cast<ConstantInt>(MSI->
getLength())->getZExtValue();
242 int64_t
End = Start+Size;
244 range_iterator
I = std::lower_bound(Ranges.begin(), Ranges.end(), Start,
245 [](
const MemsetRange &LHS, int64_t RHS) {
return LHS.End < RHS; });
250 if (I == Ranges.end() || End < I->Start) {
251 MemsetRange &R = *Ranges.insert(I, MemsetRange());
255 R.Alignment = Alignment;
256 R.TheStores.push_back(Inst);
261 I->TheStores.push_back(Inst);
265 if (I->Start <= Start && I->End >= End)
274 if (Start < I->Start) {
277 I->Alignment = Alignment;
285 range_iterator NextI =
I;
286 while (++NextI != Ranges.end() && End >= NextI->Start) {
288 I->TheStores.append(NextI->TheStores.begin(), NextI->TheStores.end());
289 if (NextI->End > I->End)
310 bool runOnFunction(
Function &
F)
override;
331 uint64_t cpyLen,
unsigned cpyAlign,
CallInst *
C);
335 bool processByValArgument(
CallSite CS,
unsigned ArgNo);
366 const DataLayout &DL = StartInst->getModule()->getDataLayout();
372 MemsetRanges Ranges(DL);
375 for (++BI; !isa<TerminatorInst>(BI); ++BI) {
376 if (!isa<StoreInst>(BI) && !isa<MemSetInst>(BI)) {
380 if (BI->mayWriteToMemory() || BI->mayReadFromMemory())
385 if (
StoreInst *NextStore = dyn_cast<StoreInst>(BI)) {
387 if (!NextStore->isSimple())
break;
399 Ranges.addStore(Offset, NextStore);
412 Ranges.addMemSet(Offset, MSI);
424 Ranges.addInst(0, StartInst);
434 for (
const MemsetRange &Range : Ranges) {
436 if (Range.TheStores.size() == 1)
continue;
439 if (!Range.isProfitableToUseMemset(DL))
444 StartPtr = Range.StartPtr;
447 unsigned Alignment = Range.Alignment;
448 if (Alignment == 0) {
450 cast<PointerType>(StartPtr->getType())->getElementType();
455 Builder.
CreateMemSet(StartPtr, ByteVal, Range.End-Range.Start, Alignment);
459 dbgs() << *SI <<
'\n';
460 dbgs() <<
"With: " << *AMemSet <<
'\n');
462 if (!Range.TheStores.empty())
463 AMemSet->
setDebugLoc(Range.TheStores[0]->getDebugLoc());
467 MD->removeInstruction(SI);
485 return std::min(StoreAlign, LoadAlign);
522 bool NeedLift =
false;
550 }
else if (isa<LoadInst>(
C) || isa<StoreInst>(
C) || isa<VAArgInst>(
C)) {
556 MemLocs.push_back(ML);
563 for (
unsigned k = 0, e =
C->getNumOperands(); k != e; ++k)
564 if (
auto *
A = dyn_cast<Instruction>(
C->getOperand(k)))
570 for (
auto *I :
reverse(ToLift)) {
571 DEBUG(
dbgs() <<
"Lifting " << *I <<
" before " << *P <<
"\n");
594 if (LI->isSimple() && LI->hasOneUse() &&
597 auto *
T = LI->getType();
598 if (
T->isAggregateType()) {
619 if (!
moveUp(AA, SI, P, LI))
629 bool UseMemMove =
false;
640 LI->getPointerOperand(), Size,
644 LI->getPointerOperand(), Size,
647 DEBUG(
dbgs() <<
"Promoting " << *LI <<
" to " << *SI
648 <<
" => " << *M <<
"\n");
653 LI->eraseFromParent();
674 bool CpyDestIsLocal = isa<AllocaInst>(CpyDest);
685 if (I->mayThrow() && !CpyDestIsLocal) {
693 bool changed = performCallSlotOptzn(
702 LI->eraseFromParent();
720 BBI = I->getIterator();
727 auto *
T = V->getType();
728 if (
T->isAggregateType()) {
737 DEBUG(
dbgs() <<
"Promoting " << *SI <<
" to " << *M <<
"\n");
758 BBI = I->getIterator();
769 Value *cpySrc, uint64_t cpyLen,
787 if (
F->isIntrinsic() &&
F->getIntrinsicID() == Intrinsic::lifetime_start)
807 if (cpyLen < srcSize)
813 if (
AllocaInst *
A = dyn_cast<AllocaInst>(cpyDest)) {
822 if (destSize < srcSize)
824 }
else if (
Argument *
A = dyn_cast<Argument>(cpyDest)) {
829 if (
A->getDereferenceableBytes() < srcSize) {
832 if (!
A->hasStructRetAttr())
835 Type *StructTy = cast<PointerType>(
A->getType())->getElementType();
844 if (destSize < srcSize)
855 bool isDestSufficientlyAligned = srcAlign <= cpyAlign;
858 if (!isDestSufficientlyAligned && !isa<AllocaInst>(cpyDest))
867 while (!srcUseList.empty()) {
868 User *U = srcUseList.pop_back_val();
870 if (isa<BitCastInst>(U) || isa<AddrSpaceCastInst>(U)) {
872 srcUseList.push_back(UU);
876 if (!
G->hasAllZeroIndices())
880 srcUseList.push_back(UU);
884 if (
IT->getIntrinsicID() == Intrinsic::lifetime_start ||
885 IT->getIntrinsicID() == Intrinsic::lifetime_end)
888 if (U != C && U != cpy)
894 for (
unsigned i = 0, e =
CS.arg_size();
i != e; ++
i)
895 if (
CS.getArgument(
i) == cpySrc && !
CS.doesNotCapture(
i))
901 if (
Instruction *cpyDestInst = dyn_cast<Instruction>(cpyDest))
918 bool changedArgument =
false;
919 for (
unsigned i = 0;
i <
CS.arg_size(); ++
i)
920 if (
CS.getArgument(
i)->stripPointerCasts() == cpySrc) {
924 changedArgument =
true;
925 if (
CS.getArgument(
i)->getType() == Dest->
getType())
926 CS.setArgument(
i, Dest);
929 CS.getArgument(
i)->getType(), Dest->
getName(),
C));
932 if (!changedArgument)
936 if (!isDestSufficientlyAligned) {
937 assert(isa<AllocaInst>(cpyDest) &&
"Can only increase alloca alignment!");
938 cast<AllocaInst>(cpyDest)->setAlignment(srcAlign);
962 bool MemCpyOptPass::processMemCpyMemCpyDependence(
MemCpyInst *M,
981 if (!MDepLen || !MLen || MDepLen->
getZExtValue() < MLen->getZExtValue())
1007 bool UseMemMove =
false;
1050 bool MemCpyOptPass::processMemSetMemCpyDependence(
MemCpyInst *MemCpy,
1060 if (DstDepInfo.
getInst() != MemSet)
1072 const unsigned DestAlign =
1075 if (
ConstantInt *SrcSizeC = dyn_cast<ConstantInt>(SrcSize))
1076 Align =
MinAlign(SrcSizeC->getZExtValue(), DestAlign);
1084 SrcSize = Builder.CreateZExt(SrcSize, DestSize->
getType());
1086 DestSize = Builder.CreateZExt(DestSize, SrcSize->
getType());
1089 Value *Ule = Builder.CreateICmpULE(DestSize, SrcSize);
1090 Value *SizeDiff = Builder.CreateSub(DestSize, SrcSize);
1091 Value *MemsetLen = Builder.CreateSelect(
1093 Builder.CreateMemSet(Builder.CreateGEP(Dest, SrcSize), MemSet->
getOperand(1),
1115 bool MemCpyOptPass::performMemCpyToMemSetOptzn(
MemCpyInst *MemCpy,
1128 if (!MemSetSize || CopySize->
getZExtValue() > MemSetSize->getZExtValue())
1142 bool MemCpyOptPass::processMemCpy(
MemCpyInst *M) {
1155 if (GV->isConstant() && GV->hasDefinitiveInitializer())
1172 if (processMemSetMemCpyDependence(M, MDep))
1177 if (!CopySize)
return false;
1204 return processMemCpyMemCpyDependence(M, MDep);
1205 }
else if (SrcDepInfo.
isDef()) {
1207 bool hasUndefContents =
false;
1209 if (isa<AllocaInst>(I)) {
1210 hasUndefContents =
true;
1211 }
else if (
IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
1212 if (II->getIntrinsicID() == Intrinsic::lifetime_start)
1213 if (
ConstantInt *LTSize = dyn_cast<ConstantInt>(II->getArgOperand(0)))
1214 if (LTSize->getZExtValue() >= CopySize->
getZExtValue())
1215 hasUndefContents =
true;
1218 if (hasUndefContents) {
1228 if (performMemCpyToMemSetOptzn(M, MDep)) {
1240 bool MemCpyOptPass::processMemMove(
MemMoveInst *M) {
1243 if (!TLI->
has(LibFunc::memmove))
1251 DEBUG(
dbgs() <<
"MemCpyOptPass: Optimizing memmove -> memcpy: " << *M
1259 Intrinsic::memcpy, ArgTys));
1270 bool MemCpyOptPass::processByValArgument(
CallSite CS,
unsigned ArgNo) {
1274 Type *ByValTy = cast<PointerType>(ByValArg->
getType())->getElementType();
1298 if (ByValAlign == 0)
return false;
1329 DEBUG(
dbgs() <<
"MemCpyOptPass: Forwarding memcpy to byval:\n"
1330 <<
" " << *MDep <<
"\n"
1340 bool MemCpyOptPass::iterateOnFunction(
Function &
F) {
1341 bool MadeChange =
false;
1349 bool RepeatInstruction =
false;
1351 if (
StoreInst *SI = dyn_cast<StoreInst>(I))
1352 MadeChange |= processStore(SI, BI);
1353 else if (
MemSetInst *M = dyn_cast<MemSetInst>(I))
1354 RepeatInstruction = processMemSet(M, BI);
1355 else if (
MemCpyInst *M = dyn_cast<MemCpyInst>(I))
1356 RepeatInstruction = processMemCpy(M);
1357 else if (
MemMoveInst *M = dyn_cast<MemMoveInst>(I))
1358 RepeatInstruction = processMemMove(M);
1360 for (
unsigned i = 0, e = CS.
arg_size();
i != e; ++
i)
1362 MadeChange |= processByValArgument(CS,
i);
1366 if (RepeatInstruction) {
1367 if (BI != BB.begin())
1392 bool MadeChange =
runImpl(F, &MD, &TLI, LookupAliasAnalysis,
1393 LookupAssumptionCache, LookupDomTree);
1407 bool MadeChange =
false;
1410 LookupAliasAnalysis = std::move(LookupAliasAnalysis_);
1411 LookupAssumptionCache = std::move(LookupAssumptionCache_);
1412 LookupDomTree = std::move(LookupDomTree_);
1417 if (!TLI->
has(LibFunc::memset) || !TLI->
has(LibFunc::memcpy))
1421 if (!iterateOnFunction(F))
1431 bool MemCpyOptLegacyPass::runOnFunction(
Function &F) {
1432 if (skipFunction(F))
1435 auto *MD = &getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
1436 auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
1439 return getAnalysis<AAResultsWrapperPass>().getAAResults();
1442 return getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
1445 return getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1448 return Impl.runImpl(F, MD, TLI, LookupAliasAnalysis, LookupAssumptionCache,
unsigned getAlignment() const
Legacy wrapper pass to provide the GlobalsAAResult object.
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::ZeroOrMore, cl::values(clEnumValN(DefaultIT,"arm-default-it","Generate IT block based on arch"), clEnumValN(RestrictedIT,"arm-restrict-it","Disallow deprecated IT based on ARMv8"), clEnumValN(NoRestrictedIT,"arm-no-restrict-it","Allow IT blocks based on ARMv7")))
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
Type * getIndexedType() const
const_iterator end(StringRef path)
Get end iterator over path.
FunTy * getCaller() const
getCaller - Return the caller function for this call site
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Provides a lazy, caching interface for making common memory aliasing information queries, backed by LLVM's alias analysis passes.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to ensure that the alignment of V is at least PrefAlign bytes.
LLVM Argument representation.
uint64_t getZExtValue() const
Get zero extended value.
bool isDef() const
Tests if this MemDepResult represents a query that is an instruction definition dependency.
STATISTIC(NumFunctions,"Total number of functions")
bool isVolatile() const
Return true if this is a store to a volatile memory location.
Value * isBytewiseValue(Value *V)
If the specified value can be set by repeating the same byte in memory, return the i8 value that it i...
Value * getValue() const
Return the arguments to the instruction.
Implements a dense probed hash-table based set.
unsigned getNumOperands() const
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias. ...
This class represents a function call, abstracting a target machine's calling convention.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of .assume calls within a function.
bool erase(const ValueT &V)
static bool IsPointerOffset(Value *Ptr1, Value *Ptr2, int64_t &Offset, const DataLayout &DL)
Return true if Ptr1 is provably equal to Ptr2 plus a constant offset, and return that constant offset...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
const_iterator begin(StringRef path)
Get begin iterator over path.
This class wraps the llvm.memset intrinsic.
Analysis pass which computes a DominatorTree.
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memset to the specified pointer and the specified value.
An instruction for reading from memory.
The access modifies the value stored in memory.
bool isClobber() const
Tests if this MemDepResult represents a query that is an instruction clobber dependency.
The two locations may or may not alias. This is the least precise result.
unsigned arg_size() const
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
StringRef getName() const
Return a constant reference to the value's name.
AnalysisUsage & addRequired()
StructType * getStructTypeOrNull() const
#define INITIALIZE_PASS_DEPENDENCY(depName)
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
INITIALIZE_PASS_BEGIN(MemCpyOptLegacyPass,"memcpyopt","MemCpy Optimization", false, false) INITIALIZE_PASS_END(MemCpyOptLegacyPass
static int64_t GetOffsetFromIndex(const GEPOperator *GEP, unsigned Idx, bool &VariableIdxFound, const DataLayout &DL)
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
const APInt & getValue() const
Return the constant as an APInt value reference.
This class wraps the llvm.memmove intrinsic.
bool has(LibFunc::Func F) const
Tests whether a library function is available.
Class to represent struct types.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
An analysis that produces MemoryDependenceResults for a function.
void setArgument(unsigned ArgNo, Value *newVal)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
static MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
This class represents a no-op cast from one type to another.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
An instruction for storing to memory.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
uint64_t getElementOffset(unsigned Idx) const
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
MinAlign - A and B are either alignments or offsets.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
The access neither references nor modifies the value stored in memory.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
friend const_iterator end(StringRef path)
Get end iterator over path.
unsigned getAlignment() const
Return the alignment of the access that is being performed.
A set of analyses that are preserved following a run of a transformation pass.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
A manager for alias analyses.
std::pair< iterator, bool > insert(const ValueT &V)
unsigned getAlignment() const
Return the alignment of the memory that is being allocated by the instruction.
Value * getRawDest() const
Represent the analysis usage information of a pass.
uint16_t getParamAlignment(uint16_t i) const
Extract the alignment for a call or parameter (0=unknown).
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
Analysis pass providing a never-invalidated alias analysis result.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static const unsigned End
FunctionPass * createMemCpyOptPass()
The public interface to this file...
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
self_iterator getIterator()
unsigned getIntegerBitWidth() const
static CastInst * CreatePointerCast(Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd)
Create a BitCast AddrSpaceCast, or a PtrToInt cast instruction.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void initializeMemCpyOptLegacyPassPass(PassRegistry &)
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance...
A memory dependence query can return one of three different answers.
bool runImpl(Function &F, MemoryDependenceResults *MD_, TargetLibraryInfo *TLI_, std::function< AliasAnalysis &()> LookupAliasAnalysis_, std::function< AssumptionCache &()> LookupAssumptionCache_, std::function< DominatorTree &()> LookupDomTree_)
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
Representation for a specific memory location.
A function analysis which provides an AssumptionCache.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
MemDepResult getPointerDependencyFrom(const MemoryLocation &Loc, bool isLoad, BasicBlock::iterator ScanIt, BasicBlock *BB, Instruction *QueryInst=nullptr, unsigned *Limit=nullptr)
Returns the instruction on which a memory location depends.
Iterator for intrusive lists based on ilist_node.
This is the shared class of boolean and integer constants.
InstrTy * getInstruction() const
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Value * getDest() const
This is just like getRawDest, but it strips off any cast instructions that feed it, giving the original input.
friend const_iterator begin(StringRef path)
Get begin iterator over path.
ValTy * getArgument(unsigned ArgNo) const
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
Provides information about what library functions are available for the current target.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Value * getLength() const
Value * stripPointerCasts()
Strip off pointer casts, all-zero GEPs, and aliases.
This class wraps the llvm.memcpy intrinsic.
Function * getCalledFunction() const
Return the function called, or null if this is an indirect function invocation.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
ModRefInfo callCapturesBefore(const Instruction *I, const MemoryLocation &MemLoc, DominatorTree *DT, OrderedBasicBlock *OBB=nullptr)
Return information about whether a particular call site modifies or reads the specified memory locati...
ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc)
getModRefInfo (for call sites) - Return information about whether a particular call site modifies or ...
iterator_range< user_iterator > users()
bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are must-alias.
bool mayThrow() const
Return true if this instruction may throw an exception.
Value * getSource() const
This is just like getRawSource, but it strips off any cast instructions that feed it...
void setCalledFunction(Value *Fn)
Set the function called.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Instruction * getInst() const
If this is a normal dependency, returns the instruction that is depended on.
unsigned getAlignment() const
Return the alignment of the access that is being performed.
ImmutableCallSite - establish a view to a call site for examination.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void preserve()
Mark an analysis as preserved.
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
Analysis pass providing the TargetLibraryInfo.
Value * getRawSource() const
Return the arguments to the instruction.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
void removeInstruction(Instruction *InstToRemove)
Removes an instruction from the dependence analysis, updating the dependence of instructions that pre...
const Value * getArraySize() const
Get the number of elements allocated.
print Print MemDeps of function
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
A container for analyses that lazily runs them and caches their results.
Legacy analysis pass which computes a DominatorTree.
static bool moveUp(AliasAnalysis &AA, StoreInst *SI, Instruction *P, const LoadInst *LI)
static unsigned findCommonAlignment(const DataLayout &DL, const StoreInst *SI, const LoadInst *LI)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
Value * getPointerOperand()
void combineMetadata(Instruction *K, const Instruction *J, ArrayRef< unsigned > KnownIDs)
Combine the metadata of two instructions so that K can replace J.
const BasicBlock * getParent() const
A wrapper class for inspecting calls to intrinsic functions.
an instruction to allocate memory on the stack
gep_type_iterator gep_type_begin(const User *GEP)
MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.
static MemoryLocation getForSource(const MemTransferInst *MTI)
Return a location representing the source of a memory transfer.