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(),
316 switch (
Op->getOpcode()) {
317 case Instruction::PHI:
318 assert(
Op->getType()->isPtrOrPtrVectorTy());
320 case Instruction::BitCast:
321 case Instruction::AddrSpaceCast:
322 case Instruction::GetElementPtr:
324 case Instruction::Select:
325 return Op->getType()->isPtrOrPtrVectorTy();
326 case Instruction::Call: {
328 return II &&
II->getIntrinsicID() == Intrinsic::ptrmask;
330 case Instruction::IntToPtr:
345 switch (
Op.getOpcode()) {
346 case Instruction::PHI: {
347 auto IncomingValues = cast<PHINode>(
Op).incoming_values();
348 return {IncomingValues.begin(), IncomingValues.end()};
350 case Instruction::BitCast:
351 case Instruction::AddrSpaceCast:
352 case Instruction::GetElementPtr:
353 return {
Op.getOperand(0)};
354 case Instruction::Select:
355 return {
Op.getOperand(1),
Op.getOperand(2)};
356 case Instruction::Call: {
358 assert(
II.getIntrinsicID() == Intrinsic::ptrmask &&
359 "unexpected intrinsic call");
360 return {
II.getArgOperand(0)};
362 case Instruction::IntToPtr: {
364 auto *P2I = cast<Operator>(
Op.getOperand(0));
365 return {P2I->getOperand(0)};
372bool InferAddressSpacesImpl::rewriteIntrinsicOperands(
IntrinsicInst *
II,
375 Module *
M =
II->getParent()->getParent()->getParent();
378 case Intrinsic::objectsize:
379 case Intrinsic::masked_load: {
380 Type *DestTy =
II->getType();
384 II->setArgOperand(0, NewV);
385 II->setCalledFunction(NewDecl);
388 case Intrinsic::ptrmask:
391 case Intrinsic::masked_gather: {
396 II->setArgOperand(0, NewV);
397 II->setCalledFunction(NewDecl);
400 case Intrinsic::masked_store:
401 case Intrinsic::masked_scatter: {
402 Type *ValueTy =
II->getOperand(0)->getType();
405 M,
II->getIntrinsicID(), {ValueTy, NewPtrTy});
406 II->setArgOperand(1, NewV);
407 II->setCalledFunction(NewDecl);
410 case Intrinsic::prefetch:
411 case Intrinsic::is_constant: {
413 M,
II->getIntrinsicID(), {NewV->getType()});
414 II->setArgOperand(0, NewV);
415 II->setCalledFunction(NewDecl);
418 case Intrinsic::fake_use: {
419 II->replaceUsesOfWith(OldV, NewV);
427 II->replaceAllUsesWith(Rewrite);
433void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
436 auto IID =
II->getIntrinsicID();
438 case Intrinsic::ptrmask:
439 case Intrinsic::objectsize:
440 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
441 PostorderStack, Visited);
443 case Intrinsic::is_constant: {
445 if (
Ptr->getType()->isPtrOrPtrVectorTy()) {
446 appendsFlatAddressExpressionToPostorderStack(
Ptr, PostorderStack,
452 case Intrinsic::masked_load:
453 case Intrinsic::masked_gather:
454 case Intrinsic::prefetch:
455 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(0),
456 PostorderStack, Visited);
458 case Intrinsic::masked_store:
459 case Intrinsic::masked_scatter:
460 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(1),
461 PostorderStack, Visited);
463 case Intrinsic::fake_use: {
465 if (
Op->getType()->isPtrOrPtrVectorTy()) {
466 appendsFlatAddressExpressionToPostorderStack(
Op, PostorderStack,
476 for (
int Idx : OpIndexes) {
477 appendsFlatAddressExpressionToPostorderStack(
II->getArgOperand(
Idx),
478 PostorderStack, Visited);
488void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
489 Value *V, PostorderStackTy &PostorderStack,
491 assert(
V->getType()->isPtrOrPtrVectorTy());
498 PostorderStack.emplace_back(CE,
false);
503 if (
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
505 if (Visited.
insert(V).second) {
506 PostorderStack.emplace_back(V,
false);
512 PostorderStack.emplace_back(CE,
false);
521std::vector<WeakTrackingVH>
522InferAddressSpacesImpl::collectFlatAddressExpressions(
Function &
F)
const {
525 PostorderStackTy PostorderStack;
529 auto PushPtrOperand = [&](
Value *
Ptr) {
530 appendsFlatAddressExpressionToPostorderStack(
Ptr, PostorderStack, Visited);
537 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(&
I)) {
538 PushPtrOperand(
GEP->getPointerOperand());
539 }
else if (
auto *LI = dyn_cast<LoadInst>(&
I))
540 PushPtrOperand(LI->getPointerOperand());
541 else if (
auto *SI = dyn_cast<StoreInst>(&
I))
542 PushPtrOperand(
SI->getPointerOperand());
543 else if (
auto *RMW = dyn_cast<AtomicRMWInst>(&
I))
544 PushPtrOperand(RMW->getPointerOperand());
545 else if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(&
I))
546 PushPtrOperand(CmpX->getPointerOperand());
547 else if (
auto *
MI = dyn_cast<MemIntrinsic>(&
I)) {
549 PushPtrOperand(
MI->getRawDest());
552 if (
auto *MTI = dyn_cast<MemTransferInst>(
MI))
553 PushPtrOperand(MTI->getRawSource());
554 }
else if (
auto *
II = dyn_cast<IntrinsicInst>(&
I))
555 collectRewritableIntrinsicOperands(
II, PostorderStack, Visited);
556 else if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(&
I)) {
557 if (
Cmp->getOperand(0)->getType()->isPtrOrPtrVectorTy()) {
558 PushPtrOperand(
Cmp->getOperand(0));
559 PushPtrOperand(
Cmp->getOperand(1));
561 }
else if (
auto *ASC = dyn_cast<AddrSpaceCastInst>(&
I)) {
562 PushPtrOperand(ASC->getPointerOperand());
563 }
else if (
auto *I2P = dyn_cast<IntToPtrInst>(&
I)) {
565 PushPtrOperand(cast<Operator>(I2P->getOperand(0))->getOperand(0));
566 }
else if (
auto *RI = dyn_cast<ReturnInst>(&
I)) {
567 if (
auto *RV = RI->getReturnValue();
568 RV && RV->getType()->isPtrOrPtrVectorTy())
573 std::vector<WeakTrackingVH> Postorder;
574 while (!PostorderStack.empty()) {
575 Value *TopVal = PostorderStack.back().getPointer();
578 if (PostorderStack.back().getInt()) {
580 Postorder.push_back(TopVal);
581 PostorderStack.pop_back();
585 PostorderStack.back().setInt(
true);
589 appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
601 const Use &OperandUse,
unsigned NewAddrSpace,
603 const PredicatedAddrSpaceMapTy &PredicatedAS,
609 if (
Constant *
C = dyn_cast<Constant>(Operand))
612 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand))
616 auto I = PredicatedAS.find(std::make_pair(Inst, Operand));
617 if (
I != PredicatedAS.end()) {
619 unsigned NewAS =
I->second;
622 NewI->insertBefore(Inst);
643Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
646 const PredicatedAddrSpaceMapTy &PredicatedAS,
650 if (
I->getOpcode() == Instruction::AddrSpaceCast) {
651 Value *Src =
I->getOperand(0);
655 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
656 if (Src->getType() != NewPtrType)
664 assert(
II->getIntrinsicID() == Intrinsic::ptrmask);
666 II->getArgOperandUse(0), NewAddrSpace, ValueWithNewAddrSpace,
667 PredicatedAS, PoisonUsesToFix);
671 assert(Rewrite !=
II &&
"cannot modify this pointer operation in place");
684 NewI->insertAfter(
I);
685 NewI->setDebugLoc(
I->getDebugLoc());
691 for (
const Use &OperandUse :
I->operands()) {
692 if (!OperandUse.get()->getType()->isPtrOrPtrVectorTy())
696 OperandUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
700 switch (
I->getOpcode()) {
701 case Instruction::BitCast:
702 return new BitCastInst(NewPointerOperands[0], NewPtrType);
703 case Instruction::PHI: {
704 assert(
I->getType()->isPtrOrPtrVectorTy());
707 for (
unsigned Index = 0;
Index <
PHI->getNumIncomingValues(); ++
Index) {
710 PHI->getIncomingBlock(Index));
714 case Instruction::GetElementPtr: {
717 GEP->getSourceElementType(), NewPointerOperands[0],
722 case Instruction::Select:
723 assert(
I->getType()->isPtrOrPtrVectorTy());
725 NewPointerOperands[2],
"",
nullptr,
I);
726 case Instruction::IntToPtr: {
728 Value *Src = cast<Operator>(
I->getOperand(0))->getOperand(0);
729 if (Src->getType() == NewPtrType)
750 CE->getType()->isPtrOrPtrVectorTy()
754 if (CE->getOpcode() == Instruction::AddrSpaceCast) {
758 assert(CE->getOperand(0)->getType()->getPointerAddressSpace() ==
763 if (CE->getOpcode() == Instruction::BitCast) {
764 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(CE->getOperand(0)))
769 if (CE->getOpcode() == Instruction::IntToPtr) {
771 Constant *Src = cast<ConstantExpr>(CE->getOperand(0))->getOperand(0);
772 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
779 for (
unsigned Index = 0; Index < CE->getNumOperands(); ++Index) {
780 Constant *Operand = CE->getOperand(Index);
786 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand)) {
788 NewOperands.
push_back(cast<Constant>(NewOperand));
791 if (
auto *CExpr = dyn_cast<ConstantExpr>(Operand))
793 CExpr, NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI)) {
795 NewOperands.
push_back(cast<Constant>(NewOperand));
807 if (CE->getOpcode() == Instruction::GetElementPtr) {
810 return CE->getWithOperands(NewOperands, TargetType,
false,
811 cast<GEPOperator>(CE)->getSourceElementType());
814 return CE->getWithOperands(NewOperands, TargetType);
822Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
823 Value *V,
unsigned NewAddrSpace,
825 const PredicatedAddrSpaceMapTy &PredicatedAS,
828 assert(
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
832 Value *NewV = cloneInstructionWithNewAddressSpace(
833 I, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, PoisonUsesToFix);
834 if (
Instruction *NewI = dyn_cast_or_null<Instruction>(NewV)) {
835 if (NewI->getParent() ==
nullptr) {
836 NewI->insertBefore(
I);
838 NewI->setDebugLoc(
I->getDebugLoc());
845 cast<ConstantExpr>(V), NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI);
850unsigned InferAddressSpacesImpl::joinAddressSpaces(
unsigned AS1,
851 unsigned AS2)
const {
852 if (AS1 == FlatAddrSpace || AS2 == FlatAddrSpace)
853 return FlatAddrSpace;
861 return (AS1 == AS2) ? AS1 : FlatAddrSpace;
864bool InferAddressSpacesImpl::run(
Function &CurFn) {
866 DL = &
F->getDataLayout();
878 std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions(*
F);
882 ValueToAddrSpaceMapTy InferredAddrSpace;
883 PredicatedAddrSpaceMapTy PredicatedAS;
884 inferAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS);
888 return rewriteWithNewAddressSpaces(Postorder, InferredAddrSpace,
894void InferAddressSpacesImpl::inferAddressSpaces(
896 ValueToAddrSpaceMapTy &InferredAddrSpace,
897 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
900 for (
Value *V : Postorder)
903 while (!Worklist.empty()) {
904 Value *
V = Worklist.pop_back_val();
908 if (!updateAddressSpace(*V, InferredAddrSpace, PredicatedAS))
913 if (Worklist.count(
User))
916 auto Pos = InferredAddrSpace.find(
User);
919 if (Pos == InferredAddrSpace.end())
925 if (Pos->second == FlatAddrSpace)
928 Worklist.insert(
User);
934InferAddressSpacesImpl::getPredicatedAddrSpace(
const Value &
Ptr,
935 const Value *UserCtx)
const {
936 const Instruction *UserCtxI = dyn_cast<Instruction>(UserCtx);
940 const Value *StrippedPtr =
Ptr.stripInBoundsOffsets();
941 for (
auto &AssumeVH : AC.assumptionsFor(StrippedPtr)) {
944 CallInst *CI = cast<CallInst>(AssumeVH);
958bool InferAddressSpacesImpl::updateAddressSpace(
959 const Value &V, ValueToAddrSpaceMapTy &InferredAddrSpace,
960 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
961 assert(InferredAddrSpace.count(&V));
963 LLVM_DEBUG(
dbgs() <<
"Updating the address space of\n " << V <<
'\n');
970 if (
Op.getOpcode() == Instruction::Select) {
971 Value *Src0 =
Op.getOperand(1);
972 Value *Src1 =
Op.getOperand(2);
974 auto I = InferredAddrSpace.find(Src0);
975 unsigned Src0AS = (
I != InferredAddrSpace.end())
979 auto J = InferredAddrSpace.find(Src1);
980 unsigned Src1AS = (J != InferredAddrSpace.end())
984 auto *C0 = dyn_cast<Constant>(Src0);
985 auto *C1 = dyn_cast<Constant>(Src1);
994 if (C0 && isSafeToCastConstAddrSpace(C0, Src1AS))
996 else if (C1 && isSafeToCastConstAddrSpace(C1, Src0AS))
999 NewAS = joinAddressSpaces(Src0AS, Src1AS);
1008 auto I = InferredAddrSpace.find(PtrOperand);
1010 if (
I == InferredAddrSpace.end()) {
1011 OperandAS = PtrOperand->getType()->getPointerAddressSpace();
1012 if (OperandAS == FlatAddrSpace) {
1014 unsigned AS = getPredicatedAddrSpace(*PtrOperand, &V);
1017 <<
" deduce operand AS from the predicate addrspace "
1021 PredicatedAS[std::make_pair(&V, PtrOperand)] = OperandAS;
1025 OperandAS =
I->second;
1028 NewAS = joinAddressSpaces(NewAS, OperandAS);
1029 if (NewAS == FlatAddrSpace)
1035 unsigned OldAS = InferredAddrSpace.lookup(&V);
1036 assert(OldAS != FlatAddrSpace);
1043 InferredAddrSpace[&
V] = NewAS;
1052 if (U.get() == OldVal) {
1060template <
typename InstrType>
1062 InstrType *MemInstr,
unsigned AddrSpace,
1080 User *Inst,
unsigned AddrSpace,
1082 if (
auto *LI = dyn_cast<LoadInst>(Inst))
1085 if (
auto *SI = dyn_cast<StoreInst>(Inst))
1088 if (
auto *RMW = dyn_cast<AtomicRMWInst>(Inst))
1091 if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst))
1103 MDNode *TBAA =
MI->getMetadata(LLVMContext::MD_tbaa);
1104 MDNode *ScopeMD =
MI->getMetadata(LLVMContext::MD_alias_scope);
1105 MDNode *NoAliasMD =
MI->getMetadata(LLVMContext::MD_noalias);
1107 if (
auto *MSI = dyn_cast<MemSetInst>(
MI)) {
1108 B.CreateMemSet(NewV, MSI->getValue(), MSI->getLength(), MSI->getDestAlign(),
1110 TBAA, ScopeMD, NoAliasMD);
1111 }
else if (
auto *MTI = dyn_cast<MemTransferInst>(
MI)) {
1112 Value *Src = MTI->getRawSource();
1113 Value *Dest = MTI->getRawDest();
1122 if (isa<MemCpyInlineInst>(MTI)) {
1123 MDNode *TBAAStruct = MTI->getMetadata(LLVMContext::MD_tbaa_struct);
1124 B.CreateMemCpyInline(Dest, MTI->getDestAlign(), Src,
1125 MTI->getSourceAlign(), MTI->getLength(),
1127 TBAA, TBAAStruct, ScopeMD, NoAliasMD);
1128 }
else if (isa<MemCpyInst>(MTI)) {
1129 MDNode *TBAAStruct = MTI->getMetadata(LLVMContext::MD_tbaa_struct);
1130 B.CreateMemCpy(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1133 TBAA, TBAAStruct, ScopeMD, NoAliasMD);
1135 assert(isa<MemMoveInst>(MTI));
1136 B.CreateMemMove(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1139 TBAA, ScopeMD, NoAliasMD);
1144 MI->eraseFromParent();
1150bool InferAddressSpacesImpl::isSafeToCastConstAddrSpace(
Constant *
C,
1151 unsigned NewAS)
const {
1154 unsigned SrcAS =
C->getType()->getPointerAddressSpace();
1155 if (SrcAS == NewAS || isa<UndefValue>(
C))
1159 if (SrcAS != FlatAddrSpace && NewAS != FlatAddrSpace)
1162 if (isa<ConstantPointerNull>(
C))
1165 if (
auto *
Op = dyn_cast<Operator>(
C)) {
1168 if (
Op->getOpcode() == Instruction::AddrSpaceCast)
1169 return isSafeToCastConstAddrSpace(cast<Constant>(
Op->getOperand(0)),
1172 if (
Op->getOpcode() == Instruction::IntToPtr &&
1173 Op->getType()->getPointerAddressSpace() == FlatAddrSpace)
1182 User *CurUser =
I->getUser();
1185 while (
I !=
End &&
I->getUser() == CurUser)
1191void InferAddressSpacesImpl::performPointerReplacement(
1195 User *CurUser =
U.getUser();
1197 unsigned AddrSpace =
V->getType()->getPointerAddressSpace();
1202 if (CurUser == NewV)
1205 auto *CurUserI = dyn_cast<Instruction>(CurUser);
1206 if (!CurUserI || CurUserI->getFunction() !=
F)
1210 if (
auto *
MI = dyn_cast<MemIntrinsic>(CurUser)) {
1215 if (
auto *
II = dyn_cast<IntrinsicInst>(CurUser)) {
1216 if (rewriteIntrinsicOperands(
II, V, NewV))
1220 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(CurUserI)) {
1228 int SrcIdx =
U.getOperandNo();
1229 int OtherIdx = (SrcIdx == 0) ? 1 : 0;
1230 Value *OtherSrc =
Cmp->getOperand(OtherIdx);
1232 if (
Value *OtherNewV = ValueWithNewAddrSpace.
lookup(OtherSrc)) {
1233 if (OtherNewV->getType()->getPointerAddressSpace() == NewAS) {
1234 Cmp->setOperand(OtherIdx, OtherNewV);
1235 Cmp->setOperand(SrcIdx, NewV);
1241 if (
auto *KOtherSrc = dyn_cast<Constant>(OtherSrc)) {
1242 if (isSafeToCastConstAddrSpace(KOtherSrc, NewAS)) {
1243 Cmp->setOperand(SrcIdx, NewV);
1253 if (ASC->getDestAddressSpace() == NewAS) {
1254 ASC->replaceAllUsesWith(NewV);
1261 if (
Instruction *VInst = dyn_cast<Instruction>(V)) {
1263 if (U == V && isa<AddrSpaceCastInst>(V))
1268 if (
Instruction *NewVInst = dyn_cast<Instruction>(NewV))
1269 InsertPos = std::next(NewVInst->getIterator());
1271 InsertPos = std::next(VInst->getIterator());
1273 while (isa<PHINode>(InsertPos))
1279 CurUserI->replaceUsesOfWith(
1284bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
1286 const ValueToAddrSpaceMapTy &InferredAddrSpace,
1287 const PredicatedAddrSpaceMapTy &PredicatedAS)
const {
1294 for (
Value *V : Postorder) {
1295 unsigned NewAddrSpace = InferredAddrSpace.lookup(V);
1302 if (
V->getType()->getPointerAddressSpace() != NewAddrSpace) {
1304 cloneValueWithNewAddressSpace(V, NewAddrSpace, ValueWithNewAddrSpace,
1305 PredicatedAS, &PoisonUsesToFix);
1307 ValueWithNewAddrSpace[
V] =
New;
1311 if (ValueWithNewAddrSpace.
empty())
1315 for (
const Use *PoisonUse : PoisonUsesToFix) {
1316 User *
V = PoisonUse->getUser();
1317 User *NewV = cast_or_null<User>(ValueWithNewAddrSpace.
lookup(V));
1321 unsigned OperandNo = PoisonUse->getOperandNo();
1323 NewV->
setOperand(OperandNo, ValueWithNewAddrSpace.
lookup(PoisonUse->get()));
1332 assert(WVH &&
"value was unexpectedly deleted");
1335 if (NewV ==
nullptr)
1338 LLVM_DEBUG(
dbgs() <<
"Replacing the uses of " << *V <<
"\n with\n "
1341 if (
Constant *
C = dyn_cast<Constant>(V)) {
1345 LLVM_DEBUG(
dbgs() <<
"Inserting replacement const cast: " << Replace
1346 <<
": " << *Replace <<
'\n');
1349 if (
auto *
I = dyn_cast<Instruction>(U)) {
1350 if (
I->getFunction() ==
F)
1351 I->replaceUsesOfWith(
C, Replace);
1353 WorkList.
append(
U->user_begin(),
U->user_end());
1356 if (!WorkList.
empty()) {
1359 while (!WorkList.
empty()) {
1361 if (
auto *
I = dyn_cast<Instruction>(U)) {
1362 if (
I->getFunction() ==
F)
1363 VMapper.remapInstruction(*
I);
1366 for (
User *U2 :
U->users())
1367 if (Visited.
insert(U2).second)
1376 for (
I =
V->use_begin(), E =
V->use_end();
I != E;) {
1383 performPointerReplacement(V, NewV, U, ValueWithNewAddrSpace,
1387 if (
V->use_empty()) {
1399bool InferAddressSpaces::runOnFunction(
Function &
F) {
1400 if (skipFunction(
F))
1403 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
1405 return InferAddressSpacesImpl(
1406 getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F), DT,
1407 &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F),
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This 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
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This class represents a conversion between pointers from one address space to another.
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
InstListType::iterator iterator
Instruction iterators...
This class represents a no-op cast from one type to another.
Represents analyses that only rely on functions' control flow.
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
static CastInst * CreatePointerBitCastOrAddrSpaceCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Create a BitCast or an AddrSpaceCast cast instruction.
static bool isNoopCast(Instruction::CastOps Opcode, Type *SrcTy, Type *DstTy, const DataLayout &DL)
A no-op cast is one that can be effected without changing any bits.
A constant value that is initialized with an expression using other constant values.
static Constant * getAddrSpaceCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
This instruction compares its operands according to the predicate given to the constructor.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
A wrapper class for inspecting calls to intrinsic functions.
This is the common base class for memset/memcpy/memmove.
A Module instance is used to store all the information related to an LLVM module.
This is a utility class that provides an abstraction for the common functionality between Instruction...
unsigned getOpcode() const
Return the opcode for this Instruction or ConstantExpr.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static unsigned getOperandNumForIncomingValue(unsigned i)
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserveSet()
Mark an analysis set as preserved.
void preserve()
Mark an analysis as preserved.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetTransformInfo.
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
const Use & getOperandUse(unsigned i) const
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Context for (re-)mapping values (and metadata).
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
use_iterator_impl< Use > use_iterator
Value handle that is nullable, but tries to track the Value.
std::pair< iterator, bool > insert(const ValueT &V)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
InstrType
This represents what is and is not supported when finding similarity in Instructions.
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.
bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, const DominatorTree *DT=nullptr, bool AllowEphemerals=false)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
void initializeInferAddressSpacesPass(PassRegistry &)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
@ RF_IgnoreMissingLocals
If this flag is set, the remapper ignores missing function-local entries (Argument,...
@ RF_NoModuleLevelChanges
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createInferAddressSpacesPass(unsigned AddressSpace=~0u)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)