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 {
194 unsigned FlatAddrSpace = 0;
198 bool updateAddressSpace(
const Value &V,
199 ValueToAddrSpaceMapTy &InferredAddrSpace,
200 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
205 ValueToAddrSpaceMapTy &InferredAddrSpace,
206 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
208 bool isSafeToCastConstAddrSpace(
Constant *
C,
unsigned NewAS)
const;
210 Value *cloneInstructionWithNewAddressSpace(
213 const PredicatedAddrSpaceMapTy &PredicatedAS,
216 void performPointerReplacement(
223 bool rewriteWithNewAddressSpaces(
225 const ValueToAddrSpaceMapTy &InferredAddrSpace,
226 const PredicatedAddrSpaceMapTy &PredicatedAS)
const;
228 void appendsFlatAddressExpressionToPostorderStack(
229 Value *V, PostorderStackTy &PostorderStack,
235 PostorderStackTy &PostorderStack,
238 std::vector<WeakTrackingVH> collectFlatAddressExpressions(
Function &F)
const;
240 Value *cloneValueWithNewAddressSpace(
241 Value *V,
unsigned NewAddrSpace,
243 const PredicatedAddrSpaceMapTy &PredicatedAS,
245 unsigned joinAddressSpaces(
unsigned AS1,
unsigned AS2)
const;
247 unsigned getPredicatedAddrSpace(
const Value &PtrV,
248 const Value *UserCtx)
const;
253 : AC(AC), DT(DT),
TTI(
TTI), FlatAddrSpace(FlatAddrSpace) {}
259char InferAddressSpaces::ID = 0;
269 assert(Ty->isPtrOrPtrVectorTy());
270 PointerType *NPT = PointerType::get(Ty->getContext(), NewAddrSpace);
271 return Ty->getWithNewType(NPT);
280 auto *P2I = dyn_cast<Operator>(I2P->
getOperand(0));
281 if (!P2I || P2I->getOpcode() != Instruction::PtrToInt)
297 unsigned P2IOp0AS = P2I->getOperand(0)->getType()->getPointerAddressSpace();
303 P2I->getOperand(0)->getType(), P2I->getType(),
317 switch (
Op->getOpcode()) {
318 case Instruction::PHI:
319 assert(
Op->getType()->isPtrOrPtrVectorTy());
321 case Instruction::BitCast:
322 case Instruction::AddrSpaceCast:
323 case Instruction::GetElementPtr:
325 case Instruction::Select:
326 return Op->getType()->isPtrOrPtrVectorTy();
327 case Instruction::Call: {
329 return II &&
II->getIntrinsicID() == Intrinsic::ptrmask;
331 case Instruction::IntToPtr:
346 switch (
Op.getOpcode()) {
347 case Instruction::PHI: {
348 auto IncomingValues = cast<PHINode>(
Op).incoming_values();
349 return {IncomingValues.begin(), IncomingValues.end()};
351 case Instruction::BitCast:
352 case Instruction::AddrSpaceCast:
353 case Instruction::GetElementPtr:
354 return {
Op.getOperand(0)};
355 case Instruction::Select:
356 return {
Op.getOperand(1),
Op.getOperand(2)};
357 case Instruction::Call: {
359 assert(
II.getIntrinsicID() == Intrinsic::ptrmask &&
360 "unexpected intrinsic call");
361 return {
II.getArgOperand(0)};
363 case Instruction::IntToPtr: {
365 auto *P2I = cast<Operator>(
Op.getOperand(0));
366 return {P2I->getOperand(0)};
373bool InferAddressSpacesImpl::rewriteIntrinsicOperands(
IntrinsicInst *
II,
376 Module *
M =
II->getParent()->getParent()->getParent();
379 case Intrinsic::objectsize:
380 case Intrinsic::masked_load: {
381 Type *DestTy =
II->getType();
384 II->setArgOperand(0, NewV);
385 II->setCalledFunction(NewDecl);
388 case Intrinsic::ptrmask:
391 case Intrinsic::masked_gather: {
395 II->setArgOperand(0, NewV);
396 II->setCalledFunction(NewDecl);
399 case Intrinsic::masked_store:
400 case Intrinsic::masked_scatter: {
401 Type *ValueTy =
II->getOperand(0)->getType();
405 II->setArgOperand(1, NewV);
406 II->setCalledFunction(NewDecl);
409 case Intrinsic::prefetch:
410 case Intrinsic::is_constant: {
413 II->setArgOperand(0, NewV);
414 II->setCalledFunction(NewDecl);
422 II->replaceAllUsesWith(Rewrite);
428void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
431 auto IID =
II->getIntrinsicID();
433 case Intrinsic::ptrmask:
434 case Intrinsic::objectsize:
435 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
436 PostorderStack, Visited);
438 case Intrinsic::is_constant: {
440 if (
Ptr->getType()->isPtrOrPtrVectorTy()) {
441 appendsFlatAddressExpressionToPostorderStack(
Ptr, PostorderStack,
447 case Intrinsic::masked_load:
448 case Intrinsic::masked_gather:
449 case Intrinsic::prefetch:
450 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
451 PostorderStack, Visited);
453 case Intrinsic::masked_store:
454 case Intrinsic::masked_scatter:
455 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(1),
456 PostorderStack, Visited);
461 for (
int Idx : OpIndexes) {
462 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(
Idx),
463 PostorderStack, Visited);
473void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
474 Value *V, PostorderStackTy &PostorderStack,
476 assert(
V->getType()->isPtrOrPtrVectorTy());
483 PostorderStack.emplace_back(CE,
false);
488 if (
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
490 if (Visited.
insert(V).second) {
491 PostorderStack.emplace_back(V,
false);
497 PostorderStack.emplace_back(CE,
false);
506std::vector<WeakTrackingVH>
507InferAddressSpacesImpl::collectFlatAddressExpressions(
Function &
F)
const {
510 PostorderStackTy PostorderStack;
514 auto PushPtrOperand = [&](
Value *
Ptr) {
515 appendsFlatAddressExpressionToPostorderStack(
Ptr, PostorderStack, Visited);
522 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(&
I)) {
523 PushPtrOperand(
GEP->getPointerOperand());
524 }
else if (
auto *LI = dyn_cast<LoadInst>(&
I))
525 PushPtrOperand(LI->getPointerOperand());
526 else if (
auto *SI = dyn_cast<StoreInst>(&
I))
527 PushPtrOperand(
SI->getPointerOperand());
528 else if (
auto *RMW = dyn_cast<AtomicRMWInst>(&
I))
529 PushPtrOperand(RMW->getPointerOperand());
530 else if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(&
I))
531 PushPtrOperand(CmpX->getPointerOperand());
532 else if (
auto *
MI = dyn_cast<MemIntrinsic>(&
I)) {
534 PushPtrOperand(
MI->getRawDest());
537 if (
auto *MTI = dyn_cast<MemTransferInst>(
MI))
538 PushPtrOperand(MTI->getRawSource());
539 }
else if (
auto *
II = dyn_cast<IntrinsicInst>(&
I))
540 collectRewritableIntrinsicOperands(
II, PostorderStack, Visited);
541 else if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(&
I)) {
542 if (
Cmp->getOperand(0)->getType()->isPtrOrPtrVectorTy()) {
543 PushPtrOperand(
Cmp->getOperand(0));
544 PushPtrOperand(
Cmp->getOperand(1));
546 }
else if (
auto *ASC = dyn_cast<AddrSpaceCastInst>(&
I)) {
547 PushPtrOperand(ASC->getPointerOperand());
548 }
else if (
auto *I2P = dyn_cast<IntToPtrInst>(&
I)) {
550 PushPtrOperand(cast<Operator>(I2P->getOperand(0))->getOperand(0));
551 }
else if (
auto *RI = dyn_cast<ReturnInst>(&
I)) {
552 if (
auto *RV = RI->getReturnValue();
553 RV && RV->getType()->isPtrOrPtrVectorTy())
558 std::vector<WeakTrackingVH> Postorder;
559 while (!PostorderStack.empty()) {
560 Value *TopVal = PostorderStack.back().getPointer();
563 if (PostorderStack.back().getInt()) {
565 Postorder.push_back(TopVal);
566 PostorderStack.pop_back();
570 PostorderStack.back().setInt(
true);
574 appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
586 const Use &OperandUse,
unsigned NewAddrSpace,
588 const PredicatedAddrSpaceMapTy &PredicatedAS,
594 if (
Constant *
C = dyn_cast<Constant>(Operand))
597 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand))
601 auto I = PredicatedAS.find(std::make_pair(Inst, Operand));
602 if (
I != PredicatedAS.end()) {
604 unsigned NewAS =
I->second;
607 NewI->insertBefore(Inst);
628Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
631 const PredicatedAddrSpaceMapTy &PredicatedAS,
635 if (
I->getOpcode() == Instruction::AddrSpaceCast) {
636 Value *Src =
I->getOperand(0);
640 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
641 if (Src->getType() != NewPtrType)
649 assert(
II->getIntrinsicID() == Intrinsic::ptrmask);
651 II->getArgOperandUse(0), NewAddrSpace, ValueWithNewAddrSpace,
652 PredicatedAS, PoisonUsesToFix);
656 assert(Rewrite !=
II &&
"cannot modify this pointer operation in place");
669 NewI->insertAfter(
I);
670 NewI->setDebugLoc(
I->getDebugLoc());
676 for (
const Use &OperandUse :
I->operands()) {
677 if (!OperandUse.get()->getType()->isPtrOrPtrVectorTy())
681 OperandUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
685 switch (
I->getOpcode()) {
686 case Instruction::BitCast:
687 return new BitCastInst(NewPointerOperands[0], NewPtrType);
688 case Instruction::PHI: {
689 assert(
I->getType()->isPtrOrPtrVectorTy());
699 case Instruction::GetElementPtr: {
702 GEP->getSourceElementType(), NewPointerOperands[0],
707 case Instruction::Select:
708 assert(
I->getType()->isPtrOrPtrVectorTy());
710 NewPointerOperands[2],
"",
nullptr,
I);
711 case Instruction::IntToPtr: {
713 Value *Src = cast<Operator>(
I->getOperand(0))->getOperand(0);
714 if (Src->getType() == NewPtrType)
735 CE->getType()->isPtrOrPtrVectorTy()
739 if (CE->getOpcode() == Instruction::AddrSpaceCast) {
743 assert(CE->getOperand(0)->getType()->getPointerAddressSpace() ==
748 if (CE->getOpcode() == Instruction::BitCast) {
749 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(CE->getOperand(0)))
754 if (CE->getOpcode() == Instruction::IntToPtr) {
756 Constant *Src = cast<ConstantExpr>(CE->getOperand(0))->getOperand(0);
757 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
771 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand)) {
773 NewOperands.
push_back(cast<Constant>(NewOperand));
776 if (
auto *CExpr = dyn_cast<ConstantExpr>(Operand))
778 CExpr, NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI)) {
780 NewOperands.
push_back(cast<Constant>(NewOperand));
792 if (CE->getOpcode() == Instruction::GetElementPtr) {
795 return CE->getWithOperands(NewOperands, TargetType,
false,
796 cast<GEPOperator>(CE)->getSourceElementType());
799 return CE->getWithOperands(NewOperands, TargetType);
807Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
808 Value *V,
unsigned NewAddrSpace,
810 const PredicatedAddrSpaceMapTy &PredicatedAS,
813 assert(
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
817 Value *NewV = cloneInstructionWithNewAddressSpace(
818 I, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, PoisonUsesToFix);
819 if (
Instruction *NewI = dyn_cast_or_null<Instruction>(NewV)) {
820 if (NewI->getParent() ==
nullptr) {
821 NewI->insertBefore(
I);
823 NewI->setDebugLoc(
I->getDebugLoc());
830 cast<ConstantExpr>(V), NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI);
835unsigned InferAddressSpacesImpl::joinAddressSpaces(
unsigned AS1,
836 unsigned AS2)
const {
837 if (AS1 == FlatAddrSpace || AS2 == FlatAddrSpace)
838 return FlatAddrSpace;
846 return (AS1 == AS2) ? AS1 : FlatAddrSpace;
849bool InferAddressSpacesImpl::run(
Function &CurFn) {
851 DL = &
F->getDataLayout();
863 std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions(*
F);
867 ValueToAddrSpaceMapTy InferredAddrSpace;
868 PredicatedAddrSpaceMapTy PredicatedAS;
869 inferAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS);
873 return rewriteWithNewAddressSpaces(Postorder, InferredAddrSpace,
879void InferAddressSpacesImpl::inferAddressSpaces(
881 ValueToAddrSpaceMapTy &InferredAddrSpace,
882 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
885 for (
Value *V : Postorder)
888 while (!Worklist.empty()) {
889 Value *
V = Worklist.pop_back_val();
893 if (!updateAddressSpace(*V, InferredAddrSpace, PredicatedAS))
898 if (Worklist.count(
User))
901 auto Pos = InferredAddrSpace.find(
User);
904 if (Pos == InferredAddrSpace.end())
910 if (Pos->second == FlatAddrSpace)
913 Worklist.insert(
User);
919InferAddressSpacesImpl::getPredicatedAddrSpace(
const Value &
Ptr,
920 const Value *UserCtx)
const {
921 const Instruction *UserCtxI = dyn_cast<Instruction>(UserCtx);
925 const Value *StrippedPtr =
Ptr.stripInBoundsOffsets();
926 for (
auto &AssumeVH : AC.assumptionsFor(StrippedPtr)) {
929 CallInst *CI = cast<CallInst>(AssumeVH);
943bool InferAddressSpacesImpl::updateAddressSpace(
944 const Value &V, ValueToAddrSpaceMapTy &InferredAddrSpace,
945 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
946 assert(InferredAddrSpace.count(&V));
948 LLVM_DEBUG(
dbgs() <<
"Updating the address space of\n " << V <<
'\n');
955 if (
Op.getOpcode() == Instruction::Select) {
956 Value *Src0 =
Op.getOperand(1);
957 Value *Src1 =
Op.getOperand(2);
959 auto I = InferredAddrSpace.find(Src0);
960 unsigned Src0AS = (
I != InferredAddrSpace.end())
964 auto J = InferredAddrSpace.find(Src1);
965 unsigned Src1AS = (J != InferredAddrSpace.end())
969 auto *C0 = dyn_cast<Constant>(Src0);
970 auto *C1 = dyn_cast<Constant>(Src1);
979 if (C0 && isSafeToCastConstAddrSpace(C0, Src1AS))
981 else if (C1 && isSafeToCastConstAddrSpace(C1, Src0AS))
984 NewAS = joinAddressSpaces(Src0AS, Src1AS);
993 auto I = InferredAddrSpace.find(PtrOperand);
995 if (
I == InferredAddrSpace.end()) {
996 OperandAS = PtrOperand->getType()->getPointerAddressSpace();
997 if (OperandAS == FlatAddrSpace) {
999 unsigned AS = getPredicatedAddrSpace(*PtrOperand, &V);
1002 <<
" deduce operand AS from the predicate addrspace "
1006 PredicatedAS[std::make_pair(&V, PtrOperand)] = OperandAS;
1010 OperandAS =
I->second;
1013 NewAS = joinAddressSpaces(NewAS, OperandAS);
1014 if (NewAS == FlatAddrSpace)
1020 unsigned OldAS = InferredAddrSpace.lookup(&V);
1021 assert(OldAS != FlatAddrSpace);
1028 InferredAddrSpace[&
V] = NewAS;
1037 if (U.get() == OldVal) {
1045template <
typename InstrType>
1047 InstrType *MemInstr,
unsigned AddrSpace,
1065 User *Inst,
unsigned AddrSpace,
1067 if (
auto *LI = dyn_cast<LoadInst>(Inst))
1070 if (
auto *SI = dyn_cast<StoreInst>(Inst))
1073 if (
auto *RMW = dyn_cast<AtomicRMWInst>(Inst))
1076 if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst))
1088 MDNode *TBAA =
MI->getMetadata(LLVMContext::MD_tbaa);
1089 MDNode *ScopeMD =
MI->getMetadata(LLVMContext::MD_alias_scope);
1090 MDNode *NoAliasMD =
MI->getMetadata(LLVMContext::MD_noalias);
1092 if (
auto *MSI = dyn_cast<MemSetInst>(
MI)) {
1093 B.CreateMemSet(NewV, MSI->getValue(), MSI->getLength(), MSI->getDestAlign(),
1095 TBAA, ScopeMD, NoAliasMD);
1096 }
else if (
auto *MTI = dyn_cast<MemTransferInst>(
MI)) {
1097 Value *Src = MTI->getRawSource();
1098 Value *Dest = MTI->getRawDest();
1107 if (isa<MemCpyInlineInst>(MTI)) {
1108 MDNode *TBAAStruct = MTI->getMetadata(LLVMContext::MD_tbaa_struct);
1109 B.CreateMemCpyInline(Dest, MTI->getDestAlign(), Src,
1110 MTI->getSourceAlign(), MTI->getLength(),
1112 TBAA, TBAAStruct, ScopeMD, NoAliasMD);
1113 }
else if (isa<MemCpyInst>(MTI)) {
1114 MDNode *TBAAStruct = MTI->getMetadata(LLVMContext::MD_tbaa_struct);
1115 B.CreateMemCpy(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1118 TBAA, TBAAStruct, ScopeMD, NoAliasMD);
1120 assert(isa<MemMoveInst>(MTI));
1121 B.CreateMemMove(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1124 TBAA, ScopeMD, NoAliasMD);
1129 MI->eraseFromParent();
1135bool InferAddressSpacesImpl::isSafeToCastConstAddrSpace(
Constant *
C,
1136 unsigned NewAS)
const {
1139 unsigned SrcAS =
C->getType()->getPointerAddressSpace();
1140 if (SrcAS == NewAS || isa<UndefValue>(
C))
1144 if (SrcAS != FlatAddrSpace && NewAS != FlatAddrSpace)
1147 if (isa<ConstantPointerNull>(
C))
1150 if (
auto *
Op = dyn_cast<Operator>(
C)) {
1153 if (
Op->getOpcode() == Instruction::AddrSpaceCast)
1154 return isSafeToCastConstAddrSpace(cast<Constant>(
Op->getOperand(0)),
1157 if (
Op->getOpcode() == Instruction::IntToPtr &&
1158 Op->getType()->getPointerAddressSpace() == FlatAddrSpace)
1167 User *CurUser =
I->getUser();
1170 while (
I !=
End &&
I->getUser() == CurUser)
1176void InferAddressSpacesImpl::performPointerReplacement(
1180 User *CurUser =
U.getUser();
1182 unsigned AddrSpace =
V->getType()->getPointerAddressSpace();
1187 if (CurUser == NewV)
1190 auto *CurUserI = dyn_cast<Instruction>(CurUser);
1191 if (!CurUserI || CurUserI->getFunction() !=
F)
1195 if (
auto *
MI = dyn_cast<MemIntrinsic>(CurUser)) {
1200 if (
auto *
II = dyn_cast<IntrinsicInst>(CurUser)) {
1201 if (rewriteIntrinsicOperands(
II, V, NewV))
1205 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(CurUserI)) {
1213 int SrcIdx =
U.getOperandNo();
1214 int OtherIdx = (SrcIdx == 0) ? 1 : 0;
1215 Value *OtherSrc =
Cmp->getOperand(OtherIdx);
1217 if (
Value *OtherNewV = ValueWithNewAddrSpace.
lookup(OtherSrc)) {
1218 if (OtherNewV->getType()->getPointerAddressSpace() == NewAS) {
1219 Cmp->setOperand(OtherIdx, OtherNewV);
1220 Cmp->setOperand(SrcIdx, NewV);
1226 if (
auto *KOtherSrc = dyn_cast<Constant>(OtherSrc)) {
1227 if (isSafeToCastConstAddrSpace(KOtherSrc, NewAS)) {
1228 Cmp->setOperand(SrcIdx, NewV);
1238 if (ASC->getDestAddressSpace() == NewAS) {
1239 ASC->replaceAllUsesWith(NewV);
1246 if (
Instruction *VInst = dyn_cast<Instruction>(V)) {
1248 if (U == V && isa<AddrSpaceCastInst>(V))
1253 if (
Instruction *NewVInst = dyn_cast<Instruction>(NewV))
1254 InsertPos = std::next(NewVInst->getIterator());
1256 InsertPos = std::next(VInst->getIterator());
1258 while (isa<PHINode>(InsertPos))
1264 CurUserI->replaceUsesOfWith(
1269bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
1271 const ValueToAddrSpaceMapTy &InferredAddrSpace,
1272 const PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1279 for (
Value *V : Postorder) {
1280 unsigned NewAddrSpace = InferredAddrSpace.lookup(V);
1287 if (
V->getType()->getPointerAddressSpace() != NewAddrSpace) {
1289 cloneValueWithNewAddressSpace(V, NewAddrSpace, ValueWithNewAddrSpace,
1290 PredicatedAS, &PoisonUsesToFix);
1292 ValueWithNewAddrSpace[
V] =
New;
1296 if (ValueWithNewAddrSpace.
empty())
1300 for (
const Use *PoisonUse : PoisonUsesToFix) {
1301 User *
V = PoisonUse->getUser();
1302 User *NewV = cast_or_null<User>(ValueWithNewAddrSpace.
lookup(V));
1306 unsigned OperandNo = PoisonUse->getOperandNo();
1308 NewV->
setOperand(OperandNo, ValueWithNewAddrSpace.
lookup(PoisonUse->get()));
1317 assert(WVH &&
"value was unexpectedly deleted");
1320 if (NewV ==
nullptr)
1323 LLVM_DEBUG(
dbgs() <<
"Replacing the uses of " << *V <<
"\n with\n "
1326 if (
Constant *
C = dyn_cast<Constant>(V)) {
1330 LLVM_DEBUG(
dbgs() <<
"Inserting replacement const cast: " << Replace
1331 <<
": " << *Replace <<
'\n');
1334 if (
auto *
I = dyn_cast<Instruction>(U)) {
1335 if (
I->getFunction() ==
F)
1336 I->replaceUsesOfWith(
C, Replace);
1338 WorkList.
append(
U->user_begin(),
U->user_end());
1341 if (!WorkList.
empty()) {
1344 while (!WorkList.
empty()) {
1346 if (
auto *
I = dyn_cast<Instruction>(U)) {
1347 if (
I->getFunction() ==
F)
1348 VMapper.remapInstruction(*
I);
1351 for (
User *U2 :
U->users())
1352 if (Visited.
insert(U2).second)
1361 for (
I =
V->use_begin(), E =
V->use_end();
I != E;) {
1368 performPointerReplacement(V, NewV, U, ValueWithNewAddrSpace,
1372 if (
V->use_empty()) {
1384bool InferAddressSpaces::runOnFunction(
Function &
F) {
1385 if (skipFunction(
F))
1388 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
1390 return InferAddressSpacesImpl(
1391 getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F), DT,
1392 &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F),
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-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.
This defines the Use class.
static bool replaceIfSimplePointerUse(const TargetTransformInfo &TTI, User *Inst, unsigned AddrSpace, Value *OldV, Value *NewV)
If OldV is used as the pointer operand of a compatible memory operation Inst, replaces the pointer op...
static bool replaceOperandIfSame(Instruction *Inst, unsigned OpIdx, Value *OldVal, Value *NewVal)
Replace operand OpIdx in Inst, if the value is the same as OldVal with NewVal.
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 Value::use_iterator skipToNextUser(Value::use_iterator I, Value::use_iterator End)
Infer address static false Type * getPtrOrVecOfPtrsWithNewAS(Type *Ty, unsigned NewAddrSpace)
static bool replaceSimplePointerUse(const TargetTransformInfo &TTI, InstrType *MemInstr, unsigned AddrSpace, Value *OldV, Value *NewV)
static const unsigned UninitializedAddressSpace
uint64_t IntrinsicInst * II
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 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.
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.
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
static CastInst * CreatePointerBitCastOrAddrSpaceCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
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
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
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.
A wrapper class for inspecting calls to intrinsic functions.
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 unsigned getOperandNumForIncomingValue(unsigned i)
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
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="", InsertPosition 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 append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
const Use & getOperandUse(unsigned i) const
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...
Context for (re-)mapping values (and metadata).
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
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.
InstrType
This represents what is and is not supported when finding similarity in Instructions.
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 isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, const DominatorTree *DT=nullptr, bool AllowEphemerals=false)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
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 &)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
@ RF_IgnoreMissingLocals
If this flag is set, the remapper ignores missing function-local entries (Argument,...
@ RF_NoModuleLevelChanges
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createInferAddressSpacesPass(unsigned AddressSpace=~0u)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)