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) {
184class InferAddressSpacesImpl {
193 unsigned FlatAddrSpace = 0;
197 bool updateAddressSpace(
const Value &V,
198 ValueToAddrSpaceMapTy &InferredAddrSpace,
199 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
204 ValueToAddrSpaceMapTy &InferredAddrSpace,
205 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
207 bool isSafeToCastConstAddrSpace(
Constant *
C,
unsigned NewAS)
const;
209 Value *cloneInstructionWithNewAddressSpace(
212 const PredicatedAddrSpaceMapTy &PredicatedAS,
215 void performPointerReplacement(
222 bool rewriteWithNewAddressSpaces(
224 const ValueToAddrSpaceMapTy &InferredAddrSpace,
225 const PredicatedAddrSpaceMapTy &PredicatedAS)
const;
227 void appendsFlatAddressExpressionToPostorderStack(
228 Value *V, PostorderStackTy &PostorderStack,
234 PostorderStackTy &PostorderStack,
237 std::vector<WeakTrackingVH> collectFlatAddressExpressions(
Function &F)
const;
239 Value *cloneValueWithNewAddressSpace(
240 Value *V,
unsigned NewAddrSpace,
242 const PredicatedAddrSpaceMapTy &PredicatedAS,
244 unsigned joinAddressSpaces(
unsigned AS1,
unsigned AS2)
const;
246 unsigned getPredicatedAddrSpace(
const Value &PtrV,
247 const Value *UserCtx)
const;
252 : AC(AC), DT(DT),
TTI(
TTI), FlatAddrSpace(FlatAddrSpace) {}
258char InferAddressSpaces::ID = 0;
268 assert(Ty->isPtrOrPtrVectorTy());
269 PointerType *NPT = PointerType::get(Ty->getContext(), NewAddrSpace);
270 return Ty->getWithNewType(NPT);
279 auto *P2I = dyn_cast<Operator>(I2P->
getOperand(0));
280 if (!P2I || P2I->getOpcode() != Instruction::PtrToInt)
296 unsigned P2IOp0AS = P2I->getOperand(0)->getType()->getPointerAddressSpace();
302 P2I->getOperand(0)->getType(), P2I->getType(),
314 if (
const Argument *Arg = dyn_cast<Argument>(&V))
315 return Arg->getType()->isPointerTy() &&
322 switch (
Op->getOpcode()) {
323 case Instruction::PHI:
324 assert(
Op->getType()->isPtrOrPtrVectorTy());
326 case Instruction::BitCast:
327 case Instruction::AddrSpaceCast:
328 case Instruction::GetElementPtr:
330 case Instruction::Select:
331 return Op->getType()->isPtrOrPtrVectorTy();
332 case Instruction::Call: {
334 return II &&
II->getIntrinsicID() == Intrinsic::ptrmask;
336 case Instruction::IntToPtr:
350 if (isa<Argument>(&V))
354 switch (
Op.getOpcode()) {
355 case Instruction::PHI: {
356 auto IncomingValues = cast<PHINode>(
Op).incoming_values();
357 return {IncomingValues.begin(), IncomingValues.end()};
359 case Instruction::BitCast:
360 case Instruction::AddrSpaceCast:
361 case Instruction::GetElementPtr:
362 return {
Op.getOperand(0)};
363 case Instruction::Select:
364 return {
Op.getOperand(1),
Op.getOperand(2)};
365 case Instruction::Call: {
367 assert(
II.getIntrinsicID() == Intrinsic::ptrmask &&
368 "unexpected intrinsic call");
369 return {
II.getArgOperand(0)};
371 case Instruction::IntToPtr: {
373 auto *P2I = cast<Operator>(
Op.getOperand(0));
374 return {P2I->getOperand(0)};
381bool InferAddressSpacesImpl::rewriteIntrinsicOperands(
IntrinsicInst *
II,
384 Module *
M =
II->getParent()->getParent()->getParent();
387 case Intrinsic::objectsize:
388 case Intrinsic::masked_load: {
389 Type *DestTy =
II->getType();
393 II->setArgOperand(0, NewV);
394 II->setCalledFunction(NewDecl);
397 case Intrinsic::ptrmask:
400 case Intrinsic::masked_gather: {
405 II->setArgOperand(0, NewV);
406 II->setCalledFunction(NewDecl);
409 case Intrinsic::masked_store:
410 case Intrinsic::masked_scatter: {
411 Type *ValueTy =
II->getOperand(0)->getType();
414 M,
II->getIntrinsicID(), {ValueTy, NewPtrTy});
415 II->setArgOperand(1, NewV);
416 II->setCalledFunction(NewDecl);
419 case Intrinsic::prefetch:
420 case Intrinsic::is_constant: {
422 M,
II->getIntrinsicID(), {NewV->getType()});
423 II->setArgOperand(0, NewV);
424 II->setCalledFunction(NewDecl);
427 case Intrinsic::fake_use: {
428 II->replaceUsesOfWith(OldV, NewV);
431 case Intrinsic::lifetime_start:
432 case Intrinsic::lifetime_end: {
436 M,
II->getIntrinsicID(), {NewV->getType()});
437 II->setArgOperand(0, NewV);
438 II->setCalledFunction(NewDecl);
446 II->replaceAllUsesWith(Rewrite);
452void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
455 auto IID =
II->getIntrinsicID();
457 case Intrinsic::ptrmask:
458 case Intrinsic::objectsize:
459 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
460 PostorderStack, Visited);
462 case Intrinsic::is_constant: {
464 if (
Ptr->getType()->isPtrOrPtrVectorTy()) {
465 appendsFlatAddressExpressionToPostorderStack(
Ptr, PostorderStack,
471 case Intrinsic::masked_load:
472 case Intrinsic::masked_gather:
473 case Intrinsic::prefetch:
474 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
475 PostorderStack, Visited);
477 case Intrinsic::masked_store:
478 case Intrinsic::masked_scatter:
479 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(1),
480 PostorderStack, Visited);
482 case Intrinsic::fake_use: {
484 if (
Op->getType()->isPtrOrPtrVectorTy()) {
485 appendsFlatAddressExpressionToPostorderStack(
Op, PostorderStack,
492 case Intrinsic::lifetime_start:
493 case Intrinsic::lifetime_end: {
494 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
495 PostorderStack, Visited);
501 for (
int Idx : OpIndexes) {
502 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(
Idx),
503 PostorderStack, Visited);
513void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
514 Value *V, PostorderStackTy &PostorderStack,
516 assert(
V->getType()->isPtrOrPtrVectorTy());
523 PostorderStack.emplace_back(CE,
false);
528 if (
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
530 if (Visited.
insert(V).second) {
531 PostorderStack.emplace_back(V,
false);
533 if (
auto *
Op = dyn_cast<Operator>(V))
534 for (
auto &O :
Op->operands())
537 PostorderStack.emplace_back(CE,
false);
544std::vector<WeakTrackingVH>
545InferAddressSpacesImpl::collectFlatAddressExpressions(
Function &
F)
const {
548 PostorderStackTy PostorderStack;
552 auto PushPtrOperand = [&](
Value *
Ptr) {
553 appendsFlatAddressExpressionToPostorderStack(
Ptr, PostorderStack, Visited);
560 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(&
I)) {
561 PushPtrOperand(
GEP->getPointerOperand());
562 }
else if (
auto *LI = dyn_cast<LoadInst>(&
I))
563 PushPtrOperand(LI->getPointerOperand());
564 else if (
auto *SI = dyn_cast<StoreInst>(&
I))
565 PushPtrOperand(
SI->getPointerOperand());
566 else if (
auto *RMW = dyn_cast<AtomicRMWInst>(&
I))
567 PushPtrOperand(RMW->getPointerOperand());
568 else if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(&
I))
569 PushPtrOperand(CmpX->getPointerOperand());
570 else if (
auto *
MI = dyn_cast<MemIntrinsic>(&
I)) {
572 PushPtrOperand(
MI->getRawDest());
575 if (
auto *MTI = dyn_cast<MemTransferInst>(
MI))
576 PushPtrOperand(MTI->getRawSource());
577 }
else if (
auto *
II = dyn_cast<IntrinsicInst>(&
I))
578 collectRewritableIntrinsicOperands(
II, PostorderStack, Visited);
579 else if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(&
I)) {
580 if (
Cmp->getOperand(0)->getType()->isPtrOrPtrVectorTy()) {
581 PushPtrOperand(
Cmp->getOperand(0));
582 PushPtrOperand(
Cmp->getOperand(1));
584 }
else if (
auto *ASC = dyn_cast<AddrSpaceCastInst>(&
I)) {
585 PushPtrOperand(ASC->getPointerOperand());
586 }
else if (
auto *I2P = dyn_cast<IntToPtrInst>(&
I)) {
588 PushPtrOperand(cast<Operator>(I2P->getOperand(0))->getOperand(0));
589 }
else if (
auto *RI = dyn_cast<ReturnInst>(&
I)) {
590 if (
auto *RV = RI->getReturnValue();
591 RV && RV->getType()->isPtrOrPtrVectorTy())
596 std::vector<WeakTrackingVH> Postorder;
597 while (!PostorderStack.empty()) {
598 Value *TopVal = PostorderStack.back().getPointer();
601 if (PostorderStack.back().getInt()) {
603 Postorder.push_back(TopVal);
604 PostorderStack.pop_back();
608 PostorderStack.back().setInt(
true);
612 appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
624 const Use &OperandUse,
unsigned NewAddrSpace,
626 const PredicatedAddrSpaceMapTy &PredicatedAS,
632 if (
Constant *
C = dyn_cast<Constant>(Operand))
635 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand))
639 auto I = PredicatedAS.find(std::make_pair(Inst, Operand));
640 if (
I != PredicatedAS.end()) {
642 unsigned NewAS =
I->second;
666Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
669 const PredicatedAddrSpaceMapTy &PredicatedAS,
673 if (
I->getOpcode() == Instruction::AddrSpaceCast) {
674 Value *Src =
I->getOperand(0);
678 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
685 assert(
II->getIntrinsicID() == Intrinsic::ptrmask);
687 II->getArgOperandUse(0), NewAddrSpace, ValueWithNewAddrSpace,
688 PredicatedAS, PoisonUsesToFix);
692 assert(Rewrite !=
II &&
"cannot modify this pointer operation in place");
705 NewI->insertAfter(
I->getIterator());
706 NewI->setDebugLoc(
I->getDebugLoc());
712 for (
const Use &OperandUse :
I->operands()) {
713 if (!OperandUse.get()->getType()->isPtrOrPtrVectorTy())
717 OperandUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
721 switch (
I->getOpcode()) {
722 case Instruction::BitCast:
723 return new BitCastInst(NewPointerOperands[0], NewPtrType);
724 case Instruction::PHI: {
725 assert(
I->getType()->isPtrOrPtrVectorTy());
728 for (
unsigned Index = 0;
Index <
PHI->getNumIncomingValues(); ++
Index) {
731 PHI->getIncomingBlock(Index));
735 case Instruction::GetElementPtr: {
738 GEP->getSourceElementType(), NewPointerOperands[0],
743 case Instruction::Select:
744 assert(
I->getType()->isPtrOrPtrVectorTy());
746 NewPointerOperands[2],
"",
nullptr,
I);
747 case Instruction::IntToPtr: {
749 Value *Src = cast<Operator>(
I->getOperand(0))->getOperand(0);
750 if (Src->getType() == NewPtrType)
771 CE->getType()->isPtrOrPtrVectorTy()
775 if (CE->getOpcode() == Instruction::AddrSpaceCast) {
779 assert(CE->getOperand(0)->getType()->getPointerAddressSpace() ==
781 return CE->getOperand(0);
784 if (CE->getOpcode() == Instruction::BitCast) {
785 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(CE->getOperand(0)))
790 if (CE->getOpcode() == Instruction::IntToPtr) {
792 Constant *Src = cast<ConstantExpr>(CE->getOperand(0))->getOperand(0);
793 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
800 for (
unsigned Index = 0; Index < CE->getNumOperands(); ++Index) {
801 Constant *Operand = CE->getOperand(Index);
807 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand)) {
809 NewOperands.
push_back(cast<Constant>(NewOperand));
812 if (
auto *CExpr = dyn_cast<ConstantExpr>(Operand))
814 CExpr, NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI)) {
816 NewOperands.
push_back(cast<Constant>(NewOperand));
828 if (CE->getOpcode() == Instruction::GetElementPtr) {
831 return CE->getWithOperands(NewOperands, TargetType,
false,
832 cast<GEPOperator>(CE)->getSourceElementType());
835 return CE->getWithOperands(NewOperands, TargetType);
843Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
844 Value *V,
unsigned NewAddrSpace,
846 const PredicatedAddrSpaceMapTy &PredicatedAS,
849 assert(
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
852 if (
auto *Arg = dyn_cast<Argument>(V)) {
858 Type *NewPtrTy = PointerType::get(Arg->getContext(), NewAddrSpace);
860 NewI->insertBefore(Insert);
865 Value *NewV = cloneInstructionWithNewAddressSpace(
866 I, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, PoisonUsesToFix);
867 if (
Instruction *NewI = dyn_cast_or_null<Instruction>(NewV)) {
868 if (NewI->getParent() ==
nullptr) {
869 NewI->insertBefore(
I->getIterator());
871 NewI->setDebugLoc(
I->getDebugLoc());
878 cast<ConstantExpr>(V), NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI);
883unsigned InferAddressSpacesImpl::joinAddressSpaces(
unsigned AS1,
884 unsigned AS2)
const {
885 if (AS1 == FlatAddrSpace || AS2 == FlatAddrSpace)
886 return FlatAddrSpace;
894 return (AS1 == AS2) ? AS1 : FlatAddrSpace;
897bool InferAddressSpacesImpl::run(
Function &CurFn) {
899 DL = &
F->getDataLayout();
911 std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions(*
F);
915 ValueToAddrSpaceMapTy InferredAddrSpace;
916 PredicatedAddrSpaceMapTy PredicatedAS;
917 inferAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS);
921 return rewriteWithNewAddressSpaces(Postorder, InferredAddrSpace,
927void InferAddressSpacesImpl::inferAddressSpaces(
929 ValueToAddrSpaceMapTy &InferredAddrSpace,
930 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
933 for (
Value *V : Postorder)
936 while (!Worklist.empty()) {
937 Value *
V = Worklist.pop_back_val();
941 if (!updateAddressSpace(*V, InferredAddrSpace, PredicatedAS))
946 if (Worklist.count(
User))
949 auto Pos = InferredAddrSpace.find(
User);
952 if (Pos == InferredAddrSpace.end())
958 if (Pos->second == FlatAddrSpace)
961 Worklist.insert(
User);
967InferAddressSpacesImpl::getPredicatedAddrSpace(
const Value &
Ptr,
968 const Value *UserCtx)
const {
969 const Instruction *UserCtxI = dyn_cast<Instruction>(UserCtx);
973 const Value *StrippedPtr =
Ptr.stripInBoundsOffsets();
974 for (
auto &AssumeVH : AC.assumptionsFor(StrippedPtr)) {
977 CallInst *CI = cast<CallInst>(AssumeVH);
991bool InferAddressSpacesImpl::updateAddressSpace(
992 const Value &V, ValueToAddrSpaceMapTy &InferredAddrSpace,
993 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
994 assert(InferredAddrSpace.count(&V));
996 LLVM_DEBUG(
dbgs() <<
"Updating the address space of\n " << V <<
'\n');
1003 assert(isa<Operator>(V) || isa<Argument>(V));
1005 if (isa<Operator>(V) &&
1006 cast<Operator>(V).
getOpcode() == Instruction::Select) {
1008 Value *Src0 =
Op.getOperand(1);
1009 Value *Src1 =
Op.getOperand(2);
1011 auto I = InferredAddrSpace.find(Src0);
1012 unsigned Src0AS = (
I != InferredAddrSpace.end())
1016 auto J = InferredAddrSpace.find(Src1);
1017 unsigned Src1AS = (J != InferredAddrSpace.end())
1021 auto *C0 = dyn_cast<Constant>(Src0);
1022 auto *C1 = dyn_cast<Constant>(Src1);
1031 if (C0 && isSafeToCastConstAddrSpace(C0, Src1AS))
1033 else if (C1 && isSafeToCastConstAddrSpace(C1, Src0AS))
1036 NewAS = joinAddressSpaces(Src0AS, Src1AS);
1045 auto I = InferredAddrSpace.find(PtrOperand);
1047 if (
I == InferredAddrSpace.end()) {
1048 OperandAS = PtrOperand->getType()->getPointerAddressSpace();
1049 if (OperandAS == FlatAddrSpace) {
1051 unsigned AS = getPredicatedAddrSpace(*PtrOperand, &V);
1054 <<
" deduce operand AS from the predicate addrspace "
1058 PredicatedAS[std::make_pair(&V, PtrOperand)] = OperandAS;
1062 OperandAS =
I->second;
1065 NewAS = joinAddressSpaces(NewAS, OperandAS);
1066 if (NewAS == FlatAddrSpace)
1072 unsigned OldAS = InferredAddrSpace.lookup(&V);
1073 assert(OldAS != FlatAddrSpace);
1080 InferredAddrSpace[&
V] = NewAS;
1089 if (U.get() == OldVal) {
1097template <
typename InstrType>
1099 InstrType *MemInstr,
unsigned AddrSpace,
1117 User *Inst,
unsigned AddrSpace,
1119 if (
auto *LI = dyn_cast<LoadInst>(Inst))
1122 if (
auto *SI = dyn_cast<StoreInst>(Inst))
1125 if (
auto *RMW = dyn_cast<AtomicRMWInst>(Inst))
1128 if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst))
1140 if (
auto *MSI = dyn_cast<MemSetInst>(
MI)) {
1141 B.CreateMemSet(NewV, MSI->getValue(), MSI->getLength(), MSI->getDestAlign(),
1143 MI->getAAMetadata());
1144 }
else if (
auto *MTI = dyn_cast<MemTransferInst>(
MI)) {
1145 Value *Src = MTI->getRawSource();
1146 Value *Dest = MTI->getRawDest();
1155 if (
auto *MCI = dyn_cast<MemCpyInst>(MTI)) {
1156 if (MCI->isForceInlined())
1157 B.CreateMemCpyInline(Dest, MTI->getDestAlign(), Src,
1158 MTI->getSourceAlign(), MTI->getLength(),
1160 MI->getAAMetadata());
1162 B.CreateMemCpy(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1165 MI->getAAMetadata());
1167 assert(isa<MemMoveInst>(MTI));
1168 B.CreateMemMove(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1171 MI->getAAMetadata());
1176 MI->eraseFromParent();
1182bool InferAddressSpacesImpl::isSafeToCastConstAddrSpace(
Constant *
C,
1183 unsigned NewAS)
const {
1186 unsigned SrcAS =
C->getType()->getPointerAddressSpace();
1187 if (SrcAS == NewAS || isa<UndefValue>(
C))
1191 if (SrcAS != FlatAddrSpace && NewAS != FlatAddrSpace)
1194 if (isa<ConstantPointerNull>(
C))
1197 if (
auto *
Op = dyn_cast<Operator>(
C)) {
1200 if (
Op->getOpcode() == Instruction::AddrSpaceCast)
1201 return isSafeToCastConstAddrSpace(cast<Constant>(
Op->getOperand(0)),
1204 if (
Op->getOpcode() == Instruction::IntToPtr &&
1205 Op->getType()->getPointerAddressSpace() == FlatAddrSpace)
1214 User *CurUser =
I->getUser();
1217 while (
I !=
End &&
I->getUser() == CurUser)
1223void InferAddressSpacesImpl::performPointerReplacement(
1227 User *CurUser =
U.getUser();
1229 unsigned AddrSpace =
V->getType()->getPointerAddressSpace();
1234 if (CurUser == NewV)
1237 auto *CurUserI = dyn_cast<Instruction>(CurUser);
1238 if (!CurUserI || CurUserI->getFunction() !=
F)
1242 if (
auto *
MI = dyn_cast<MemIntrinsic>(CurUser)) {
1247 if (
auto *
II = dyn_cast<IntrinsicInst>(CurUser)) {
1248 if (rewriteIntrinsicOperands(
II, V, NewV))
1252 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(CurUserI)) {
1260 int SrcIdx =
U.getOperandNo();
1261 int OtherIdx = (SrcIdx == 0) ? 1 : 0;
1262 Value *OtherSrc =
Cmp->getOperand(OtherIdx);
1264 if (
Value *OtherNewV = ValueWithNewAddrSpace.
lookup(OtherSrc)) {
1265 if (OtherNewV->getType()->getPointerAddressSpace() == NewAS) {
1266 Cmp->setOperand(OtherIdx, OtherNewV);
1267 Cmp->setOperand(SrcIdx, NewV);
1273 if (
auto *KOtherSrc = dyn_cast<Constant>(OtherSrc)) {
1274 if (isSafeToCastConstAddrSpace(KOtherSrc, NewAS)) {
1275 Cmp->setOperand(SrcIdx, NewV);
1285 if (ASC->getDestAddressSpace() == NewAS) {
1286 ASC->replaceAllUsesWith(NewV);
1293 if (isa<Instruction>(V) || isa<Instruction>(NewV)) {
1295 if (U == V && isa<AddrSpaceCastInst>(V))
1300 if (
Instruction *NewVInst = dyn_cast<Instruction>(NewV))
1301 InsertPos = std::next(NewVInst->getIterator());
1303 InsertPos = std::next(cast<Instruction>(V)->getIterator());
1305 while (isa<PHINode>(InsertPos))
1311 CurUserI->replaceUsesOfWith(
1316bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
1318 const ValueToAddrSpaceMapTy &InferredAddrSpace,
1319 const PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1326 for (
Value *V : Postorder) {
1327 unsigned NewAddrSpace = InferredAddrSpace.lookup(V);
1334 if (
V->getType()->getPointerAddressSpace() != NewAddrSpace) {
1336 cloneValueWithNewAddressSpace(V, NewAddrSpace, ValueWithNewAddrSpace,
1337 PredicatedAS, &PoisonUsesToFix);
1339 ValueWithNewAddrSpace[
V] =
New;
1343 if (ValueWithNewAddrSpace.
empty())
1347 for (
const Use *PoisonUse : PoisonUsesToFix) {
1348 User *
V = PoisonUse->getUser();
1349 User *NewV = cast_or_null<User>(ValueWithNewAddrSpace.
lookup(V));
1353 unsigned OperandNo = PoisonUse->getOperandNo();
1355 NewV->
setOperand(OperandNo, ValueWithNewAddrSpace.
lookup(PoisonUse->get()));
1364 assert(WVH &&
"value was unexpectedly deleted");
1367 if (NewV ==
nullptr)
1370 LLVM_DEBUG(
dbgs() <<
"Replacing the uses of " << *V <<
"\n with\n "
1373 if (
Constant *
C = dyn_cast<Constant>(V)) {
1377 LLVM_DEBUG(
dbgs() <<
"Inserting replacement const cast: " << Replace
1378 <<
": " << *Replace <<
'\n');
1381 if (
auto *
I = dyn_cast<Instruction>(U)) {
1382 if (
I->getFunction() ==
F)
1383 I->replaceUsesOfWith(
C, Replace);
1385 WorkList.
append(
U->user_begin(),
U->user_end());
1388 if (!WorkList.
empty()) {
1391 while (!WorkList.
empty()) {
1393 if (
auto *
I = dyn_cast<Instruction>(U)) {
1394 if (
I->getFunction() ==
F)
1395 VMapper.remapInstruction(*
I);
1398 for (
User *U2 :
U->users())
1399 if (Visited.
insert(U2).second)
1408 for (
I =
V->use_begin(), E =
V->use_end();
I != E;) {
1415 performPointerReplacement(V, NewV, U, ValueWithNewAddrSpace,
1419 if (
V->use_empty()) {
1431bool InferAddressSpaces::runOnFunction(
Function &
F) {
1432 if (skipFunction(
F))
1435 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
1437 return InferAddressSpacesImpl(
1438 getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F), DT,
1439 &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F),
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This 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 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
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 std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
This class represents a conversion between pointers from one address space to another.
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
InstListType::iterator iterator
Instruction iterators...
This class represents a no-op cast from one type to another.
Represents analyses that only rely on functions' control flow.
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
static 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.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
LLVM_ABI void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
This instruction compares its operands according to the predicate given to the constructor.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
A wrapper class for inspecting calls to intrinsic functions.
This is the common base class for memset/memcpy/memmove.
A Module instance is used to store all the information related to an LLVM module.
This is a utility class that provides an abstraction for the common functionality between Instruction...
unsigned getOpcode() const
Return the opcode for this Instruction or ConstantExpr.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static unsigned getOperandNumForIncomingValue(unsigned i)
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static 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, Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetTransformInfo.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Context for (re-)mapping values (and metadata).
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
use_iterator_impl< Use > use_iterator
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Value handle that is nullable, but tries to track the Value.
std::pair< iterator, bool > insert(const ValueT &V)
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.
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.
LLVM_ABI void initializeInferAddressSpacesPass(PassRegistry &)
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...
@ 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 raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI FunctionPass * createInferAddressSpacesPass(unsigned AddressSpace=~0u)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)