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 {
188class InferAddressSpacesImpl {
191 const DominatorTree *DT =
nullptr;
192 const TargetTransformInfo *TTI =
nullptr;
193 const DataLayout *DL =
nullptr;
197 unsigned FlatAddrSpace = 0;
198 DenseMap<const Value *, Value *> PtrIntCastPairs;
203 Value *getIntToPtrPointerOperand(
const Operator *I2P)
const;
208 void collectIntToPtrPointerOperand();
212 bool isSafeToCastIntToPtrAddrSpace(
const Operator *I2P)
const {
213 return PtrIntCastPairs.contains(I2P);
215 bool isAddressExpression(
const Value &V,
const DataLayout &DL,
216 const TargetTransformInfo *TTI)
const;
217 Value *cloneConstantExprWithNewAddressSpace(
218 ConstantExpr *CE,
unsigned NewAddrSpace,
220 const TargetTransformInfo *TTI)
const;
222 SmallVector<Value *, 2>
223 getPointerOperands(
const Value &V,
const DataLayout &DL,
224 const TargetTransformInfo *TTI)
const;
228 bool updateAddressSpace(
const Value &V,
229 ValueToAddrSpaceMapTy &InferredAddrSpace,
230 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
233 void enqueueUsers(
Value &V,
const ValueToAddrSpaceMapTy &InferredAddrSpace,
234 SetVector<Value *> &Worklist)
const;
237 void runToFixPoint(SetVector<Value *> &Worklist,
238 ValueToAddrSpaceMapTy &InferredAddrSpace,
239 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
244 ValueToAddrSpaceMapTy &InferredAddrSpace,
245 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
247 bool isSafeToCastConstAddrSpace(Constant *
C,
unsigned NewAS)
const;
249 Value *clonePtrMaskWithNewAddressSpace(
250 IntrinsicInst *
I,
unsigned NewAddrSpace,
252 const PredicatedAddrSpaceMapTy &PredicatedAS,
253 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const;
255 Value *cloneInstructionWithNewAddressSpace(
256 Instruction *
I,
unsigned NewAddrSpace,
258 const PredicatedAddrSpaceMapTy &PredicatedAS,
259 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const;
261 void performPointerReplacement(
263 SmallVectorImpl<Instruction *> &DeadInstructions)
const;
268 bool rewriteWithNewAddressSpaces(
270 const ValueToAddrSpaceMapTy &InferredAddrSpace,
271 const PredicatedAddrSpaceMapTy &PredicatedAS)
const;
273 void appendsFlatAddressExpressionToPostorderStack(
274 Value *V, PostorderStackTy &PostorderStack,
275 DenseSet<Value *> &Visited)
const;
277 bool rewriteIntrinsicOperands(IntrinsicInst *
II,
Value *OldV,
279 void collectRewritableIntrinsicOperands(IntrinsicInst *
II,
280 PostorderStackTy &PostorderStack,
281 DenseSet<Value *> &Visited)
const;
283 std::vector<WeakTrackingVH> collectFlatAddressExpressions(
Function &F)
const;
285 Value *cloneValueWithNewAddressSpace(
286 Value *V,
unsigned NewAddrSpace,
288 const PredicatedAddrSpaceMapTy &PredicatedAS,
289 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const;
290 unsigned joinAddressSpaces(
unsigned AS1,
unsigned AS2)
const;
292 unsigned getPredicatedAddrSpace(
const Value &PtrV,
293 const Value *UserCtx)
const;
296 InferAddressSpacesImpl(AssumptionCache &AC,
const DominatorTree *DT,
297 const TargetTransformInfo *TTI,
unsigned FlatAddrSpace)
298 : AC(AC), DT(DT), TTI(TTI), FlatAddrSpace(FlatAddrSpace) {}
304char InferAddressSpaces::ID = 0;
314 assert(Ty->isPtrOrPtrVectorTy());
316 return Ty->getWithNewType(NPT);
326 if (!P2I || P2I->getOpcode() != Instruction::PtrToInt)
342 unsigned P2IOp0AS = P2I->getOperand(0)->getType()->getPointerAddressSpace();
348 P2I->getOperand(0)->getType(), P2I->getType(),
350 (P2IOp0AS == I2PAS ||
TTI->isNoopAddrSpaceCast(P2IOp0AS, I2PAS));
357bool InferAddressSpacesImpl::isAddressExpression(
362 return Arg->getType()->isPointerTy() &&
369 switch (
Op->getOpcode()) {
370 case Instruction::PHI:
371 assert(
Op->getType()->isPtrOrPtrVectorTy());
373 case Instruction::BitCast:
374 case Instruction::AddrSpaceCast:
375 case Instruction::GetElementPtr:
377 case Instruction::Select:
378 return Op->getType()->isPtrOrPtrVectorTy();
379 case Instruction::Call: {
381 return II &&
II->getIntrinsicID() == Intrinsic::ptrmask;
383 case Instruction::IntToPtr:
385 isSafeToCastIntToPtrAddrSpace(
Op);
395SmallVector<Value *, 2> InferAddressSpacesImpl::getPointerOperands(
396 const Value &V,
const DataLayout &
DL,
397 const TargetTransformInfo *
TTI)
const {
402 switch (
Op.getOpcode()) {
403 case Instruction::PHI: {
405 return {IncomingValues.begin(), IncomingValues.end()};
407 case Instruction::BitCast:
408 case Instruction::AddrSpaceCast:
409 case Instruction::GetElementPtr:
410 return {
Op.getOperand(0)};
411 case Instruction::Select:
412 return {
Op.getOperand(1),
Op.getOperand(2)};
413 case Instruction::Call: {
415 assert(
II.getIntrinsicID() == Intrinsic::ptrmask &&
416 "unexpected intrinsic call");
417 return {
II.getArgOperand(0)};
419 case Instruction::IntToPtr: {
422 return {P2I->getOperand(0)};
424 assert(isSafeToCastIntToPtrAddrSpace(&
Op));
425 return {getIntToPtrPointerOperand(&
Op)};
439 switch (
Op->getOpcode()) {
440 case Instruction::Xor:
441 case Instruction::Or:
443 case Instruction::And:
451InferAddressSpacesImpl::getIntToPtrPointerOperand(
const Operator *I2P)
const {
458 if (
auto *OldPtr = PtrIntCastPairs.
lookup(I2P))
463 if (!
match(LogicalOp,
474 if (PreservedPtrMask.
isZero())
476 APInt ChangedPtrBits =
485 if (ChangedPtrBits.
isSubsetOf(PreservedPtrMask))
491void InferAddressSpacesImpl::collectIntToPtrPointerOperand() {
498 PtrIntCastPairs.
insert({&
I, OldPtr});
502bool InferAddressSpacesImpl::rewriteIntrinsicOperands(IntrinsicInst *
II,
505 Module *
M =
II->getParent()->getParent()->getParent();
508 case Intrinsic::objectsize:
509 case Intrinsic::masked_load: {
510 Type *DestTy =
II->getType();
514 II->setArgOperand(0, NewV);
515 II->setCalledFunction(NewDecl);
518 case Intrinsic::ptrmask:
521 case Intrinsic::masked_gather: {
522 Type *RetTy =
II->getType();
526 II->setArgOperand(0, NewV);
527 II->setCalledFunction(NewDecl);
530 case Intrinsic::masked_store:
531 case Intrinsic::masked_scatter: {
532 Type *ValueTy =
II->getOperand(0)->getType();
535 M,
II->getIntrinsicID(), {ValueTy, NewPtrTy});
536 II->setArgOperand(1, NewV);
537 II->setCalledFunction(NewDecl);
540 case Intrinsic::prefetch:
541 case Intrinsic::is_constant: {
543 M,
II->getIntrinsicID(), {NewV->getType()});
544 II->setArgOperand(0, NewV);
545 II->setCalledFunction(NewDecl);
548 case Intrinsic::fake_use: {
549 II->replaceUsesOfWith(OldV, NewV);
552 case Intrinsic::lifetime_start:
553 case Intrinsic::lifetime_end: {
557 M,
II->getIntrinsicID(), {NewV->getType()});
558 II->setArgOperand(0, NewV);
559 II->setCalledFunction(NewDecl);
567 II->replaceAllUsesWith(Rewrite);
573void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
574 IntrinsicInst *
II, PostorderStackTy &PostorderStack,
575 DenseSet<Value *> &Visited)
const {
576 auto IID =
II->getIntrinsicID();
578 case Intrinsic::ptrmask:
579 case Intrinsic::objectsize:
580 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
581 PostorderStack, Visited);
583 case Intrinsic::is_constant: {
584 Value *Ptr =
II->getArgOperand(0);
586 appendsFlatAddressExpressionToPostorderStack(Ptr, PostorderStack,
592 case Intrinsic::masked_load:
593 case Intrinsic::masked_gather:
594 case Intrinsic::prefetch:
595 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
596 PostorderStack, Visited);
598 case Intrinsic::masked_store:
599 case Intrinsic::masked_scatter:
600 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(1),
601 PostorderStack, Visited);
603 case Intrinsic::fake_use: {
605 if (
Op->getType()->isPtrOrPtrVectorTy()) {
606 appendsFlatAddressExpressionToPostorderStack(
Op, PostorderStack,
613 case Intrinsic::lifetime_start:
614 case Intrinsic::lifetime_end: {
615 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
616 PostorderStack, Visited);
620 SmallVector<int, 2> OpIndexes;
622 for (
int Idx : OpIndexes) {
623 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(Idx),
624 PostorderStack, Visited);
634void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
635 Value *V, PostorderStackTy &PostorderStack,
636 DenseSet<Value *> &Visited)
const {
637 assert(
V->getType()->isPtrOrPtrVectorTy());
643 if (isAddressExpression(*CE, *
DL,
TTI) && Visited.
insert(CE).second)
644 PostorderStack.emplace_back(CE,
false);
649 if (
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
650 isAddressExpression(*V, *
DL,
TTI)) {
651 if (Visited.
insert(V).second) {
652 PostorderStack.emplace_back(V,
false);
655 for (
auto &O :
Op->operands())
657 if (isAddressExpression(*CE, *
DL,
TTI) && Visited.
insert(CE).second)
658 PostorderStack.emplace_back(CE,
false);
665std::vector<WeakTrackingVH>
666InferAddressSpacesImpl::collectFlatAddressExpressions(
Function &
F)
const {
669 PostorderStackTy PostorderStack;
671 DenseSet<Value *> Visited;
673 auto PushPtrOperand = [&](
Value *Ptr) {
674 appendsFlatAddressExpressionToPostorderStack(Ptr, PostorderStack, Visited);
682 PushPtrOperand(
GEP->getPointerOperand());
684 PushPtrOperand(LI->getPointerOperand());
686 PushPtrOperand(
SI->getPointerOperand());
688 PushPtrOperand(RMW->getPointerOperand());
690 PushPtrOperand(CmpX->getPointerOperand());
693 PushPtrOperand(
MI->getRawDest());
697 PushPtrOperand(MTI->getRawSource());
699 collectRewritableIntrinsicOperands(
II, PostorderStack, Visited);
701 if (
Cmp->getOperand(0)->getType()->isPtrOrPtrVectorTy()) {
702 PushPtrOperand(
Cmp->getOperand(0));
703 PushPtrOperand(
Cmp->getOperand(1));
706 PushPtrOperand(ASC->getPointerOperand());
713 if (
auto *RV = RI->getReturnValue();
714 RV && RV->getType()->isPtrOrPtrVectorTy())
719 std::vector<WeakTrackingVH> Postorder;
720 while (!PostorderStack.empty()) {
721 Value *TopVal = PostorderStack.back().getPointer();
724 if (PostorderStack.back().getInt()) {
726 Postorder.push_back(TopVal);
727 PostorderStack.pop_back();
731 PostorderStack.back().setInt(
true);
734 for (
Value *PtrOperand : getPointerOperands(*TopVal, *
DL,
TTI)) {
735 appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
747 auto InsertBefore = [NewI](
auto It) {
757 auto InsertI =
F->getEntryBlock().getFirstNonPHIIt();
758 return InsertBefore(InsertI);
768 auto InsertI = OpInst->
getParent()->getFirstNonPHIIt();
769 return InsertBefore(InsertI);
782 const Use &OperandUse,
unsigned NewAddrSpace,
784 const PredicatedAddrSpaceMapTy &PredicatedAS,
793 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand))
797 auto I = PredicatedAS.find(std::make_pair(Inst, Operand));
798 if (
I != PredicatedAS.end()) {
800 unsigned NewAS =
I->second;
818Value *InferAddressSpacesImpl::clonePtrMaskWithNewAddressSpace(
819 IntrinsicInst *
I,
unsigned NewAddrSpace,
821 const PredicatedAddrSpaceMapTy &PredicatedAS,
822 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const {
823 const Use &PtrOpUse =
I->getArgOperandUse(0);
825 Value *MaskOp =
I->getArgOperand(1);
828 KnownBits OldPtrBits{
DL->getPointerSizeInBits(OldAddrSpace)};
829 KnownBits NewPtrBits{
DL->getPointerSizeInBits(NewAddrSpace)};
831 std::tie(OldPtrBits, NewPtrBits) =
846 OldPtrBits.
One |= ~OldPtrBits.Zero;
848 KnownBits ClearedBits =
KnownBits::sub(OldPtrBits, OldPtrBits & MaskBits);
853 std::optional<BasicBlock::iterator> InsertPoint =
854 I->getInsertionPointAfterDef();
855 assert(InsertPoint &&
"insertion after ptrmask should be possible");
858 new AddrSpaceCastInst(
I, NewPtrType,
"", *InsertPoint);
860 return AddrSpaceCast;
867 MaskOp =
B.CreateTrunc(MaskOp, MaskTy);
870 PtrOpUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
872 return B.CreateIntrinsic(Intrinsic::ptrmask, {NewPtr->
getType(), MaskTy},
885Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
886 Instruction *
I,
unsigned NewAddrSpace,
888 const PredicatedAddrSpaceMapTy &PredicatedAS,
889 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const {
892 if (
I->getOpcode() == Instruction::AddrSpaceCast) {
893 Value *Src =
I->getOperand(0);
897 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
904 assert(
II->getIntrinsicID() == Intrinsic::ptrmask);
905 return clonePtrMaskWithNewAddressSpace(
906 II, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, PoisonUsesToFix);
914 auto *NewI =
new AddrSpaceCastInst(
I, NewPtrTy);
915 NewI->insertAfter(
I->getIterator());
916 NewI->setDebugLoc(
I->getDebugLoc());
921 SmallVector<Value *, 4> NewPointerOperands;
922 for (
const Use &OperandUse :
I->operands()) {
923 if (!OperandUse.get()->getType()->isPtrOrPtrVectorTy())
927 OperandUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
931 switch (
I->getOpcode()) {
932 case Instruction::BitCast:
933 return new BitCastInst(NewPointerOperands[0], NewPtrType);
934 case Instruction::PHI: {
935 assert(
I->getType()->isPtrOrPtrVectorTy());
938 for (
unsigned Index = 0;
Index <
PHI->getNumIncomingValues(); ++
Index) {
941 PHI->getIncomingBlock(Index));
945 case Instruction::GetElementPtr: {
948 GEP->getSourceElementType(), NewPointerOperands[0],
949 SmallVector<Value *, 4>(
GEP->indices()));
953 case Instruction::Select:
954 assert(
I->getType()->isPtrOrPtrVectorTy());
956 NewPointerOperands[2],
"",
nullptr,
I);
957 case Instruction::IntToPtr: {
960 if (Src->getType() == NewPtrType)
966 return new AddrSpaceCastInst(Src, NewPtrType);
969 AddrSpaceCastInst *AsCast =
new AddrSpaceCastInst(
I, NewPtrType);
981Value *InferAddressSpacesImpl::cloneConstantExprWithNewAddressSpace(
982 ConstantExpr *CE,
unsigned NewAddrSpace,
984 const TargetTransformInfo *
TTI)
const {
986 CE->getType()->isPtrOrPtrVectorTy()
990 if (
CE->getOpcode() == Instruction::AddrSpaceCast) {
994 assert(CE->getOperand(0)->getType()->getPointerAddressSpace() ==
996 return CE->getOperand(0);
999 if (
CE->getOpcode() == Instruction::BitCast) {
1000 if (Value *NewOperand = ValueWithNewAddrSpace.lookup(CE->getOperand(0)))
1001 return ConstantExpr::getBitCast(cast<Constant>(NewOperand), TargetType);
1002 return ConstantExpr::getAddrSpaceCast(CE, TargetType);
1005 if (
CE->getOpcode() == Instruction::IntToPtr) {
1006 if (isNoopPtrIntCastPair(cast<Operator>(CE), *DL, TTI)) {
1007 Constant *Src = cast<ConstantExpr>(CE->getOperand(0))->getOperand(0);
1008 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
1017 SmallVector<Constant *, 4> NewOperands;
1018 for (
unsigned Index = 0;
Index <
CE->getNumOperands(); ++
Index) {
1025 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand)) {
1031 if (
Value *NewOperand = cloneConstantExprWithNewAddressSpace(
1032 CExpr, NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI)) {
1046 if (
CE->getOpcode() == Instruction::GetElementPtr) {
1049 return CE->getWithOperands(NewOperands, TargetType,
false,
1053 return CE->getWithOperands(NewOperands, TargetType);
1061Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
1062 Value *V,
unsigned NewAddrSpace,
1064 const PredicatedAddrSpaceMapTy &PredicatedAS,
1065 SmallVectorImpl<const Use *> *PoisonUsesToFix)
const {
1067 assert(
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
1068 isAddressExpression(*V, *
DL,
TTI));
1076 Type *NewPtrTy = PointerType::get(Arg->getContext(), NewAddrSpace);
1077 auto *NewI =
new AddrSpaceCastInst(Arg, NewPtrTy);
1078 NewI->insertBefore(Insert);
1083 Value *NewV = cloneInstructionWithNewAddressSpace(
1084 I, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, PoisonUsesToFix);
1086 if (NewI->getParent() ==
nullptr) {
1087 NewI->insertBefore(
I->getIterator());
1089 NewI->setDebugLoc(
I->getDebugLoc());
1095 return cloneConstantExprWithNewAddressSpace(
1101unsigned InferAddressSpacesImpl::joinAddressSpaces(
unsigned AS1,
1102 unsigned AS2)
const {
1103 if (AS1 == FlatAddrSpace || AS2 == FlatAddrSpace)
1115bool InferAddressSpacesImpl::run(
Function &CurFn) {
1117 DL = &
F->getDataLayout();
1118 PtrIntCastPairs.
clear();
1129 collectIntToPtrPointerOperand();
1131 std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions(*
F);
1135 ValueToAddrSpaceMapTy InferredAddrSpace;
1136 PredicatedAddrSpaceMapTy PredicatedAS;
1137 inferAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS);
1141 return rewriteWithNewAddressSpaces(Postorder, InferredAddrSpace,
1145void InferAddressSpacesImpl::enqueueUsers(
1146 Value &V,
const ValueToAddrSpaceMapTy &InferredAddrSpace,
1147 SetVector<Value *> &Worklist)
const {
1148 for (
Value *User :
V.users()) {
1150 if (Worklist.
count(User))
1153 ValueToAddrSpaceMapTy::const_iterator Pos = InferredAddrSpace.find(User);
1156 if (Pos == InferredAddrSpace.end())
1162 if (Pos->second == FlatAddrSpace)
1169void InferAddressSpacesImpl::runToFixPoint(
1170 SetVector<Value *> &Worklist, ValueToAddrSpaceMapTy &InferredAddrSpace,
1171 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1172 while (!Worklist.
empty()) {
1177 if (!updateAddressSpace(*V, InferredAddrSpace, PredicatedAS))
1180 enqueueUsers(*V, InferredAddrSpace, Worklist);
1186void InferAddressSpacesImpl::inferAddressSpaces(
1188 ValueToAddrSpaceMapTy &InferredAddrSpace,
1189 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1192 for (
Value *V : Postorder)
1195 runToFixPoint(Worklist, InferredAddrSpace, PredicatedAS);
1201 SmallVector<Value *, 4> Lowered;
1202 for (
Value *V : Postorder) {
1203 ValueToAddrSpaceMapTy::iterator
I = InferredAddrSpace.find(V);
1210 for (
Value *V : Lowered)
1211 enqueueUsers(*V, InferredAddrSpace, Worklist);
1213 runToFixPoint(Worklist, InferredAddrSpace, PredicatedAS);
1217InferAddressSpacesImpl::getPredicatedAddrSpace(
const Value &Ptr,
1218 const Value *UserCtx)
const {
1241bool InferAddressSpacesImpl::updateAddressSpace(
1242 const Value &V, ValueToAddrSpaceMapTy &InferredAddrSpace,
1243 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1244 assert(InferredAddrSpace.count(&V));
1246 LLVM_DEBUG(
dbgs() <<
"Updating the address space of\n " << V <<
'\n');
1262 SmallVector<Value *, 2> PtrOps = getPointerOperands(V, *
DL,
TTI);
1263 for (
Value *PtrOperand : PtrOps) {
1264 auto I = InferredAddrSpace.find(PtrOperand);
1266 if (
I == InferredAddrSpace.end()) {
1267 OperandAS = PtrOperand->getType()->getPointerAddressSpace();
1274 if (OperandAS == FlatAddrSpace) {
1276 unsigned AS = getPredicatedAddrSpace(*PtrOperand, &V);
1279 <<
" deduce operand AS from the predicate addrspace "
1283 PredicatedAS[std::make_pair(&V, PtrOperand)] = OperandAS;
1287 OperandAS =
I->second;
1290 NewAS = joinAddressSpaces(NewAS, OperandAS);
1291 if (NewAS == FlatAddrSpace)
1296 if (
any_of(ConstantPtrOps, [=](Constant *
C) {
1297 return !isSafeToCastConstAddrSpace(
C, NewAS);
1299 NewAS = FlatAddrSpace;
1304 PtrOps.size() == ConstantPtrOps.
size())
1308 unsigned OldAS = InferredAddrSpace.lookup(&V);
1309 assert(OldAS != FlatAddrSpace);
1316 InferredAddrSpace[&
V] = NewAS;
1325 if (U.get() == OldVal) {
1333template <
typename InstrType>
1335 InstrType *MemInstr,
unsigned AddrSpace,
1337 if (!MemInstr->isVolatile() ||
TTI.hasVolatileVariant(MemInstr, AddrSpace)) {
1353 User *Inst,
unsigned AddrSpace,
1377 B.CreateMemSet(NewV, MSI->getValue(), MSI->getLength(), MSI->getDestAlign(),
1379 MI->getAAMetadata());
1381 Value *Src = MTI->getRawSource();
1382 Value *Dest = MTI->getRawDest();
1392 if (MCI->isForceInlined())
1393 B.CreateMemCpyInline(Dest, MTI->getDestAlign(), Src,
1394 MTI->getSourceAlign(), MTI->getLength(),
1396 MI->getAAMetadata());
1398 B.CreateMemCpy(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1401 MI->getAAMetadata());
1404 B.CreateMemMove(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1407 MI->getAAMetadata());
1412 MI->eraseFromParent();
1418bool InferAddressSpacesImpl::isSafeToCastConstAddrSpace(Constant *
C,
1419 unsigned NewAS)
const {
1422 unsigned SrcAS =
C->getType()->getPointerAddressSpace();
1427 if (SrcAS != FlatAddrSpace && NewAS != FlatAddrSpace)
1436 if (
Op->getOpcode() == Instruction::AddrSpaceCast)
1440 if (
Op->getOpcode() == Instruction::IntToPtr &&
1441 Op->getType()->getPointerAddressSpace() == FlatAddrSpace)
1450 User *CurUser =
I->getUser();
1453 while (
I != End &&
I->getUser() == CurUser)
1459void InferAddressSpacesImpl::performPointerReplacement(
1461 SmallVectorImpl<Instruction *> &DeadInstructions)
const {
1463 User *CurUser =
U.getUser();
1465 unsigned AddrSpace =
V->getType()->getPointerAddressSpace();
1470 if (CurUser == NewV)
1474 if (!CurUserI || CurUserI->getFunction() !=
F)
1484 if (rewriteIntrinsicOperands(
II, V, NewV))
1496 int SrcIdx =
U.getOperandNo();
1497 int OtherIdx = (SrcIdx == 0) ? 1 : 0;
1498 Value *OtherSrc =
Cmp->getOperand(OtherIdx);
1500 if (
Value *OtherNewV = ValueWithNewAddrSpace.
lookup(OtherSrc)) {
1501 if (OtherNewV->getType()->getPointerAddressSpace() == NewAS) {
1502 Cmp->setOperand(OtherIdx, OtherNewV);
1503 Cmp->setOperand(SrcIdx, NewV);
1510 if (isSafeToCastConstAddrSpace(KOtherSrc, NewAS)) {
1511 Cmp->setOperand(SrcIdx, NewV);
1521 if (ASC->getDestAddressSpace() == NewAS) {
1522 ASC->replaceAllUsesWith(NewV);
1537 InsertPos = std::next(NewVInst->getIterator());
1545 V,
new AddrSpaceCastInst(NewV,
V->getType(),
"", InsertPos));
1547 CurUserI->replaceUsesOfWith(
1552bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
1554 const ValueToAddrSpaceMapTy &InferredAddrSpace,
1555 const PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1562 for (
Value *V : Postorder) {
1563 unsigned NewAddrSpace = InferredAddrSpace.lookup(V);
1570 if (
V->getType()->getPointerAddressSpace() != NewAddrSpace) {
1572 cloneValueWithNewAddressSpace(V, NewAddrSpace, ValueWithNewAddrSpace,
1573 PredicatedAS, &PoisonUsesToFix);
1575 ValueWithNewAddrSpace[
V] =
New;
1579 if (ValueWithNewAddrSpace.
empty())
1583 for (
const Use *PoisonUse : PoisonUsesToFix) {
1584 User *
V = PoisonUse->getUser();
1589 unsigned OperandNo = PoisonUse->getOperandNo();
1591 WeakTrackingVH NewOp = ValueWithNewAddrSpace.
lookup(PoisonUse->get());
1593 "poison replacements in ValueWithNewAddrSpace shouldn't be null");
1597 SmallVector<Instruction *, 16> DeadInstructions;
1602 for (
const WeakTrackingVH &WVH : Postorder) {
1603 assert(WVH &&
"value was unexpectedly deleted");
1606 if (NewV ==
nullptr)
1609 LLVM_DEBUG(
dbgs() <<
"Replacing the uses of " << *V <<
"\n with\n "
1621 if (
I->getFunction() ==
F)
1624 WorkList.
append(
U->user_begin(),
U->user_end());
1627 if (!WorkList.
empty()) {
1629 DenseSet<User *> Visited{WorkList.
begin(), WorkList.
end()};
1630 while (!WorkList.
empty()) {
1633 if (
I->getFunction() ==
F)
1634 VMapper.remapInstruction(*
I);
1637 for (User *U2 :
U->users())
1638 if (Visited.
insert(U2).second)
1646 Value::use_iterator
I,
E,
Next;
1647 for (
I =
V->use_begin(),
E =
V->use_end();
I !=
E;) {
1654 performPointerReplacement(V, NewV, U, ValueWithNewAddrSpace,
1658 if (
V->use_empty()) {
1664 for (Instruction *
I : DeadInstructions)
1670bool InferAddressSpaces::runOnFunction(
Function &
F) {
1671 if (skipFunction(
F))
1674 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
1675 DominatorTree *DT = DTWP ? &DTWP->getDomTree() :
nullptr;
1676 return InferAddressSpacesImpl(
1677 getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F), DT,
1678 &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F),
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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
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()
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
Return the entry for the specified key, or a default constructed value if no such entry exists.
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(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object 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.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
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.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
BinOpPred_match< LHS, RHS, is_bitwiselogic_op, true > m_c_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations in either order.
CastOperator_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
DXILDebugInfoMap run(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.
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.
@ Known
Known to have no common set bits.
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)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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 >
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI InferAddressSpacesPass()
LLVM_ABI 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.