139#define DEBUG_TYPE "infer-address-spaces"
146 cl::desc(
"The default address space is assumed as the flat address space. "
147 "This is mainly for test purpose."));
150 std::numeric_limits<unsigned>::max();
161using PredicatedAddrSpaceMapTy =
166 unsigned FlatAddrSpace = 0;
175 InferAddressSpaces(
unsigned AS) : FunctionPass(ID), FlatAddrSpace(AS) {
179 void getAnalysisUsage(AnalysisUsage &AU)
const override {
189class InferAddressSpacesImpl {
192 const DominatorTree *DT =
nullptr;
193 const TargetTransformInfo *TTI =
nullptr;
194 const DataLayout *DL =
nullptr;
198 unsigned FlatAddrSpace = 0;
199 DenseMap<const Value *, Value *> PtrIntCastPairs;
204 Value *getIntToPtrPointerOperand(
const Operator *I2P)
const;
209 void collectIntToPtrPointerOperand();
213 bool isSafeToCastIntToPtrAddrSpace(
const Operator *I2P)
const {
214 return PtrIntCastPairs.contains(I2P);
216 bool isAddressExpression(
const Value &V,
const DataLayout &DL,
217 const TargetTransformInfo *TTI)
const;
218 Value *cloneConstantExprWithNewAddressSpace(
219 ConstantExpr *CE,
unsigned NewAddrSpace,
221 const TargetTransformInfo *TTI)
const;
223 SmallVector<Value *, 2>
224 getPointerOperands(
const Value &V,
const DataLayout &DL,
225 const TargetTransformInfo *TTI)
const;
229 bool updateAddressSpace(
const Value &V,
230 ValueToAddrSpaceMapTy &InferredAddrSpace,
231 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
236 ValueToAddrSpaceMapTy &InferredAddrSpace,
237 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
239 bool isSafeToCastConstAddrSpace(Constant *
C,
unsigned NewAS)
const;
241 Value *clonePtrMaskWithNewAddressSpace(
242 IntrinsicInst *
I,
unsigned NewAddrSpace,
244 const PredicatedAddrSpaceMapTy &PredicatedAS,
245 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const;
247 Value *cloneInstructionWithNewAddressSpace(
248 Instruction *
I,
unsigned NewAddrSpace,
250 const PredicatedAddrSpaceMapTy &PredicatedAS,
251 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const;
253 void performPointerReplacement(
255 SmallVectorImpl<Instruction *> &DeadInstructions)
const;
260 bool rewriteWithNewAddressSpaces(
262 const ValueToAddrSpaceMapTy &InferredAddrSpace,
263 const PredicatedAddrSpaceMapTy &PredicatedAS)
const;
265 void appendsFlatAddressExpressionToPostorderStack(
266 Value *V, PostorderStackTy &PostorderStack,
267 DenseSet<Value *> &Visited)
const;
269 bool rewriteIntrinsicOperands(IntrinsicInst *
II,
Value *OldV,
271 void collectRewritableIntrinsicOperands(IntrinsicInst *
II,
272 PostorderStackTy &PostorderStack,
273 DenseSet<Value *> &Visited)
const;
275 std::vector<WeakTrackingVH> collectFlatAddressExpressions(Function &F)
const;
277 Value *cloneValueWithNewAddressSpace(
278 Value *V,
unsigned NewAddrSpace,
280 const PredicatedAddrSpaceMapTy &PredicatedAS,
281 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const;
282 unsigned joinAddressSpaces(
unsigned AS1,
unsigned AS2)
const;
284 unsigned getPredicatedAddrSpace(
const Value &PtrV,
285 const Value *UserCtx)
const;
288 InferAddressSpacesImpl(AssumptionCache &AC,
const DominatorTree *DT,
289 const TargetTransformInfo *TTI,
unsigned FlatAddrSpace)
290 : AC(AC), DT(DT), TTI(TTI), FlatAddrSpace(FlatAddrSpace) {}
291 bool run(Function &F);
296char InferAddressSpaces::ID = 0;
306 assert(Ty->isPtrOrPtrVectorTy());
308 return Ty->getWithNewType(NPT);
318 if (!P2I || P2I->getOpcode() != Instruction::PtrToInt)
334 unsigned P2IOp0AS = P2I->getOperand(0)->getType()->getPointerAddressSpace();
340 P2I->getOperand(0)->getType(), P2I->getType(),
342 (P2IOp0AS == I2PAS ||
TTI->isNoopAddrSpaceCast(P2IOp0AS, I2PAS));
349bool InferAddressSpacesImpl::isAddressExpression(
354 return Arg->getType()->isPointerTy() &&
361 switch (
Op->getOpcode()) {
362 case Instruction::PHI:
363 assert(
Op->getType()->isPtrOrPtrVectorTy());
365 case Instruction::BitCast:
366 case Instruction::AddrSpaceCast:
367 case Instruction::GetElementPtr:
369 case Instruction::Select:
370 return Op->getType()->isPtrOrPtrVectorTy();
371 case Instruction::Call: {
373 return II &&
II->getIntrinsicID() == Intrinsic::ptrmask;
375 case Instruction::IntToPtr:
377 isSafeToCastIntToPtrAddrSpace(
Op);
387SmallVector<Value *, 2> InferAddressSpacesImpl::getPointerOperands(
388 const Value &V,
const DataLayout &
DL,
389 const TargetTransformInfo *
TTI)
const {
394 switch (
Op.getOpcode()) {
395 case Instruction::PHI: {
397 return {IncomingValues.begin(), IncomingValues.end()};
399 case Instruction::BitCast:
400 case Instruction::AddrSpaceCast:
401 case Instruction::GetElementPtr:
402 return {
Op.getOperand(0)};
403 case Instruction::Select:
404 return {
Op.getOperand(1),
Op.getOperand(2)};
405 case Instruction::Call: {
407 assert(
II.getIntrinsicID() == Intrinsic::ptrmask &&
408 "unexpected intrinsic call");
409 return {
II.getArgOperand(0)};
411 case Instruction::IntToPtr: {
414 return {P2I->getOperand(0)};
416 assert(isSafeToCastIntToPtrAddrSpace(&
Op));
417 return {getIntToPtrPointerOperand(&
Op)};
431 switch (
Op->getOpcode()) {
432 case Instruction::Xor:
433 case Instruction::Or:
435 case Instruction::And:
443InferAddressSpacesImpl::getIntToPtrPointerOperand(
const Operator *I2P)
const {
450 if (
auto *OldPtr = PtrIntCastPairs.
lookup(I2P))
455 if (!
match(LogicalOp,
466 if (PreservedPtrMask.
isZero())
468 APInt ChangedPtrBits =
477 if (ChangedPtrBits.
isSubsetOf(PreservedPtrMask))
483void InferAddressSpacesImpl::collectIntToPtrPointerOperand() {
490 PtrIntCastPairs.
insert({&
I, OldPtr});
494bool InferAddressSpacesImpl::rewriteIntrinsicOperands(IntrinsicInst *
II,
497 Module *
M =
II->getParent()->getParent()->getParent();
500 case Intrinsic::objectsize:
501 case Intrinsic::masked_load: {
502 Type *DestTy =
II->getType();
506 II->setArgOperand(0, NewV);
507 II->setCalledFunction(NewDecl);
510 case Intrinsic::ptrmask:
513 case Intrinsic::masked_gather: {
514 Type *RetTy =
II->getType();
518 II->setArgOperand(0, NewV);
519 II->setCalledFunction(NewDecl);
522 case Intrinsic::masked_store:
523 case Intrinsic::masked_scatter: {
524 Type *ValueTy =
II->getOperand(0)->getType();
527 M,
II->getIntrinsicID(), {ValueTy, NewPtrTy});
528 II->setArgOperand(1, NewV);
529 II->setCalledFunction(NewDecl);
532 case Intrinsic::prefetch:
533 case Intrinsic::is_constant: {
535 M,
II->getIntrinsicID(), {NewV->getType()});
536 II->setArgOperand(0, NewV);
537 II->setCalledFunction(NewDecl);
540 case Intrinsic::fake_use: {
541 II->replaceUsesOfWith(OldV, NewV);
544 case Intrinsic::lifetime_start:
545 case Intrinsic::lifetime_end: {
549 M,
II->getIntrinsicID(), {NewV->getType()});
550 II->setArgOperand(0, NewV);
551 II->setCalledFunction(NewDecl);
559 II->replaceAllUsesWith(Rewrite);
565void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
566 IntrinsicInst *
II, PostorderStackTy &PostorderStack,
567 DenseSet<Value *> &Visited)
const {
568 auto IID =
II->getIntrinsicID();
570 case Intrinsic::ptrmask:
571 case Intrinsic::objectsize:
572 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
573 PostorderStack, Visited);
575 case Intrinsic::is_constant: {
576 Value *Ptr =
II->getArgOperand(0);
578 appendsFlatAddressExpressionToPostorderStack(Ptr, PostorderStack,
584 case Intrinsic::masked_load:
585 case Intrinsic::masked_gather:
586 case Intrinsic::prefetch:
587 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
588 PostorderStack, Visited);
590 case Intrinsic::masked_store:
591 case Intrinsic::masked_scatter:
592 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(1),
593 PostorderStack, Visited);
595 case Intrinsic::fake_use: {
597 if (
Op->getType()->isPtrOrPtrVectorTy()) {
598 appendsFlatAddressExpressionToPostorderStack(
Op, PostorderStack,
605 case Intrinsic::lifetime_start:
606 case Intrinsic::lifetime_end: {
607 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
608 PostorderStack, Visited);
612 SmallVector<int, 2> OpIndexes;
614 for (
int Idx : OpIndexes) {
615 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(Idx),
616 PostorderStack, Visited);
626void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
627 Value *V, PostorderStackTy &PostorderStack,
628 DenseSet<Value *> &Visited)
const {
629 assert(
V->getType()->isPtrOrPtrVectorTy());
635 if (isAddressExpression(*CE, *
DL,
TTI) && Visited.
insert(CE).second)
636 PostorderStack.emplace_back(CE,
false);
641 if (
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
642 isAddressExpression(*V, *
DL,
TTI)) {
643 if (Visited.
insert(V).second) {
644 PostorderStack.emplace_back(V,
false);
647 for (
auto &O :
Op->operands())
649 if (isAddressExpression(*CE, *
DL,
TTI) && Visited.
insert(CE).second)
650 PostorderStack.emplace_back(CE,
false);
657std::vector<WeakTrackingVH>
658InferAddressSpacesImpl::collectFlatAddressExpressions(Function &
F)
const {
661 PostorderStackTy PostorderStack;
663 DenseSet<Value *> Visited;
665 auto PushPtrOperand = [&](
Value *Ptr) {
666 appendsFlatAddressExpressionToPostorderStack(Ptr, PostorderStack, Visited);
674 PushPtrOperand(
GEP->getPointerOperand());
676 PushPtrOperand(LI->getPointerOperand());
678 PushPtrOperand(
SI->getPointerOperand());
680 PushPtrOperand(RMW->getPointerOperand());
682 PushPtrOperand(CmpX->getPointerOperand());
685 PushPtrOperand(
MI->getRawDest());
689 PushPtrOperand(MTI->getRawSource());
691 collectRewritableIntrinsicOperands(
II, PostorderStack, Visited);
693 if (
Cmp->getOperand(0)->getType()->isPtrOrPtrVectorTy()) {
694 PushPtrOperand(
Cmp->getOperand(0));
695 PushPtrOperand(
Cmp->getOperand(1));
698 PushPtrOperand(ASC->getPointerOperand());
705 if (
auto *RV = RI->getReturnValue();
706 RV && RV->getType()->isPtrOrPtrVectorTy())
711 std::vector<WeakTrackingVH> Postorder;
712 while (!PostorderStack.empty()) {
713 Value *TopVal = PostorderStack.back().getPointer();
716 if (PostorderStack.back().getInt()) {
718 Postorder.push_back(TopVal);
719 PostorderStack.pop_back();
723 PostorderStack.back().setInt(
true);
726 for (
Value *PtrOperand : getPointerOperands(*TopVal, *
DL,
TTI)) {
727 appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
739 auto InsertBefore = [NewI](
auto It) {
749 auto InsertI =
F->getEntryBlock().getFirstNonPHIIt();
750 return InsertBefore(InsertI);
760 auto InsertI = OpInst->
getParent()->getFirstNonPHIIt();
761 return InsertBefore(InsertI);
774 const Use &OperandUse,
unsigned NewAddrSpace,
776 const PredicatedAddrSpaceMapTy &PredicatedAS,
785 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand))
789 auto I = PredicatedAS.find(std::make_pair(Inst, Operand));
790 if (
I != PredicatedAS.end()) {
792 unsigned NewAS =
I->second;
810Value *InferAddressSpacesImpl::clonePtrMaskWithNewAddressSpace(
811 IntrinsicInst *
I,
unsigned NewAddrSpace,
813 const PredicatedAddrSpaceMapTy &PredicatedAS,
814 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const {
815 const Use &PtrOpUse =
I->getArgOperandUse(0);
817 Value *MaskOp =
I->getArgOperand(1);
820 KnownBits OldPtrBits{
DL->getPointerSizeInBits(OldAddrSpace)};
821 KnownBits NewPtrBits{
DL->getPointerSizeInBits(NewAddrSpace)};
823 std::tie(OldPtrBits, NewPtrBits) =
838 OldPtrBits.
One |= ~OldPtrBits.Zero;
840 KnownBits ClearedBits =
KnownBits::sub(OldPtrBits, OldPtrBits & MaskBits);
845 std::optional<BasicBlock::iterator> InsertPoint =
846 I->getInsertionPointAfterDef();
847 assert(InsertPoint &&
"insertion after ptrmask should be possible");
850 new AddrSpaceCastInst(
I, NewPtrType,
"", *InsertPoint);
852 return AddrSpaceCast;
859 MaskOp =
B.CreateTrunc(MaskOp, MaskTy);
862 PtrOpUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
864 return B.CreateIntrinsic(Intrinsic::ptrmask, {NewPtr->
getType(), MaskTy},
877Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
878 Instruction *
I,
unsigned NewAddrSpace,
880 const PredicatedAddrSpaceMapTy &PredicatedAS,
881 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const {
884 if (
I->getOpcode() == Instruction::AddrSpaceCast) {
885 Value *Src =
I->getOperand(0);
889 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
896 assert(
II->getIntrinsicID() == Intrinsic::ptrmask);
897 return clonePtrMaskWithNewAddressSpace(
898 II, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, PoisonUsesToFix);
906 auto *NewI =
new AddrSpaceCastInst(
I, NewPtrTy);
907 NewI->insertAfter(
I->getIterator());
908 NewI->setDebugLoc(
I->getDebugLoc());
913 SmallVector<Value *, 4> NewPointerOperands;
914 for (
const Use &OperandUse :
I->operands()) {
915 if (!OperandUse.get()->getType()->isPtrOrPtrVectorTy())
919 OperandUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
923 switch (
I->getOpcode()) {
924 case Instruction::BitCast:
925 return new BitCastInst(NewPointerOperands[0], NewPtrType);
926 case Instruction::PHI: {
927 assert(
I->getType()->isPtrOrPtrVectorTy());
930 for (
unsigned Index = 0;
Index <
PHI->getNumIncomingValues(); ++
Index) {
933 PHI->getIncomingBlock(Index));
937 case Instruction::GetElementPtr: {
940 GEP->getSourceElementType(), NewPointerOperands[0],
941 SmallVector<Value *, 4>(
GEP->indices()));
945 case Instruction::Select:
946 assert(
I->getType()->isPtrOrPtrVectorTy());
948 NewPointerOperands[2],
"",
nullptr,
I);
949 case Instruction::IntToPtr: {
952 if (Src->getType() == NewPtrType)
958 return new AddrSpaceCastInst(Src, NewPtrType);
961 AddrSpaceCastInst *AsCast =
new AddrSpaceCastInst(
I, NewPtrType);
973Value *InferAddressSpacesImpl::cloneConstantExprWithNewAddressSpace(
974 ConstantExpr *CE,
unsigned NewAddrSpace,
976 const TargetTransformInfo *
TTI)
const {
978 CE->getType()->isPtrOrPtrVectorTy()
982 if (
CE->getOpcode() == Instruction::AddrSpaceCast) {
986 assert(CE->getOperand(0)->getType()->getPointerAddressSpace() ==
988 return CE->getOperand(0);
991 if (
CE->getOpcode() == Instruction::BitCast) {
992 if (Value *NewOperand = ValueWithNewAddrSpace.lookup(CE->getOperand(0)))
993 return ConstantExpr::getBitCast(cast<Constant>(NewOperand), TargetType);
994 return ConstantExpr::getAddrSpaceCast(CE, TargetType);
997 if (
CE->getOpcode() == Instruction::IntToPtr) {
998 if (isNoopPtrIntCastPair(cast<Operator>(CE), *DL, TTI)) {
999 Constant *Src = cast<ConstantExpr>(CE->getOperand(0))->getOperand(0);
1000 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
1009 SmallVector<Constant *, 4> NewOperands;
1010 for (
unsigned Index = 0;
Index <
CE->getNumOperands(); ++
Index) {
1017 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand)) {
1023 if (
Value *NewOperand = cloneConstantExprWithNewAddressSpace(
1024 CExpr, NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI)) {
1038 if (
CE->getOpcode() == Instruction::GetElementPtr) {
1041 return CE->getWithOperands(NewOperands, TargetType,
false,
1045 return CE->getWithOperands(NewOperands, TargetType);
1053Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
1054 Value *V,
unsigned NewAddrSpace,
1056 const PredicatedAddrSpaceMapTy &PredicatedAS,
1057 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const {
1059 assert(
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
1060 isAddressExpression(*V, *
DL,
TTI));
1068 Type *NewPtrTy = PointerType::get(Arg->getContext(), NewAddrSpace);
1069 auto *NewI =
new AddrSpaceCastInst(Arg, NewPtrTy);
1070 NewI->insertBefore(Insert);
1075 Value *NewV = cloneInstructionWithNewAddressSpace(
1076 I, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, PoisonUsesToFix);
1078 if (NewI->getParent() ==
nullptr) {
1079 NewI->insertBefore(
I->getIterator());
1081 NewI->setDebugLoc(
I->getDebugLoc());
1087 return cloneConstantExprWithNewAddressSpace(
1093unsigned InferAddressSpacesImpl::joinAddressSpaces(
unsigned AS1,
1094 unsigned AS2)
const {
1095 if (AS1 == FlatAddrSpace || AS2 == FlatAddrSpace)
1096 return FlatAddrSpace;
1104 return (AS1 == AS2) ? AS1 : FlatAddrSpace;
1107bool InferAddressSpacesImpl::run(Function &CurFn) {
1109 DL = &
F->getDataLayout();
1110 PtrIntCastPairs.
clear();
1121 collectIntToPtrPointerOperand();
1123 std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions(*
F);
1127 ValueToAddrSpaceMapTy InferredAddrSpace;
1128 PredicatedAddrSpaceMapTy PredicatedAS;
1129 inferAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS);
1133 return rewriteWithNewAddressSpaces(Postorder, InferredAddrSpace,
1139void InferAddressSpacesImpl::inferAddressSpaces(
1141 ValueToAddrSpaceMapTy &InferredAddrSpace,
1142 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1145 for (
Value *V : Postorder)
1148 while (!Worklist.empty()) {
1149 Value *
V = Worklist.pop_back_val();
1153 if (!updateAddressSpace(*V, InferredAddrSpace, PredicatedAS))
1156 for (
Value *User :
V->users()) {
1158 if (Worklist.count(User))
1161 auto Pos = InferredAddrSpace.find(User);
1164 if (Pos == InferredAddrSpace.end())
1170 if (Pos->second == FlatAddrSpace)
1173 Worklist.insert(User);
1179InferAddressSpacesImpl::getPredicatedAddrSpace(
const Value &Ptr,
1180 const Value *UserCtx)
const {
1203bool InferAddressSpacesImpl::updateAddressSpace(
1204 const Value &V, ValueToAddrSpaceMapTy &InferredAddrSpace,
1205 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1206 assert(InferredAddrSpace.count(&V));
1208 LLVM_DEBUG(
dbgs() <<
"Updating the address space of\n " << V <<
'\n');
1224 SmallVector<Value *, 2> PtrOps = getPointerOperands(V, *
DL,
TTI);
1225 for (
Value *PtrOperand : PtrOps) {
1226 auto I = InferredAddrSpace.find(PtrOperand);
1228 if (
I == InferredAddrSpace.end()) {
1229 OperandAS = PtrOperand->getType()->getPointerAddressSpace();
1231 C && OperandAS == FlatAddrSpace) {
1236 if (OperandAS == FlatAddrSpace) {
1238 unsigned AS = getPredicatedAddrSpace(*PtrOperand, &V);
1241 <<
" deduce operand AS from the predicate addrspace "
1245 PredicatedAS[std::make_pair(&V, PtrOperand)] = OperandAS;
1249 OperandAS =
I->second;
1252 NewAS = joinAddressSpaces(NewAS, OperandAS);
1253 if (NewAS == FlatAddrSpace)
1258 if (
any_of(ConstantPtrOps, [=](Constant *
C) {
1259 return !isSafeToCastConstAddrSpace(
C, NewAS);
1261 NewAS = FlatAddrSpace;
1266 PtrOps.size() == ConstantPtrOps.
size())
1267 NewAS = FlatAddrSpace;
1270 unsigned OldAS = InferredAddrSpace.lookup(&V);
1271 assert(OldAS != FlatAddrSpace);
1278 InferredAddrSpace[&
V] = NewAS;
1287 if (U.get() == OldVal) {
1295template <
typename InstrType>
1297 InstrType *MemInstr,
unsigned AddrSpace,
1299 if (!MemInstr->isVolatile() ||
TTI.hasVolatileVariant(MemInstr, AddrSpace)) {
1315 User *Inst,
unsigned AddrSpace,
1339 B.CreateMemSet(NewV, MSI->getValue(), MSI->getLength(), MSI->getDestAlign(),
1341 MI->getAAMetadata());
1343 Value *Src = MTI->getRawSource();
1344 Value *Dest = MTI->getRawDest();
1354 if (MCI->isForceInlined())
1355 B.CreateMemCpyInline(Dest, MTI->getDestAlign(), Src,
1356 MTI->getSourceAlign(), MTI->getLength(),
1358 MI->getAAMetadata());
1360 B.CreateMemCpy(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1363 MI->getAAMetadata());
1366 B.CreateMemMove(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1369 MI->getAAMetadata());
1374 MI->eraseFromParent();
1380bool InferAddressSpacesImpl::isSafeToCastConstAddrSpace(Constant *
C,
1381 unsigned NewAS)
const {
1384 unsigned SrcAS =
C->getType()->getPointerAddressSpace();
1389 if (SrcAS != FlatAddrSpace && NewAS != FlatAddrSpace)
1398 if (
Op->getOpcode() == Instruction::AddrSpaceCast)
1402 if (
Op->getOpcode() == Instruction::IntToPtr &&
1403 Op->getType()->getPointerAddressSpace() == FlatAddrSpace)
1412 User *CurUser =
I->getUser();
1415 while (
I != End &&
I->getUser() == CurUser)
1421void InferAddressSpacesImpl::performPointerReplacement(
1423 SmallVectorImpl<Instruction *> &DeadInstructions)
const {
1425 User *CurUser =
U.getUser();
1427 unsigned AddrSpace =
V->getType()->getPointerAddressSpace();
1432 if (CurUser == NewV)
1436 if (!CurUserI || CurUserI->getFunction() !=
F)
1446 if (rewriteIntrinsicOperands(
II, V, NewV))
1458 int SrcIdx =
U.getOperandNo();
1459 int OtherIdx = (SrcIdx == 0) ? 1 : 0;
1460 Value *OtherSrc =
Cmp->getOperand(OtherIdx);
1462 if (
Value *OtherNewV = ValueWithNewAddrSpace.
lookup(OtherSrc)) {
1463 if (OtherNewV->getType()->getPointerAddressSpace() == NewAS) {
1464 Cmp->setOperand(OtherIdx, OtherNewV);
1465 Cmp->setOperand(SrcIdx, NewV);
1472 if (isSafeToCastConstAddrSpace(KOtherSrc, NewAS)) {
1473 Cmp->setOperand(SrcIdx, NewV);
1483 if (ASC->getDestAddressSpace() == NewAS) {
1484 ASC->replaceAllUsesWith(NewV);
1499 InsertPos = std::next(NewVInst->getIterator());
1507 V,
new AddrSpaceCastInst(NewV,
V->getType(),
"", InsertPos));
1509 CurUserI->replaceUsesOfWith(
1514bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
1516 const ValueToAddrSpaceMapTy &InferredAddrSpace,
1517 const PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1524 for (
Value *V : Postorder) {
1525 unsigned NewAddrSpace = InferredAddrSpace.lookup(V);
1532 if (
V->getType()->getPointerAddressSpace() != NewAddrSpace) {
1534 cloneValueWithNewAddressSpace(V, NewAddrSpace, ValueWithNewAddrSpace,
1535 PredicatedAS, &PoisonUsesToFix);
1537 ValueWithNewAddrSpace[
V] =
New;
1541 if (ValueWithNewAddrSpace.
empty())
1545 for (
const Use *PoisonUse : PoisonUsesToFix) {
1546 User *
V = PoisonUse->getUser();
1551 unsigned OperandNo = PoisonUse->getOperandNo();
1553 WeakTrackingVH NewOp = ValueWithNewAddrSpace.
lookup(PoisonUse->get());
1555 "poison replacements in ValueWithNewAddrSpace shouldn't be null");
1559 SmallVector<Instruction *, 16> DeadInstructions;
1564 for (
const WeakTrackingVH &WVH : Postorder) {
1565 assert(WVH &&
"value was unexpectedly deleted");
1568 if (NewV ==
nullptr)
1571 LLVM_DEBUG(
dbgs() <<
"Replacing the uses of " << *V <<
"\n with\n "
1578 LLVM_DEBUG(
dbgs() <<
"Inserting replacement const cast: " << Replace
1579 <<
": " << *Replace <<
'\n');
1583 if (
I->getFunction() ==
F)
1584 I->replaceUsesOfWith(
C, Replace);
1586 WorkList.
append(
U->user_begin(),
U->user_end());
1589 if (!WorkList.
empty()) {
1591 DenseSet<User *> Visited{WorkList.
begin(), WorkList.
end()};
1592 while (!WorkList.
empty()) {
1595 if (
I->getFunction() ==
F)
1596 VMapper.remapInstruction(*
I);
1599 for (User *U2 :
U->users())
1600 if (Visited.
insert(U2).second)
1608 Value::use_iterator
I,
E,
Next;
1609 for (
I =
V->use_begin(),
E =
V->use_end();
I !=
E;) {
1616 performPointerReplacement(V, NewV, U, ValueWithNewAddrSpace,
1620 if (
V->use_empty()) {
1626 for (Instruction *
I : DeadInstructions)
1632bool InferAddressSpaces::runOnFunction(Function &
F) {
1633 if (skipFunction(
F))
1636 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
1637 DominatorTree *DT = DTWP ? &DTWP->getDomTree() :
nullptr;
1638 return InferAddressSpacesImpl(
1639 getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F), DT,
1640 &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 handleMemIntrinsicPtrUse(MemIntrinsic *MI, Value *OldV, Value *NewV)
Update memory intrinsic uses that require more complex processing than simple memory instructions.
static Value * operandWithNewAddressSpaceOrCreatePoison(const Use &OperandUse, unsigned NewAddrSpace, const ValueToValueMapTy &ValueWithNewAddrSpace, const PredicatedAddrSpaceMapTy &PredicatedAS, SmallVectorImpl< const Use * > *PoisonUsesToFix)
static Value::use_iterator skipToNextUser(Value::use_iterator I, Value::use_iterator End)
Infer address static false Type * getPtrOrVecOfPtrsWithNewAS(Type *Ty, unsigned NewAddrSpace)
static APInt computeMaxChangedPtrBits(const Operator *Op, const Value *Mask, const DataLayout &DL, AssumptionCache *AC, const DominatorTree *DT)
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.
static SymbolRef::Type getType(const Symbol *Sym)
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
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:
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.
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.
static LLVM_ABI Constant * getAddrSpaceCast(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.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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.
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.
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.
bool isVectorTy() const
True if this is an instance of VectorType.
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.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
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.
bool match(Val *V, const Pattern &P)
BinOpPred_match< LHS, RHS, is_bitwiselogic_op, true > m_c_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations in either order.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
CastOperator_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
@ CE
Windows NT (Windows on ARM)
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.