136#define DEBUG_TYPE "infer-address-spaces"
142 cl::desc(
"The default address space is assumed as the flat address space. "
143 "This is mainly for test purpose."));
146 std::numeric_limits<unsigned>::max();
157using PredicatedAddrSpaceMapTy =
162 unsigned FlatAddrSpace = 0;
171 InferAddressSpaces(
unsigned AS) :
FunctionPass(
ID), FlatAddrSpace(AS) {
185class 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,
220 const ValueToAddrSpaceMapTy &InferredAddrSpace,
221 const PredicatedAddrSpaceMapTy &PredicatedAS,
224 void appendsFlatAddressExpressionToPostorderStack(
225 Value *V, PostorderStackTy &PostorderStack,
231 PostorderStackTy &PostorderStack,
234 std::vector<WeakTrackingVH> collectFlatAddressExpressions(
Function &
F)
const;
236 Value *cloneValueWithNewAddressSpace(
237 Value *V,
unsigned NewAddrSpace,
239 const PredicatedAddrSpaceMapTy &PredicatedAS,
241 unsigned joinAddressSpaces(
unsigned AS1,
unsigned AS2)
const;
243 unsigned getPredicatedAddrSpace(
const Value &V,
Value *Opnd)
const;
248 : AC(AC), DT(DT),
TTI(
TTI), FlatAddrSpace(FlatAddrSpace) {}
254char InferAddressSpaces::ID = 0;
264 assert(Ty->isPtrOrPtrVectorTy());
265 PointerType *NPT = PointerType::get(Ty->getContext(), NewAddrSpace);
266 return Ty->getWithNewType(NPT);
275 auto *P2I = dyn_cast<Operator>(I2P->
getOperand(0));
276 if (!P2I || P2I->getOpcode() != Instruction::PtrToInt)
292 unsigned P2IOp0AS = P2I->getOperand(0)->getType()->getPointerAddressSpace();
298 P2I->getOperand(0)->getType(), P2I->getType(),
312 switch (
Op->getOpcode()) {
313 case Instruction::PHI:
314 assert(
Op->getType()->isPtrOrPtrVectorTy());
316 case Instruction::BitCast:
317 case Instruction::AddrSpaceCast:
318 case Instruction::GetElementPtr:
320 case Instruction::Select:
321 return Op->getType()->isPtrOrPtrVectorTy();
322 case Instruction::Call: {
326 case Instruction::IntToPtr:
341 switch (
Op.getOpcode()) {
342 case Instruction::PHI: {
343 auto IncomingValues = cast<PHINode>(
Op).incoming_values();
344 return {IncomingValues.begin(), IncomingValues.end()};
346 case Instruction::BitCast:
347 case Instruction::AddrSpaceCast:
348 case Instruction::GetElementPtr:
349 return {
Op.getOperand(0)};
350 case Instruction::Select:
351 return {
Op.getOperand(1),
Op.getOperand(2)};
352 case Instruction::Call: {
355 "unexpected intrinsic call");
358 case Instruction::IntToPtr: {
360 auto *P2I = cast<Operator>(
Op.getOperand(0));
361 return {P2I->getOperand(0)};
368bool InferAddressSpacesImpl::rewriteIntrinsicOperands(
IntrinsicInst *II,
374 case Intrinsic::objectsize: {
383 case Intrinsic::ptrmask:
386 case Intrinsic::masked_gather: {
395 case Intrinsic::masked_scatter: {
415void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
420 case Intrinsic::ptrmask:
421 case Intrinsic::objectsize:
422 appendsFlatAddressExpressionToPostorderStack(II->
getArgOperand(0),
423 PostorderStack, Visited);
425 case Intrinsic::masked_gather:
426 appendsFlatAddressExpressionToPostorderStack(II->
getArgOperand(0),
427 PostorderStack, Visited);
429 case Intrinsic::masked_scatter:
430 appendsFlatAddressExpressionToPostorderStack(II->
getArgOperand(1),
431 PostorderStack, Visited);
436 for (
int Idx : OpIndexes) {
438 PostorderStack, Visited);
448void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
449 Value *V, PostorderStackTy &PostorderStack,
451 assert(
V->getType()->isPtrOrPtrVectorTy());
458 PostorderStack.emplace_back(CE,
false);
463 if (
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
465 if (Visited.
insert(V).second) {
466 PostorderStack.emplace_back(V,
false);
472 PostorderStack.emplace_back(CE,
false);
481std::vector<WeakTrackingVH>
482InferAddressSpacesImpl::collectFlatAddressExpressions(
Function &
F)
const {
485 PostorderStackTy PostorderStack;
489 auto PushPtrOperand = [&](
Value *
Ptr) {
490 appendsFlatAddressExpressionToPostorderStack(
Ptr, PostorderStack, Visited);
497 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(&
I)) {
498 PushPtrOperand(
GEP->getPointerOperand());
499 }
else if (
auto *LI = dyn_cast<LoadInst>(&
I))
500 PushPtrOperand(LI->getPointerOperand());
501 else if (
auto *SI = dyn_cast<StoreInst>(&
I))
502 PushPtrOperand(
SI->getPointerOperand());
503 else if (
auto *RMW = dyn_cast<AtomicRMWInst>(&
I))
504 PushPtrOperand(RMW->getPointerOperand());
505 else if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(&
I))
506 PushPtrOperand(CmpX->getPointerOperand());
507 else if (
auto *
MI = dyn_cast<MemIntrinsic>(&
I)) {
509 PushPtrOperand(
MI->getRawDest());
512 if (
auto *MTI = dyn_cast<MemTransferInst>(
MI))
513 PushPtrOperand(MTI->getRawSource());
514 }
else if (
auto *II = dyn_cast<IntrinsicInst>(&
I))
515 collectRewritableIntrinsicOperands(II, PostorderStack, Visited);
516 else if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(&
I)) {
517 if (
Cmp->getOperand(0)->getType()->isPtrOrPtrVectorTy()) {
518 PushPtrOperand(
Cmp->getOperand(0));
519 PushPtrOperand(
Cmp->getOperand(1));
521 }
else if (
auto *ASC = dyn_cast<AddrSpaceCastInst>(&
I)) {
522 PushPtrOperand(ASC->getPointerOperand());
523 }
else if (
auto *I2P = dyn_cast<IntToPtrInst>(&
I)) {
525 PushPtrOperand(cast<Operator>(I2P->getOperand(0))->getOperand(0));
526 }
else if (
auto *RI = dyn_cast<ReturnInst>(&
I)) {
527 if (
auto *RV = RI->getReturnValue();
528 RV && RV->getType()->isPtrOrPtrVectorTy())
533 std::vector<WeakTrackingVH> Postorder;
534 while (!PostorderStack.empty()) {
535 Value *TopVal = PostorderStack.back().getPointer();
538 if (PostorderStack.back().getInt()) {
540 Postorder.push_back(TopVal);
541 PostorderStack.pop_back();
545 PostorderStack.back().setInt(
true);
549 appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
561 const Use &OperandUse,
unsigned NewAddrSpace,
563 const PredicatedAddrSpaceMapTy &PredicatedAS,
569 if (
Constant *
C = dyn_cast<Constant>(Operand))
572 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand))
576 auto I = PredicatedAS.find(std::make_pair(Inst, Operand));
577 if (
I != PredicatedAS.end()) {
579 unsigned NewAS =
I->second;
582 NewI->insertBefore(Inst);
603Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
606 const PredicatedAddrSpaceMapTy &PredicatedAS,
610 if (
I->getOpcode() == Instruction::AddrSpaceCast) {
611 Value *Src =
I->getOperand(0);
615 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
616 if (Src->getType() != NewPtrType)
627 PredicatedAS, PoisonUsesToFix);
631 assert(Rewrite != II &&
"cannot modify this pointer operation in place");
644 NewI->insertAfter(
I);
650 for (
const Use &OperandUse :
I->operands()) {
651 if (!OperandUse.get()->getType()->isPtrOrPtrVectorTy())
655 OperandUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
659 switch (
I->getOpcode()) {
660 case Instruction::BitCast:
661 return new BitCastInst(NewPointerOperands[0], NewPtrType);
662 case Instruction::PHI: {
663 assert(
I->getType()->isPtrOrPtrVectorTy());
673 case Instruction::GetElementPtr: {
676 GEP->getSourceElementType(), NewPointerOperands[0],
681 case Instruction::Select:
682 assert(
I->getType()->isPtrOrPtrVectorTy());
684 NewPointerOperands[2],
"",
nullptr,
I);
685 case Instruction::IntToPtr: {
687 Value *Src = cast<Operator>(
I->getOperand(0))->getOperand(0);
688 if (Src->getType() == NewPtrType)
709 CE->getType()->isPtrOrPtrVectorTy()
713 if (CE->getOpcode() == Instruction::AddrSpaceCast) {
717 assert(CE->getOperand(0)->getType()->getPointerAddressSpace() ==
722 if (CE->getOpcode() == Instruction::BitCast) {
723 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(CE->getOperand(0)))
728 if (CE->getOpcode() == Instruction::IntToPtr) {
730 Constant *Src = cast<ConstantExpr>(CE->getOperand(0))->getOperand(0);
731 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
745 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand)) {
747 NewOperands.
push_back(cast<Constant>(NewOperand));
750 if (
auto *CExpr = dyn_cast<ConstantExpr>(Operand))
752 CExpr, NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI)) {
754 NewOperands.
push_back(cast<Constant>(NewOperand));
766 if (CE->getOpcode() == Instruction::GetElementPtr) {
769 return CE->getWithOperands(NewOperands, TargetType,
false,
770 cast<GEPOperator>(CE)->getSourceElementType());
773 return CE->getWithOperands(NewOperands, TargetType);
781Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
782 Value *V,
unsigned NewAddrSpace,
784 const PredicatedAddrSpaceMapTy &PredicatedAS,
787 assert(
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
791 Value *NewV = cloneInstructionWithNewAddressSpace(
792 I, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, PoisonUsesToFix);
793 if (
Instruction *NewI = dyn_cast_or_null<Instruction>(NewV)) {
794 if (NewI->getParent() ==
nullptr) {
795 NewI->insertBefore(
I);
797 NewI->setDebugLoc(
I->getDebugLoc());
804 cast<ConstantExpr>(V), NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI);
809unsigned InferAddressSpacesImpl::joinAddressSpaces(
unsigned AS1,
810 unsigned AS2)
const {
811 if (AS1 == FlatAddrSpace || AS2 == FlatAddrSpace)
812 return FlatAddrSpace;
820 return (AS1 == AS2) ? AS1 : FlatAddrSpace;
823bool InferAddressSpacesImpl::run(
Function &
F) {
824 DL = &
F.getParent()->getDataLayout();
836 std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions(
F);
840 ValueToAddrSpaceMapTy InferredAddrSpace;
841 PredicatedAddrSpaceMapTy PredicatedAS;
842 inferAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS);
846 return rewriteWithNewAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS,
852void InferAddressSpacesImpl::inferAddressSpaces(
854 ValueToAddrSpaceMapTy &InferredAddrSpace,
855 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
858 for (
Value *V : Postorder)
861 while (!Worklist.empty()) {
862 Value *
V = Worklist.pop_back_val();
866 if (!updateAddressSpace(*V, InferredAddrSpace, PredicatedAS))
871 if (Worklist.count(
User))
874 auto Pos = InferredAddrSpace.find(
User);
877 if (Pos == InferredAddrSpace.end())
883 if (Pos->second == FlatAddrSpace)
886 Worklist.insert(
User);
891unsigned InferAddressSpacesImpl::getPredicatedAddrSpace(
const Value &V,
898 for (
auto &AssumeVH : AC.assumptionsFor(Opnd)) {
901 CallInst *CI = cast<CallInst>(AssumeVH);
915bool InferAddressSpacesImpl::updateAddressSpace(
916 const Value &V, ValueToAddrSpaceMapTy &InferredAddrSpace,
917 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
918 assert(InferredAddrSpace.count(&V));
920 LLVM_DEBUG(
dbgs() <<
"Updating the address space of\n " << V <<
'\n');
927 if (
Op.getOpcode() == Instruction::Select) {
928 Value *Src0 =
Op.getOperand(1);
929 Value *Src1 =
Op.getOperand(2);
931 auto I = InferredAddrSpace.find(Src0);
932 unsigned Src0AS = (
I != InferredAddrSpace.end())
936 auto J = InferredAddrSpace.find(Src1);
937 unsigned Src1AS = (J != InferredAddrSpace.end())
941 auto *C0 = dyn_cast<Constant>(Src0);
942 auto *C1 = dyn_cast<Constant>(Src1);
951 if (C0 && isSafeToCastConstAddrSpace(C0, Src1AS))
953 else if (C1 && isSafeToCastConstAddrSpace(C1, Src0AS))
956 NewAS = joinAddressSpaces(Src0AS, Src1AS);
965 auto I = InferredAddrSpace.find(PtrOperand);
967 if (
I == InferredAddrSpace.end()) {
968 OperandAS = PtrOperand->getType()->getPointerAddressSpace();
969 if (OperandAS == FlatAddrSpace) {
971 unsigned AS = getPredicatedAddrSpace(V, PtrOperand);
974 <<
" deduce operand AS from the predicate addrspace "
978 PredicatedAS[std::make_pair(&V, PtrOperand)] = OperandAS;
982 OperandAS =
I->second;
985 NewAS = joinAddressSpaces(NewAS, OperandAS);
986 if (NewAS == FlatAddrSpace)
992 unsigned OldAS = InferredAddrSpace.lookup(&V);
993 assert(OldAS != FlatAddrSpace);
1000 InferredAddrSpace[&
V] = NewAS;
1010 Use &U,
unsigned AddrSpace) {
1011 User *Inst = U.getUser();
1012 unsigned OpNo = U.getOperandNo();
1013 bool VolatileIsAllowed =
false;
1014 if (
auto *
I = dyn_cast<Instruction>(Inst))
1017 if (
auto *LI = dyn_cast<LoadInst>(Inst))
1019 (VolatileIsAllowed || !LI->isVolatile());
1021 if (
auto *SI = dyn_cast<StoreInst>(Inst))
1023 (VolatileIsAllowed || !SI->isVolatile());
1025 if (
auto *RMW = dyn_cast<AtomicRMWInst>(Inst))
1027 (VolatileIsAllowed || !RMW->isVolatile());
1029 if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst))
1031 (VolatileIsAllowed || !CmpX->isVolatile());
1042 MDNode *TBAA =
MI->getMetadata(LLVMContext::MD_tbaa);
1043 MDNode *ScopeMD =
MI->getMetadata(LLVMContext::MD_alias_scope);
1044 MDNode *NoAliasMD =
MI->getMetadata(LLVMContext::MD_noalias);
1046 if (
auto *MSI = dyn_cast<MemSetInst>(
MI)) {
1047 B.CreateMemSet(NewV, MSI->getValue(), MSI->getLength(), MSI->getDestAlign(),
1049 TBAA, ScopeMD, NoAliasMD);
1050 }
else if (
auto *MTI = dyn_cast<MemTransferInst>(
MI)) {
1051 Value *Src = MTI->getRawSource();
1052 Value *Dest = MTI->getRawDest();
1061 if (isa<MemCpyInlineInst>(MTI)) {
1062 MDNode *TBAAStruct = MTI->getMetadata(LLVMContext::MD_tbaa_struct);
1063 B.CreateMemCpyInline(Dest, MTI->getDestAlign(), Src,
1064 MTI->getSourceAlign(), MTI->getLength(),
1066 TBAA, TBAAStruct, ScopeMD, NoAliasMD);
1067 }
else if (isa<MemCpyInst>(MTI)) {
1068 MDNode *TBAAStruct = MTI->getMetadata(LLVMContext::MD_tbaa_struct);
1069 B.CreateMemCpy(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1072 TBAA, TBAAStruct, ScopeMD, NoAliasMD);
1074 assert(isa<MemMoveInst>(MTI));
1075 B.CreateMemMove(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1078 TBAA, ScopeMD, NoAliasMD);
1083 MI->eraseFromParent();
1089bool InferAddressSpacesImpl::isSafeToCastConstAddrSpace(
Constant *
C,
1090 unsigned NewAS)
const {
1093 unsigned SrcAS =
C->getType()->getPointerAddressSpace();
1094 if (SrcAS == NewAS || isa<UndefValue>(
C))
1098 if (SrcAS != FlatAddrSpace && NewAS != FlatAddrSpace)
1101 if (isa<ConstantPointerNull>(
C))
1104 if (
auto *
Op = dyn_cast<Operator>(
C)) {
1107 if (
Op->getOpcode() == Instruction::AddrSpaceCast)
1108 return isSafeToCastConstAddrSpace(cast<Constant>(
Op->getOperand(0)),
1111 if (
Op->getOpcode() == Instruction::IntToPtr &&
1112 Op->getType()->getPointerAddressSpace() == FlatAddrSpace)
1121 User *CurUser =
I->getUser();
1124 while (
I !=
End &&
I->getUser() == CurUser)
1130bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
1132 const ValueToAddrSpaceMapTy &InferredAddrSpace,
1133 const PredicatedAddrSpaceMapTy &PredicatedAS,
Function *
F)
const {
1140 for (
Value *V : Postorder) {
1141 unsigned NewAddrSpace = InferredAddrSpace.lookup(V);
1148 if (
V->getType()->getPointerAddressSpace() != NewAddrSpace) {
1150 cloneValueWithNewAddressSpace(V, NewAddrSpace, ValueWithNewAddrSpace,
1151 PredicatedAS, &PoisonUsesToFix);
1153 ValueWithNewAddrSpace[
V] =
New;
1157 if (ValueWithNewAddrSpace.
empty())
1161 for (
const Use *PoisonUse : PoisonUsesToFix) {
1162 User *
V = PoisonUse->getUser();
1163 User *NewV = cast_or_null<User>(ValueWithNewAddrSpace.
lookup(V));
1167 unsigned OperandNo = PoisonUse->getOperandNo();
1169 NewV->
setOperand(OperandNo, ValueWithNewAddrSpace.
lookup(PoisonUse->get()));
1178 assert(WVH &&
"value was unexpectedly deleted");
1181 if (NewV ==
nullptr)
1184 LLVM_DEBUG(
dbgs() <<
"Replacing the uses of " << *V <<
"\n with\n "
1187 if (
Constant *
C = dyn_cast<Constant>(V)) {
1191 LLVM_DEBUG(
dbgs() <<
"Inserting replacement const cast: " << Replace
1192 <<
": " << *Replace <<
'\n');
1195 if (
auto *
I = dyn_cast<Instruction>(U)) {
1196 if (
I->getFunction() ==
F)
1197 I->replaceUsesOfWith(
C, Replace);
1199 WorkList.
append(
U->user_begin(),
U->user_end());
1202 if (!WorkList.
empty()) {
1205 while (!WorkList.
empty()) {
1207 if (
auto *
I = dyn_cast<Instruction>(U)) {
1208 if (
I->getFunction() ==
F)
1209 VMapper.remapInstruction(*
I);
1212 for (
User *U2 :
U->users())
1213 if (Visited.
insert(U2).second)
1222 for (
I =
V->use_begin(), E =
V->use_end();
I != E;) {
1224 User *CurUser =
U.getUser();
1231 *
TTI, U,
V->getType()->getPointerAddressSpace())) {
1240 if (CurUser == NewV)
1243 if (
auto *CurUserI = dyn_cast<Instruction>(CurUser);
1244 CurUserI && CurUserI->getFunction() !=
F)
1248 if (
auto *
MI = dyn_cast<MemIntrinsic>(CurUser)) {
1253 if (
auto *II = dyn_cast<IntrinsicInst>(CurUser)) {
1254 if (rewriteIntrinsicOperands(II, V, NewV))
1258 if (isa<Instruction>(CurUser)) {
1259 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(CurUser)) {
1267 int SrcIdx =
U.getOperandNo();
1268 int OtherIdx = (SrcIdx == 0) ? 1 : 0;
1269 Value *OtherSrc =
Cmp->getOperand(OtherIdx);
1271 if (
Value *OtherNewV = ValueWithNewAddrSpace.
lookup(OtherSrc)) {
1272 if (OtherNewV->getType()->getPointerAddressSpace() == NewAS) {
1273 Cmp->setOperand(OtherIdx, OtherNewV);
1274 Cmp->setOperand(SrcIdx, NewV);
1280 if (
auto *KOtherSrc = dyn_cast<Constant>(OtherSrc)) {
1281 if (isSafeToCastConstAddrSpace(KOtherSrc, NewAS)) {
1282 Cmp->setOperand(SrcIdx, NewV);
1292 if (ASC->getDestAddressSpace() == NewAS) {
1293 ASC->replaceAllUsesWith(NewV);
1300 if (
Instruction *VInst = dyn_cast<Instruction>(V)) {
1302 if (U == V && isa<AddrSpaceCastInst>(V))
1307 if (
Instruction *NewVInst = dyn_cast<Instruction>(NewV))
1308 InsertPos = std::next(NewVInst->getIterator());
1310 InsertPos = std::next(VInst->getIterator());
1312 while (isa<PHINode>(InsertPos))
1325 if (
V->use_empty()) {
1337bool InferAddressSpaces::runOnFunction(
Function &
F) {
1338 if (skipFunction(
F))
1341 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
1343 return InferAddressSpacesImpl(
1344 getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F), DT,
1345 &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.
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 bool isSimplePointerUseValidToReplace(const TargetTransformInfo &TTI, Use &U, unsigned AddrSpace)
returns true if U is the pointer operand of a memory instruction with a single pointer operand that c...
static Value::use_iterator skipToNextUser(Value::use_iterator I, Value::use_iterator End)
Infer address static false Type * getPtrOrVecOfPtrsWithNewAS(Type *Ty, unsigned NewAddrSpace)
static const unsigned UninitializedAddressSpace
This header defines various interfaces for pass management in LLVM.
#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 defines the Use 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.
static unsigned getPointerOperandIndex()
static unsigned getPointerOperandIndex()
const Function * getParent() const
Return the enclosing method, or null if none.
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.
const Use & getArgOperandUse(unsigned i) const
Wrappers for getting the Use of a call argument.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
This class represents a function call, abstracting a target machine's calling convention.
static CastInst * CreatePointerBitCastOrAddrSpaceCast(Value *S, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd)
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, BasicBlock::iterator InsertBefore)
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
Module * getParent()
Get the module that this global value is contained inside of...
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.
const BasicBlock * getParent() const
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static unsigned getPointerOperandIndex()
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 PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock::iterator InsertBefore)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static unsigned getOperandNumForIncomingValue(unsigned i)
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, BasicBlock::iterator InsertBefore, 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.
static unsigned getPointerOperandIndex()
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.
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.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
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
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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)