135#define DEBUG_TYPE "infer-address-spaces"
141 cl::desc(
"The default address space is assumed as the flat address space. "
142 "This is mainly for test purpose."));
145 std::numeric_limits<unsigned>::max();
156using PredicatedAddrSpaceMapTy =
161 unsigned FlatAddrSpace = 0;
170 InferAddressSpaces(
unsigned AS) : FunctionPass(ID), FlatAddrSpace(AS) {
174 void getAnalysisUsage(AnalysisUsage &AU)
const override {
184class InferAddressSpacesImpl {
187 const DominatorTree *DT =
nullptr;
188 const TargetTransformInfo *TTI =
nullptr;
189 const DataLayout *DL =
nullptr;
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 *clonePtrMaskWithNewAddressSpace(
210 IntrinsicInst *
I,
unsigned NewAddrSpace,
212 const PredicatedAddrSpaceMapTy &PredicatedAS,
213 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const;
215 Value *cloneInstructionWithNewAddressSpace(
216 Instruction *
I,
unsigned NewAddrSpace,
218 const PredicatedAddrSpaceMapTy &PredicatedAS,
219 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const;
221 void performPointerReplacement(
223 SmallVectorImpl<Instruction *> &DeadInstructions)
const;
228 bool rewriteWithNewAddressSpaces(
230 const ValueToAddrSpaceMapTy &InferredAddrSpace,
231 const PredicatedAddrSpaceMapTy &PredicatedAS)
const;
233 void appendsFlatAddressExpressionToPostorderStack(
234 Value *V, PostorderStackTy &PostorderStack,
235 DenseSet<Value *> &Visited)
const;
237 bool rewriteIntrinsicOperands(IntrinsicInst *
II,
Value *OldV,
239 void collectRewritableIntrinsicOperands(IntrinsicInst *
II,
240 PostorderStackTy &PostorderStack,
241 DenseSet<Value *> &Visited)
const;
243 std::vector<WeakTrackingVH> collectFlatAddressExpressions(Function &F)
const;
245 Value *cloneValueWithNewAddressSpace(
246 Value *V,
unsigned NewAddrSpace,
248 const PredicatedAddrSpaceMapTy &PredicatedAS,
249 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const;
250 unsigned joinAddressSpaces(
unsigned AS1,
unsigned AS2)
const;
252 unsigned getPredicatedAddrSpace(
const Value &PtrV,
253 const Value *UserCtx)
const;
256 InferAddressSpacesImpl(AssumptionCache &AC,
const DominatorTree *DT,
257 const TargetTransformInfo *TTI,
unsigned FlatAddrSpace)
258 : AC(AC), DT(DT), TTI(TTI), FlatAddrSpace(FlatAddrSpace) {}
259 bool run(Function &F);
264char InferAddressSpaces::ID = 0;
274 assert(Ty->isPtrOrPtrVectorTy());
276 return Ty->getWithNewType(NPT);
286 if (!P2I || P2I->getOpcode() != Instruction::PtrToInt)
302 unsigned P2IOp0AS = P2I->getOperand(0)->getType()->getPointerAddressSpace();
308 P2I->getOperand(0)->getType(), P2I->getType(),
310 (P2IOp0AS == I2PAS ||
TTI->isNoopAddrSpaceCast(P2IOp0AS, I2PAS));
321 return Arg->getType()->isPointerTy() &&
328 switch (
Op->getOpcode()) {
329 case Instruction::PHI:
330 assert(
Op->getType()->isPtrOrPtrVectorTy());
332 case Instruction::BitCast:
333 case Instruction::AddrSpaceCast:
334 case Instruction::GetElementPtr:
336 case Instruction::Select:
337 return Op->getType()->isPtrOrPtrVectorTy();
338 case Instruction::Call: {
340 return II &&
II->getIntrinsicID() == Intrinsic::ptrmask;
342 case Instruction::IntToPtr:
360 switch (
Op.getOpcode()) {
361 case Instruction::PHI: {
363 return {IncomingValues.begin(), IncomingValues.end()};
365 case Instruction::BitCast:
366 case Instruction::AddrSpaceCast:
367 case Instruction::GetElementPtr:
368 return {
Op.getOperand(0)};
369 case Instruction::Select:
370 return {
Op.getOperand(1),
Op.getOperand(2)};
371 case Instruction::Call: {
373 assert(
II.getIntrinsicID() == Intrinsic::ptrmask &&
374 "unexpected intrinsic call");
375 return {
II.getArgOperand(0)};
377 case Instruction::IntToPtr: {
380 return {P2I->getOperand(0)};
387bool InferAddressSpacesImpl::rewriteIntrinsicOperands(
IntrinsicInst *
II,
390 Module *
M =
II->getParent()->getParent()->getParent();
393 case Intrinsic::objectsize:
394 case Intrinsic::masked_load: {
395 Type *DestTy =
II->getType();
399 II->setArgOperand(0, NewV);
400 II->setCalledFunction(NewDecl);
403 case Intrinsic::ptrmask:
406 case Intrinsic::masked_gather: {
407 Type *RetTy =
II->getType();
411 II->setArgOperand(0, NewV);
412 II->setCalledFunction(NewDecl);
415 case Intrinsic::masked_store:
416 case Intrinsic::masked_scatter: {
417 Type *ValueTy =
II->getOperand(0)->getType();
420 M,
II->getIntrinsicID(), {ValueTy, NewPtrTy});
421 II->setArgOperand(1, NewV);
422 II->setCalledFunction(NewDecl);
425 case Intrinsic::prefetch:
426 case Intrinsic::is_constant: {
428 M,
II->getIntrinsicID(), {NewV->getType()});
429 II->setArgOperand(0, NewV);
430 II->setCalledFunction(NewDecl);
433 case Intrinsic::fake_use: {
434 II->replaceUsesOfWith(OldV, NewV);
437 case Intrinsic::lifetime_start:
438 case Intrinsic::lifetime_end: {
442 M,
II->getIntrinsicID(), {NewV->getType()});
443 II->setArgOperand(0, NewV);
444 II->setCalledFunction(NewDecl);
452 II->replaceAllUsesWith(Rewrite);
458void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
459 IntrinsicInst *
II, PostorderStackTy &PostorderStack,
460 DenseSet<Value *> &Visited)
const {
461 auto IID =
II->getIntrinsicID();
463 case Intrinsic::ptrmask:
464 case Intrinsic::objectsize:
465 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
466 PostorderStack, Visited);
468 case Intrinsic::is_constant: {
469 Value *Ptr =
II->getArgOperand(0);
471 appendsFlatAddressExpressionToPostorderStack(Ptr, PostorderStack,
477 case Intrinsic::masked_load:
478 case Intrinsic::masked_gather:
479 case Intrinsic::prefetch:
480 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
481 PostorderStack, Visited);
483 case Intrinsic::masked_store:
484 case Intrinsic::masked_scatter:
485 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(1),
486 PostorderStack, Visited);
488 case Intrinsic::fake_use: {
490 if (
Op->getType()->isPtrOrPtrVectorTy()) {
491 appendsFlatAddressExpressionToPostorderStack(
Op, PostorderStack,
498 case Intrinsic::lifetime_start:
499 case Intrinsic::lifetime_end: {
500 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
501 PostorderStack, Visited);
505 SmallVector<int, 2> OpIndexes;
507 for (
int Idx : OpIndexes) {
508 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(Idx),
509 PostorderStack, Visited);
519void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
520 Value *V, PostorderStackTy &PostorderStack,
521 DenseSet<Value *> &Visited)
const {
522 assert(
V->getType()->isPtrOrPtrVectorTy());
529 PostorderStack.emplace_back(CE,
false);
534 if (
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
536 if (Visited.
insert(V).second) {
537 PostorderStack.emplace_back(V,
false);
540 for (
auto &O :
Op->operands())
543 PostorderStack.emplace_back(CE,
false);
550std::vector<WeakTrackingVH>
551InferAddressSpacesImpl::collectFlatAddressExpressions(Function &
F)
const {
554 PostorderStackTy PostorderStack;
556 DenseSet<Value *> Visited;
558 auto PushPtrOperand = [&](
Value *Ptr) {
559 appendsFlatAddressExpressionToPostorderStack(Ptr, PostorderStack, Visited);
567 PushPtrOperand(
GEP->getPointerOperand());
569 PushPtrOperand(LI->getPointerOperand());
571 PushPtrOperand(
SI->getPointerOperand());
573 PushPtrOperand(RMW->getPointerOperand());
575 PushPtrOperand(CmpX->getPointerOperand());
578 PushPtrOperand(
MI->getRawDest());
582 PushPtrOperand(MTI->getRawSource());
584 collectRewritableIntrinsicOperands(
II, PostorderStack, Visited);
586 if (
Cmp->getOperand(0)->getType()->isPtrOrPtrVectorTy()) {
587 PushPtrOperand(
Cmp->getOperand(0));
588 PushPtrOperand(
Cmp->getOperand(1));
591 PushPtrOperand(ASC->getPointerOperand());
594 PushPtrOperand(
cast<Operator>(I2P->getOperand(0))->getOperand(0));
596 if (
auto *RV = RI->getReturnValue();
597 RV && RV->getType()->isPtrOrPtrVectorTy())
602 std::vector<WeakTrackingVH> Postorder;
603 while (!PostorderStack.empty()) {
604 Value *TopVal = PostorderStack.back().getPointer();
607 if (PostorderStack.back().getInt()) {
609 Postorder.push_back(TopVal);
610 PostorderStack.pop_back();
614 PostorderStack.back().setInt(
true);
618 appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
630 auto InsertBefore = [NewI](
auto It) {
640 auto InsertI =
F->getEntryBlock().getFirstNonPHIIt();
641 return InsertBefore(InsertI);
651 auto InsertI = OpInst->
getParent()->getFirstNonPHIIt();
652 return InsertBefore(InsertI);
665 const Use &OperandUse,
unsigned NewAddrSpace,
667 const PredicatedAddrSpaceMapTy &PredicatedAS,
676 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand))
680 auto I = PredicatedAS.find(std::make_pair(Inst, Operand));
681 if (
I != PredicatedAS.end()) {
683 unsigned NewAS =
I->second;
701Value *InferAddressSpacesImpl::clonePtrMaskWithNewAddressSpace(
702 IntrinsicInst *
I,
unsigned NewAddrSpace,
704 const PredicatedAddrSpaceMapTy &PredicatedAS,
705 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const {
706 const Use &PtrOpUse =
I->getArgOperandUse(0);
708 Value *MaskOp =
I->getArgOperand(1);
711 KnownBits OldPtrBits{
DL->getPointerSizeInBits(OldAddrSpace)};
712 KnownBits NewPtrBits{
DL->getPointerSizeInBits(NewAddrSpace)};
714 std::tie(OldPtrBits, NewPtrBits) =
729 OldPtrBits.
One |= ~OldPtrBits.Zero;
731 KnownBits ClearedBits =
KnownBits::sub(OldPtrBits, OldPtrBits & MaskBits);
736 std::optional<BasicBlock::iterator> InsertPoint =
737 I->getInsertionPointAfterDef();
738 assert(InsertPoint &&
"insertion after ptrmask should be possible");
741 new AddrSpaceCastInst(
I, NewPtrType,
"", *InsertPoint);
743 return AddrSpaceCast;
750 MaskOp =
B.CreateTrunc(MaskOp, MaskTy);
753 PtrOpUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
755 return B.CreateIntrinsic(Intrinsic::ptrmask, {NewPtr->
getType(), MaskTy},
768Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
769 Instruction *
I,
unsigned NewAddrSpace,
771 const PredicatedAddrSpaceMapTy &PredicatedAS,
772 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const {
775 if (
I->getOpcode() == Instruction::AddrSpaceCast) {
776 Value *Src =
I->getOperand(0);
780 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
787 assert(
II->getIntrinsicID() == Intrinsic::ptrmask);
788 return clonePtrMaskWithNewAddressSpace(
789 II, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, PoisonUsesToFix);
797 auto *NewI =
new AddrSpaceCastInst(
I, NewPtrTy);
798 NewI->insertAfter(
I->getIterator());
799 NewI->setDebugLoc(
I->getDebugLoc());
804 SmallVector<Value *, 4> NewPointerOperands;
805 for (
const Use &OperandUse :
I->operands()) {
806 if (!OperandUse.get()->getType()->isPtrOrPtrVectorTy())
810 OperandUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
814 switch (
I->getOpcode()) {
815 case Instruction::BitCast:
816 return new BitCastInst(NewPointerOperands[0], NewPtrType);
817 case Instruction::PHI: {
818 assert(
I->getType()->isPtrOrPtrVectorTy());
821 for (
unsigned Index = 0;
Index <
PHI->getNumIncomingValues(); ++
Index) {
824 PHI->getIncomingBlock(Index));
828 case Instruction::GetElementPtr: {
831 GEP->getSourceElementType(), NewPointerOperands[0],
832 SmallVector<Value *, 4>(
GEP->indices()));
836 case Instruction::Select:
837 assert(
I->getType()->isPtrOrPtrVectorTy());
839 NewPointerOperands[2],
"",
nullptr,
I);
840 case Instruction::IntToPtr: {
843 if (Src->getType() == NewPtrType)
849 return new AddrSpaceCastInst(Src, NewPtrType);
864 CE->getType()->isPtrOrPtrVectorTy()
868 if (CE->getOpcode() == Instruction::AddrSpaceCast) {
872 assert(CE->getOperand(0)->getType()->getPointerAddressSpace() ==
874 return CE->getOperand(0);
877 if (CE->getOpcode() == Instruction::BitCast) {
878 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(CE->getOperand(0)))
883 if (CE->getOpcode() == Instruction::IntToPtr) {
886 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
893 for (
unsigned Index = 0; Index < CE->getNumOperands(); ++Index) {
894 Constant *Operand = CE->getOperand(Index);
900 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand)) {
907 CExpr, NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI)) {
921 if (CE->getOpcode() == Instruction::GetElementPtr) {
924 return CE->getWithOperands(NewOperands, TargetType,
false,
928 return CE->getWithOperands(NewOperands, TargetType);
936Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
937 Value *V,
unsigned NewAddrSpace,
939 const PredicatedAddrSpaceMapTy &PredicatedAS,
940 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const {
942 assert(
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
951 Type *NewPtrTy = PointerType::get(Arg->getContext(), NewAddrSpace);
952 auto *NewI =
new AddrSpaceCastInst(Arg, NewPtrTy);
953 NewI->insertBefore(Insert);
958 Value *NewV = cloneInstructionWithNewAddressSpace(
959 I, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, PoisonUsesToFix);
961 if (NewI->getParent() ==
nullptr) {
962 NewI->insertBefore(
I->getIterator());
964 NewI->setDebugLoc(
I->getDebugLoc());
976unsigned InferAddressSpacesImpl::joinAddressSpaces(
unsigned AS1,
977 unsigned AS2)
const {
978 if (AS1 == FlatAddrSpace || AS2 == FlatAddrSpace)
979 return FlatAddrSpace;
987 return (AS1 == AS2) ? AS1 : FlatAddrSpace;
990bool InferAddressSpacesImpl::run(Function &CurFn) {
992 DL = &
F->getDataLayout();
1004 std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions(*
F);
1008 ValueToAddrSpaceMapTy InferredAddrSpace;
1009 PredicatedAddrSpaceMapTy PredicatedAS;
1010 inferAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS);
1014 return rewriteWithNewAddressSpaces(Postorder, InferredAddrSpace,
1020void InferAddressSpacesImpl::inferAddressSpaces(
1022 ValueToAddrSpaceMapTy &InferredAddrSpace,
1023 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1026 for (
Value *V : Postorder)
1029 while (!Worklist.empty()) {
1030 Value *
V = Worklist.pop_back_val();
1034 if (!updateAddressSpace(*V, InferredAddrSpace, PredicatedAS))
1037 for (
Value *User :
V->users()) {
1039 if (Worklist.count(User))
1042 auto Pos = InferredAddrSpace.find(User);
1045 if (Pos == InferredAddrSpace.end())
1051 if (Pos->second == FlatAddrSpace)
1054 Worklist.insert(User);
1060InferAddressSpacesImpl::getPredicatedAddrSpace(
const Value &Ptr,
1061 const Value *UserCtx)
const {
1084bool InferAddressSpacesImpl::updateAddressSpace(
1085 const Value &V, ValueToAddrSpaceMapTy &InferredAddrSpace,
1086 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1087 assert(InferredAddrSpace.count(&V));
1089 LLVM_DEBUG(
dbgs() <<
"Updating the address space of\n " << V <<
'\n');
1106 auto I = InferredAddrSpace.find(PtrOperand);
1108 if (
I == InferredAddrSpace.end()) {
1109 OperandAS = PtrOperand->getType()->getPointerAddressSpace();
1111 C && OperandAS == FlatAddrSpace) {
1116 if (OperandAS == FlatAddrSpace) {
1118 unsigned AS = getPredicatedAddrSpace(*PtrOperand, &V);
1121 <<
" deduce operand AS from the predicate addrspace "
1125 PredicatedAS[std::make_pair(&V, PtrOperand)] = OperandAS;
1129 OperandAS =
I->second;
1132 NewAS = joinAddressSpaces(NewAS, OperandAS);
1133 if (NewAS == FlatAddrSpace)
1137 if (
any_of(ConstantPtrOps, [=](Constant *
C) {
1138 return !isSafeToCastConstAddrSpace(
C, NewAS);
1140 NewAS = FlatAddrSpace;
1144 unsigned OldAS = InferredAddrSpace.lookup(&V);
1145 assert(OldAS != FlatAddrSpace);
1152 InferredAddrSpace[&
V] = NewAS;
1161 if (U.get() == OldVal) {
1169template <
typename InstrType>
1171 InstrType *MemInstr,
unsigned AddrSpace,
1173 if (!MemInstr->isVolatile() ||
TTI.hasVolatileVariant(MemInstr, AddrSpace)) {
1189 User *Inst,
unsigned AddrSpace,
1213 B.CreateMemSet(NewV, MSI->getValue(), MSI->getLength(), MSI->getDestAlign(),
1215 MI->getAAMetadata());
1217 Value *Src = MTI->getRawSource();
1218 Value *Dest = MTI->getRawDest();
1228 if (MCI->isForceInlined())
1229 B.CreateMemCpyInline(Dest, MTI->getDestAlign(), Src,
1230 MTI->getSourceAlign(), MTI->getLength(),
1232 MI->getAAMetadata());
1234 B.CreateMemCpy(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1237 MI->getAAMetadata());
1240 B.CreateMemMove(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1243 MI->getAAMetadata());
1248 MI->eraseFromParent();
1254bool InferAddressSpacesImpl::isSafeToCastConstAddrSpace(Constant *
C,
1255 unsigned NewAS)
const {
1258 unsigned SrcAS =
C->getType()->getPointerAddressSpace();
1263 if (SrcAS != FlatAddrSpace && NewAS != FlatAddrSpace)
1272 if (
Op->getOpcode() == Instruction::AddrSpaceCast)
1276 if (
Op->getOpcode() == Instruction::IntToPtr &&
1277 Op->getType()->getPointerAddressSpace() == FlatAddrSpace)
1286 User *CurUser =
I->getUser();
1289 while (
I != End &&
I->getUser() == CurUser)
1295void InferAddressSpacesImpl::performPointerReplacement(
1297 SmallVectorImpl<Instruction *> &DeadInstructions)
const {
1299 User *CurUser =
U.getUser();
1301 unsigned AddrSpace =
V->getType()->getPointerAddressSpace();
1306 if (CurUser == NewV)
1310 if (!CurUserI || CurUserI->getFunction() !=
F)
1320 if (rewriteIntrinsicOperands(
II, V, NewV))
1332 int SrcIdx =
U.getOperandNo();
1333 int OtherIdx = (SrcIdx == 0) ? 1 : 0;
1334 Value *OtherSrc =
Cmp->getOperand(OtherIdx);
1336 if (
Value *OtherNewV = ValueWithNewAddrSpace.
lookup(OtherSrc)) {
1337 if (OtherNewV->getType()->getPointerAddressSpace() == NewAS) {
1338 Cmp->setOperand(OtherIdx, OtherNewV);
1339 Cmp->setOperand(SrcIdx, NewV);
1346 if (isSafeToCastConstAddrSpace(KOtherSrc, NewAS)) {
1347 Cmp->setOperand(SrcIdx, NewV);
1357 if (ASC->getDestAddressSpace() == NewAS) {
1358 ASC->replaceAllUsesWith(NewV);
1373 InsertPos = std::next(NewVInst->getIterator());
1381 V,
new AddrSpaceCastInst(NewV,
V->getType(),
"", InsertPos));
1383 CurUserI->replaceUsesOfWith(
1388bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
1390 const ValueToAddrSpaceMapTy &InferredAddrSpace,
1391 const PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1398 for (
Value *V : Postorder) {
1399 unsigned NewAddrSpace = InferredAddrSpace.lookup(V);
1406 if (
V->getType()->getPointerAddressSpace() != NewAddrSpace) {
1408 cloneValueWithNewAddressSpace(V, NewAddrSpace, ValueWithNewAddrSpace,
1409 PredicatedAS, &PoisonUsesToFix);
1411 ValueWithNewAddrSpace[
V] =
New;
1415 if (ValueWithNewAddrSpace.
empty())
1419 for (
const Use *PoisonUse : PoisonUsesToFix) {
1420 User *
V = PoisonUse->getUser();
1425 unsigned OperandNo = PoisonUse->getOperandNo();
1427 WeakTrackingVH NewOp = ValueWithNewAddrSpace.
lookup(PoisonUse->get());
1429 "poison replacements in ValueWithNewAddrSpace shouldn't be null");
1433 SmallVector<Instruction *, 16> DeadInstructions;
1438 for (
const WeakTrackingVH &WVH : Postorder) {
1439 assert(WVH &&
"value was unexpectedly deleted");
1442 if (NewV ==
nullptr)
1445 LLVM_DEBUG(
dbgs() <<
"Replacing the uses of " << *V <<
"\n with\n "
1452 LLVM_DEBUG(
dbgs() <<
"Inserting replacement const cast: " << Replace
1453 <<
": " << *Replace <<
'\n');
1457 if (
I->getFunction() ==
F)
1458 I->replaceUsesOfWith(
C, Replace);
1460 WorkList.
append(
U->user_begin(),
U->user_end());
1463 if (!WorkList.
empty()) {
1465 DenseSet<User *> Visited{WorkList.
begin(), WorkList.
end()};
1466 while (!WorkList.
empty()) {
1469 if (
I->getFunction() ==
F)
1470 VMapper.remapInstruction(*
I);
1473 for (User *U2 :
U->users())
1474 if (Visited.
insert(U2).second)
1482 Value::use_iterator
I,
E,
Next;
1483 for (
I =
V->use_begin(),
E =
V->use_end();
I !=
E;) {
1490 performPointerReplacement(V, NewV, U, ValueWithNewAddrSpace,
1494 if (
V->use_empty()) {
1500 for (Instruction *
I : DeadInstructions)
1506bool InferAddressSpaces::runOnFunction(Function &
F) {
1507 if (skipFunction(
F))
1510 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
1511 DominatorTree *DT = DTWP ? &DTWP->getDomTree() :
nullptr;
1512 return InferAddressSpacesImpl(
1513 getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F), DT,
1514 &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F),
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_UNLIKELY(EXPR)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
static bool runOnFunction(Function &F, bool PostInlining)
This header defines various interfaces for pass management in LLVM.
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 Value * phiNodeOperandWithNewAddressSpace(AddrSpaceCastInst *NewI, Value *Operand)
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
Machine Check Debug Module
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file 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.
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.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
This class represents an incoming formal argument to a Function.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
MutableArrayRef< ResultElem > assumptionsFor(const Value *V)
Access the list of assumptions which affect this value.
InstListType::iterator iterator
Instruction iterators...
Represents analyses that only rely on functions' control flow.
Value * getArgOperand(unsigned i) const
static LLVM_ABI 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 LLVM_ABI Constant * getAddrSpaceCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
Analysis pass which computes a DominatorTree.
FunctionPass class - This class is used to implement most global optimizations.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
LLVM_ABI void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
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.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
A wrapper class for inspecting calls to intrinsic functions.
This is the common base class for memset/memcpy/memmove.
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 LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static LLVM_ABI 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.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
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.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
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.
LLVM_ABI 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
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
std::pair< iterator, bool > insert(const ValueT &V)
const ParentTy * getParent() const
self_iterator getIterator()
#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.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI 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,...
LLVM_ABI 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.
LLVM_ABI void initializeInferAddressSpacesPass(PassRegistry &)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr from_range_t from_range
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...
auto cast_or_null(const Y &Val)
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
@ 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...
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
FunctionAddr VTableAddr Next
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI FunctionPass * createInferAddressSpacesPass(unsigned AddressSpace=~0u)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
unsigned getBitWidth() const
Get the bit width of this value.
unsigned countMaxActiveBits() const
Returns the maximum number of bits needed to represent all possible unsigned values with these known ...
static KnownBits sub(const KnownBits &LHS, const KnownBits &RHS, bool NSW=false, bool NUW=false)
Compute knownbits resulting from subtraction of LHS and RHS.