136#define DEBUG_TYPE "infer-address-spaces"
142 cl::desc(
"The default address space is assumed as the flat address space. "
143 "This is mainly for test purpose."));
146 std::numeric_limits<unsigned>::max();
157using PredicatedAddrSpaceMapTy =
162 unsigned FlatAddrSpace = 0;
171 InferAddressSpaces(
unsigned AS) :
FunctionPass(
ID), FlatAddrSpace(AS) {
185class InferAddressSpacesImpl {
193 unsigned FlatAddrSpace = 0;
197 bool updateAddressSpace(
const Value &V,
198 ValueToAddrSpaceMapTy &InferredAddrSpace,
199 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
204 ValueToAddrSpaceMapTy &InferredAddrSpace,
205 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
207 bool isSafeToCastConstAddrSpace(
Constant *
C,
unsigned NewAS)
const;
209 Value *cloneInstructionWithNewAddressSpace(
212 const PredicatedAddrSpaceMapTy &PredicatedAS,
220 const ValueToAddrSpaceMapTy &InferredAddrSpace,
221 const PredicatedAddrSpaceMapTy &PredicatedAS,
224 void appendsFlatAddressExpressionToPostorderStack(
225 Value *V, PostorderStackTy &PostorderStack,
231 PostorderStackTy &PostorderStack,
234 std::vector<WeakTrackingVH> collectFlatAddressExpressions(
Function &
F)
const;
236 Value *cloneValueWithNewAddressSpace(
237 Value *V,
unsigned NewAddrSpace,
239 const PredicatedAddrSpaceMapTy &PredicatedAS,
241 unsigned joinAddressSpaces(
unsigned AS1,
unsigned AS2)
const;
243 unsigned getPredicatedAddrSpace(
const Value &V,
Value *Opnd)
const;
248 : AC(AC), DT(DT),
TTI(
TTI), FlatAddrSpace(FlatAddrSpace) {}
254char InferAddressSpaces::ID = 0;
264 assert(Ty->isPtrOrPtrVectorTy());
265 PointerType *NPT = PointerType::get(Ty->getContext(), NewAddrSpace);
266 return Ty->getWithNewType(NPT);
275 auto *P2I = dyn_cast<Operator>(I2P->
getOperand(0));
276 if (!P2I || P2I->getOpcode() != Instruction::PtrToInt)
292 unsigned P2IOp0AS = P2I->getOperand(0)->getType()->getPointerAddressSpace();
298 P2I->getOperand(0)->getType(), P2I->getType(),
312 switch (
Op->getOpcode()) {
313 case Instruction::PHI:
314 assert(
Op->getType()->isPtrOrPtrVectorTy());
316 case Instruction::BitCast:
317 case Instruction::AddrSpaceCast:
318 case Instruction::GetElementPtr:
320 case Instruction::Select:
321 return Op->getType()->isPtrOrPtrVectorTy();
322 case Instruction::Call: {
326 case Instruction::IntToPtr:
341 switch (
Op.getOpcode()) {
342 case Instruction::PHI: {
343 auto IncomingValues = cast<PHINode>(
Op).incoming_values();
344 return {IncomingValues.begin(), IncomingValues.end()};
346 case Instruction::BitCast:
347 case Instruction::AddrSpaceCast:
348 case Instruction::GetElementPtr:
349 return {
Op.getOperand(0)};
350 case Instruction::Select:
351 return {
Op.getOperand(1),
Op.getOperand(2)};
352 case Instruction::Call: {
355 "unexpected intrinsic call");
358 case Instruction::IntToPtr: {
360 auto *P2I = cast<Operator>(
Op.getOperand(0));
361 return {P2I->getOperand(0)};
368bool InferAddressSpacesImpl::rewriteIntrinsicOperands(
IntrinsicInst *II,
374 case Intrinsic::objectsize: {
383 case Intrinsic::ptrmask:
386 case Intrinsic::masked_gather: {
395 case Intrinsic::masked_scatter: {
415void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
420 case Intrinsic::ptrmask:
421 case Intrinsic::objectsize:
422 appendsFlatAddressExpressionToPostorderStack(II->
getArgOperand(0),
423 PostorderStack, Visited);
425 case Intrinsic::masked_gather:
426 appendsFlatAddressExpressionToPostorderStack(II->
getArgOperand(0),
427 PostorderStack, Visited);
429 case Intrinsic::masked_scatter:
430 appendsFlatAddressExpressionToPostorderStack(II->
getArgOperand(1),
431 PostorderStack, Visited);
436 for (
int Idx : OpIndexes) {
438 PostorderStack, Visited);
448void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
449 Value *V, PostorderStackTy &PostorderStack,
451 assert(
V->getType()->isPtrOrPtrVectorTy());
458 PostorderStack.emplace_back(CE,
false);
463 if (
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
465 if (Visited.
insert(V).second) {
466 PostorderStack.emplace_back(V,
false);
472 PostorderStack.emplace_back(CE,
false);
481std::vector<WeakTrackingVH>
482InferAddressSpacesImpl::collectFlatAddressExpressions(
Function &
F)
const {
485 PostorderStackTy PostorderStack;
489 auto PushPtrOperand = [&](
Value *
Ptr) {
490 appendsFlatAddressExpressionToPostorderStack(
Ptr, PostorderStack, Visited);
497 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(&
I)) {
498 PushPtrOperand(
GEP->getPointerOperand());
499 }
else if (
auto *LI = dyn_cast<LoadInst>(&
I))
500 PushPtrOperand(LI->getPointerOperand());
501 else if (
auto *SI = dyn_cast<StoreInst>(&
I))
502 PushPtrOperand(
SI->getPointerOperand());
503 else if (
auto *RMW = dyn_cast<AtomicRMWInst>(&
I))
504 PushPtrOperand(RMW->getPointerOperand());
505 else if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(&
I))
506 PushPtrOperand(CmpX->getPointerOperand());
507 else if (
auto *
MI = dyn_cast<MemIntrinsic>(&
I)) {
509 PushPtrOperand(
MI->getRawDest());
512 if (
auto *MTI = dyn_cast<MemTransferInst>(
MI))
513 PushPtrOperand(MTI->getRawSource());
514 }
else if (
auto *II = dyn_cast<IntrinsicInst>(&
I))
515 collectRewritableIntrinsicOperands(II, PostorderStack, Visited);
516 else if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(&
I)) {
517 if (
Cmp->getOperand(0)->getType()->isPtrOrPtrVectorTy()) {
518 PushPtrOperand(
Cmp->getOperand(0));
519 PushPtrOperand(
Cmp->getOperand(1));
521 }
else if (
auto *ASC = dyn_cast<AddrSpaceCastInst>(&
I)) {
522 PushPtrOperand(ASC->getPointerOperand());
523 }
else if (
auto *I2P = dyn_cast<IntToPtrInst>(&
I)) {
525 PushPtrOperand(cast<Operator>(I2P->getOperand(0))->getOperand(0));
529 std::vector<WeakTrackingVH> Postorder;
530 while (!PostorderStack.empty()) {
531 Value *TopVal = PostorderStack.back().getPointer();
534 if (PostorderStack.back().getInt()) {
536 Postorder.push_back(TopVal);
537 PostorderStack.pop_back();
541 PostorderStack.back().setInt(
true);
545 appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
557 const Use &OperandUse,
unsigned NewAddrSpace,
559 const PredicatedAddrSpaceMapTy &PredicatedAS,
565 if (
Constant *
C = dyn_cast<Constant>(Operand))
568 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand))
572 auto I = PredicatedAS.find(std::make_pair(Inst, Operand));
573 if (
I != PredicatedAS.end()) {
575 unsigned NewAS =
I->second;
578 NewI->insertBefore(Inst);
599Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
602 const PredicatedAddrSpaceMapTy &PredicatedAS,
606 if (
I->getOpcode() == Instruction::AddrSpaceCast) {
607 Value *Src =
I->getOperand(0);
611 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
612 if (Src->getType() != NewPtrType)
623 PredicatedAS, PoisonUsesToFix);
627 assert(Rewrite != II &&
"cannot modify this pointer operation in place");
640 NewI->insertAfter(
I);
646 for (
const Use &OperandUse :
I->operands()) {
647 if (!OperandUse.get()->getType()->isPtrOrPtrVectorTy())
651 OperandUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
655 switch (
I->getOpcode()) {
656 case Instruction::BitCast:
657 return new BitCastInst(NewPointerOperands[0], NewPtrType);
658 case Instruction::PHI: {
659 assert(
I->getType()->isPtrOrPtrVectorTy());
669 case Instruction::GetElementPtr: {
672 GEP->getSourceElementType(), NewPointerOperands[0],
677 case Instruction::Select:
678 assert(
I->getType()->isPtrOrPtrVectorTy());
680 NewPointerOperands[2],
"",
nullptr,
I);
681 case Instruction::IntToPtr: {
683 Value *Src = cast<Operator>(
I->getOperand(0))->getOperand(0);
684 if (Src->getType() == NewPtrType)
705 CE->getType()->isPtrOrPtrVectorTy()
709 if (CE->getOpcode() == Instruction::AddrSpaceCast) {
713 assert(CE->getOperand(0)->getType()->getPointerAddressSpace() ==
718 if (CE->getOpcode() == Instruction::BitCast) {
719 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(CE->getOperand(0)))
724 if (CE->getOpcode() == Instruction::IntToPtr) {
726 Constant *Src = cast<ConstantExpr>(CE->getOperand(0))->getOperand(0);
727 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
741 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand)) {
743 NewOperands.
push_back(cast<Constant>(NewOperand));
746 if (
auto *CExpr = dyn_cast<ConstantExpr>(Operand))
748 CExpr, NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI)) {
750 NewOperands.
push_back(cast<Constant>(NewOperand));
762 if (CE->getOpcode() == Instruction::GetElementPtr) {
765 return CE->getWithOperands(NewOperands, TargetType,
false,
766 cast<GEPOperator>(CE)->getSourceElementType());
769 return CE->getWithOperands(NewOperands, TargetType);
777Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
778 Value *V,
unsigned NewAddrSpace,
780 const PredicatedAddrSpaceMapTy &PredicatedAS,
783 assert(
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
787 Value *NewV = cloneInstructionWithNewAddressSpace(
788 I, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, PoisonUsesToFix);
789 if (
Instruction *NewI = dyn_cast_or_null<Instruction>(NewV)) {
790 if (NewI->getParent() ==
nullptr) {
791 NewI->insertBefore(
I);
793 NewI->setDebugLoc(
I->getDebugLoc());
800 cast<ConstantExpr>(V), NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI);
805unsigned InferAddressSpacesImpl::joinAddressSpaces(
unsigned AS1,
806 unsigned AS2)
const {
807 if (AS1 == FlatAddrSpace || AS2 == FlatAddrSpace)
808 return FlatAddrSpace;
816 return (AS1 == AS2) ? AS1 : FlatAddrSpace;
819bool InferAddressSpacesImpl::run(
Function &
F) {
820 DL = &
F.getParent()->getDataLayout();
832 std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions(
F);
836 ValueToAddrSpaceMapTy InferredAddrSpace;
837 PredicatedAddrSpaceMapTy PredicatedAS;
838 inferAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS);
842 return rewriteWithNewAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS,
848void InferAddressSpacesImpl::inferAddressSpaces(
850 ValueToAddrSpaceMapTy &InferredAddrSpace,
851 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
854 for (
Value *V : Postorder)
857 while (!Worklist.empty()) {
858 Value *
V = Worklist.pop_back_val();
862 if (!updateAddressSpace(*V, InferredAddrSpace, PredicatedAS))
867 if (Worklist.count(
User))
870 auto Pos = InferredAddrSpace.find(
User);
873 if (Pos == InferredAddrSpace.end())
879 if (Pos->second == FlatAddrSpace)
882 Worklist.insert(
User);
887unsigned InferAddressSpacesImpl::getPredicatedAddrSpace(
const Value &V,
894 for (
auto &AssumeVH : AC.assumptionsFor(Opnd)) {
897 CallInst *CI = cast<CallInst>(AssumeVH);
911bool InferAddressSpacesImpl::updateAddressSpace(
912 const Value &V, ValueToAddrSpaceMapTy &InferredAddrSpace,
913 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
914 assert(InferredAddrSpace.count(&V));
916 LLVM_DEBUG(
dbgs() <<
"Updating the address space of\n " << V <<
'\n');
923 if (
Op.getOpcode() == Instruction::Select) {
924 Value *Src0 =
Op.getOperand(1);
925 Value *Src1 =
Op.getOperand(2);
927 auto I = InferredAddrSpace.find(Src0);
928 unsigned Src0AS = (
I != InferredAddrSpace.end())
932 auto J = InferredAddrSpace.find(Src1);
933 unsigned Src1AS = (J != InferredAddrSpace.end())
937 auto *C0 = dyn_cast<Constant>(Src0);
938 auto *C1 = dyn_cast<Constant>(Src1);
947 if (C0 && isSafeToCastConstAddrSpace(C0, Src1AS))
949 else if (C1 && isSafeToCastConstAddrSpace(C1, Src0AS))
952 NewAS = joinAddressSpaces(Src0AS, Src1AS);
961 auto I = InferredAddrSpace.find(PtrOperand);
963 if (
I == InferredAddrSpace.end()) {
964 OperandAS = PtrOperand->getType()->getPointerAddressSpace();
965 if (OperandAS == FlatAddrSpace) {
967 unsigned AS = getPredicatedAddrSpace(V, PtrOperand);
970 <<
" deduce operand AS from the predicate addrspace "
974 PredicatedAS[std::make_pair(&V, PtrOperand)] = OperandAS;
978 OperandAS =
I->second;
981 NewAS = joinAddressSpaces(NewAS, OperandAS);
982 if (NewAS == FlatAddrSpace)
988 unsigned OldAS = InferredAddrSpace.lookup(&V);
989 assert(OldAS != FlatAddrSpace);
996 InferredAddrSpace[&
V] = NewAS;
1006 Use &U,
unsigned AddrSpace) {
1007 User *Inst = U.getUser();
1008 unsigned OpNo = U.getOperandNo();
1009 bool VolatileIsAllowed =
false;
1010 if (
auto *
I = dyn_cast<Instruction>(Inst))
1013 if (
auto *LI = dyn_cast<LoadInst>(Inst))
1015 (VolatileIsAllowed || !LI->isVolatile());
1017 if (
auto *SI = dyn_cast<StoreInst>(Inst))
1019 (VolatileIsAllowed || !SI->isVolatile());
1021 if (
auto *RMW = dyn_cast<AtomicRMWInst>(Inst))
1023 (VolatileIsAllowed || !RMW->isVolatile());
1025 if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst))
1027 (VolatileIsAllowed || !CmpX->isVolatile());
1038 MDNode *TBAA =
MI->getMetadata(LLVMContext::MD_tbaa);
1039 MDNode *ScopeMD =
MI->getMetadata(LLVMContext::MD_alias_scope);
1040 MDNode *NoAliasMD =
MI->getMetadata(LLVMContext::MD_noalias);
1042 if (
auto *MSI = dyn_cast<MemSetInst>(
MI)) {
1043 B.CreateMemSet(NewV, MSI->getValue(), MSI->getLength(), MSI->getDestAlign(),
1045 TBAA, ScopeMD, NoAliasMD);
1046 }
else if (
auto *MTI = dyn_cast<MemTransferInst>(
MI)) {
1047 Value *Src = MTI->getRawSource();
1048 Value *Dest = MTI->getRawDest();
1057 if (isa<MemCpyInlineInst>(MTI)) {
1058 MDNode *TBAAStruct = MTI->getMetadata(LLVMContext::MD_tbaa_struct);
1059 B.CreateMemCpyInline(Dest, MTI->getDestAlign(), Src,
1060 MTI->getSourceAlign(), MTI->getLength(),
1062 TBAA, TBAAStruct, ScopeMD, NoAliasMD);
1063 }
else if (isa<MemCpyInst>(MTI)) {
1064 MDNode *TBAAStruct = MTI->getMetadata(LLVMContext::MD_tbaa_struct);
1065 B.CreateMemCpy(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1068 TBAA, TBAAStruct, ScopeMD, NoAliasMD);
1070 assert(isa<MemMoveInst>(MTI));
1071 B.CreateMemMove(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1074 TBAA, ScopeMD, NoAliasMD);
1079 MI->eraseFromParent();
1085bool InferAddressSpacesImpl::isSafeToCastConstAddrSpace(
Constant *
C,
1086 unsigned NewAS)
const {
1089 unsigned SrcAS =
C->getType()->getPointerAddressSpace();
1090 if (SrcAS == NewAS || isa<UndefValue>(
C))
1094 if (SrcAS != FlatAddrSpace && NewAS != FlatAddrSpace)
1097 if (isa<ConstantPointerNull>(
C))
1100 if (
auto *
Op = dyn_cast<Operator>(
C)) {
1103 if (
Op->getOpcode() == Instruction::AddrSpaceCast)
1104 return isSafeToCastConstAddrSpace(cast<Constant>(
Op->getOperand(0)),
1107 if (
Op->getOpcode() == Instruction::IntToPtr &&
1108 Op->getType()->getPointerAddressSpace() == FlatAddrSpace)
1117 User *CurUser =
I->getUser();
1120 while (
I !=
End &&
I->getUser() == CurUser)
1126bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
1128 const ValueToAddrSpaceMapTy &InferredAddrSpace,
1129 const PredicatedAddrSpaceMapTy &PredicatedAS,
Function *
F)
const {
1136 for (
Value *V : Postorder) {
1137 unsigned NewAddrSpace = InferredAddrSpace.lookup(V);
1144 if (
V->getType()->getPointerAddressSpace() != NewAddrSpace) {
1146 cloneValueWithNewAddressSpace(V, NewAddrSpace, ValueWithNewAddrSpace,
1147 PredicatedAS, &PoisonUsesToFix);
1149 ValueWithNewAddrSpace[
V] =
New;
1153 if (ValueWithNewAddrSpace.
empty())
1157 for (
const Use *PoisonUse : PoisonUsesToFix) {
1158 User *
V = PoisonUse->getUser();
1159 User *NewV = cast_or_null<User>(ValueWithNewAddrSpace.
lookup(V));
1163 unsigned OperandNo = PoisonUse->getOperandNo();
1165 NewV->
setOperand(OperandNo, ValueWithNewAddrSpace.
lookup(PoisonUse->get()));
1172 assert(WVH &&
"value was unexpectedly deleted");
1175 if (NewV ==
nullptr)
1178 LLVM_DEBUG(
dbgs() <<
"Replacing the uses of " << *V <<
"\n with\n "
1181 if (
Constant *
C = dyn_cast<Constant>(V)) {
1185 LLVM_DEBUG(
dbgs() <<
"Inserting replacement const cast: " << Replace
1186 <<
": " << *Replace <<
'\n');
1187 C->replaceAllUsesWith(Replace);
1193 for (
I =
V->use_begin(),
E =
V->use_end();
I !=
E;) {
1201 *
TTI, U,
V->getType()->getPointerAddressSpace())) {
1209 User *CurUser =
U.getUser();
1211 if (CurUser == NewV)
1214 if (
auto *
MI = dyn_cast<MemIntrinsic>(CurUser)) {
1219 if (
auto *II = dyn_cast<IntrinsicInst>(CurUser)) {
1220 if (rewriteIntrinsicOperands(II, V, NewV))
1224 if (isa<Instruction>(CurUser)) {
1225 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(CurUser)) {
1233 int SrcIdx =
U.getOperandNo();
1234 int OtherIdx = (SrcIdx == 0) ? 1 : 0;
1235 Value *OtherSrc =
Cmp->getOperand(OtherIdx);
1237 if (
Value *OtherNewV = ValueWithNewAddrSpace.
lookup(OtherSrc)) {
1238 if (OtherNewV->getType()->getPointerAddressSpace() == NewAS) {
1239 Cmp->setOperand(OtherIdx, OtherNewV);
1240 Cmp->setOperand(SrcIdx, NewV);
1246 if (
auto *KOtherSrc = dyn_cast<Constant>(OtherSrc)) {
1247 if (isSafeToCastConstAddrSpace(KOtherSrc, NewAS)) {
1248 Cmp->setOperand(SrcIdx, NewV);
1258 if (ASC->getDestAddressSpace() == NewAS) {
1259 ASC->replaceAllUsesWith(NewV);
1266 if (
Instruction *VInst = dyn_cast<Instruction>(V)) {
1268 if (U == V && isa<AddrSpaceCastInst>(V))
1273 if (
Instruction *NewVInst = dyn_cast<Instruction>(NewV))
1274 InsertPos = std::next(NewVInst->getIterator());
1276 InsertPos = std::next(VInst->getIterator());
1278 while (isa<PHINode>(InsertPos))
1288 if (
V->use_empty()) {
1300bool InferAddressSpaces::runOnFunction(
Function &
F) {
1301 if (skipFunction(
F))
1304 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
1306 return InferAddressSpacesImpl(
1307 getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F), DT,
1308 &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F),
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
static cl::opt< bool > AssumeDefaultIsFlatAddressSpace("assume-default-is-flat-addrspace", cl::init(false), cl::ReallyHidden, cl::desc("The default address space is assumed as the flat address space. " "This is mainly for test purpose."))
static bool isNoopPtrIntCastPair(const Operator *I2P, const DataLayout &DL, const TargetTransformInfo *TTI)
static bool isAddressExpression(const Value &V, const DataLayout &DL, const TargetTransformInfo *TTI)
static bool handleMemIntrinsicPtrUse(MemIntrinsic *MI, Value *OldV, Value *NewV)
Update memory intrinsic uses that require more complex processing than simple memory instructions.
static SmallVector< Value *, 2 > getPointerOperands(const Value &V, const DataLayout &DL, const TargetTransformInfo *TTI)
static Value * operandWithNewAddressSpaceOrCreatePoison(const Use &OperandUse, unsigned NewAddrSpace, const ValueToValueMapTy &ValueWithNewAddrSpace, const PredicatedAddrSpaceMapTy &PredicatedAS, SmallVectorImpl< const Use * > *PoisonUsesToFix)
static Value * cloneConstantExprWithNewAddressSpace(ConstantExpr *CE, unsigned NewAddrSpace, const ValueToValueMapTy &ValueWithNewAddrSpace, const DataLayout *DL, const TargetTransformInfo *TTI)
static bool isSimplePointerUseValidToReplace(const TargetTransformInfo &TTI, Use &U, unsigned AddrSpace)
returns true if U is the pointer operand of a memory instruction with a single pointer operand that c...
static Value::use_iterator skipToNextUser(Value::use_iterator I, Value::use_iterator End)
Infer address static false Type * getPtrOrVecOfPtrsWithNewAS(Type *Ty, unsigned NewAddrSpace)
static const unsigned UninitializedAddressSpace
Select target instructions out of generic instructions
This header defines various interfaces for pass management in LLVM.
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This defines the Use class.
This class represents a conversion between pointers from one address space to another.
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
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()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
static unsigned getPointerOperandIndex()
static unsigned getPointerOperandIndex()
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
This class represents a no-op cast from one type to another.
Represents analyses that only rely on functions' control flow.
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
This class represents a function call, abstracting a target machine's calling convention.
static CastInst * CreatePointerBitCastOrAddrSpaceCast(Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd)
Create a BitCast or an AddrSpaceCast cast instruction.
static bool isNoopCast(Instruction::CastOps Opcode, Type *SrcTy, Type *DstTy, const DataLayout &DL)
A no-op cast is one that can be effected without changing any bits.
A constant value that is initialized with an expression using other constant values.
static Constant * getAddrSpaceCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Module * getParent()
Get the module that this global value is contained inside of...
This instruction compares its operands according to the predicate given to the constructor.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
const BasicBlock * getParent() const
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static unsigned getPointerOperandIndex()
This is the common base class for memset/memcpy/memmove.
A Module instance is used to store all the information related to an LLVM module.
This is a utility class that provides an abstraction for the common functionality between Instruction...
unsigned getOpcode() const
Return the opcode for this Instruction or ConstantExpr.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static unsigned getOperandNumForIncomingValue(unsigned i)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
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.
void preserveSet()
Mark an analysis set as preserved.
void preserve()
Mark an analysis as preserved.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static unsigned getPointerOperandIndex()
Analysis pass providing the TargetTransformInfo.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
const Value * stripInBoundsOffsets(function_ref< void(const Value *)> Func=[](const Value *) {}) const
Strip off pointer casts and inbounds GEPs.
use_iterator_impl< Use > use_iterator
Value handle that is nullable, but tries to track the Value.
std::pair< iterator, bool > insert(const ValueT &V)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
void initializeInferAddressSpacesPass(PassRegistry &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createInferAddressSpacesPass(unsigned AddressSpace=~0u)
bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, const DominatorTree *DT=nullptr)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)