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;
167 InferAddressSpaces() :
169 InferAddressSpaces(
unsigned AS) :
FunctionPass(
ID), FlatAddrSpace(AS) {}
181class InferAddressSpacesImpl {
189 unsigned FlatAddrSpace = 0;
193 bool updateAddressSpace(
const Value &V,
194 ValueToAddrSpaceMapTy &InferredAddrSpace,
195 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
200 ValueToAddrSpaceMapTy &InferredAddrSpace,
201 PredicatedAddrSpaceMapTy &PredicatedAS)
const;
203 bool isSafeToCastConstAddrSpace(
Constant *
C,
unsigned NewAS)
const;
205 Value *cloneInstructionWithNewAddressSpace(
208 const PredicatedAddrSpaceMapTy &PredicatedAS,
216 const ValueToAddrSpaceMapTy &InferredAddrSpace,
217 const PredicatedAddrSpaceMapTy &PredicatedAS,
220 void appendsFlatAddressExpressionToPostorderStack(
221 Value *V, PostorderStackTy &PostorderStack,
227 PostorderStackTy &PostorderStack,
230 std::vector<WeakTrackingVH> collectFlatAddressExpressions(
Function &
F)
const;
232 Value *cloneValueWithNewAddressSpace(
233 Value *V,
unsigned NewAddrSpace,
235 const PredicatedAddrSpaceMapTy &PredicatedAS,
237 unsigned joinAddressSpaces(
unsigned AS1,
unsigned AS2)
const;
239 unsigned getPredicatedAddrSpace(
const Value &V,
Value *Opnd)
const;
244 : AC(AC), DT(DT),
TTI(
TTI), FlatAddrSpace(FlatAddrSpace) {}
250char InferAddressSpaces::ID = 0;
264 assert(I2P->getOpcode() == Instruction::IntToPtr);
265 auto *P2I = dyn_cast<Operator>(I2P->getOperand(0));
266 if (!P2I || P2I->getOpcode() != Instruction::PtrToInt)
282 unsigned P2IOp0AS = P2I->getOperand(0)->getType()->getPointerAddressSpace();
283 unsigned I2PAS = I2P->getType()->getPointerAddressSpace();
285 I2P->getOperand(0)->getType(), I2P->getType(),
288 P2I->getOperand(0)->getType(), P2I->getType(),
298 const Operator *Op = dyn_cast<Operator>(&V);
302 switch (Op->getOpcode()) {
303 case Instruction::PHI:
304 assert(Op->getType()->isPointerTy());
306 case Instruction::BitCast:
307 case Instruction::AddrSpaceCast:
308 case Instruction::GetElementPtr:
310 case Instruction::Select:
311 return Op->getType()->isPointerTy();
312 case Instruction::Call: {
316 case Instruction::IntToPtr:
330 const Operator &Op = cast<Operator>(V);
331 switch (Op.getOpcode()) {
332 case Instruction::PHI: {
333 auto IncomingValues = cast<PHINode>(Op).incoming_values();
334 return {IncomingValues.begin(), IncomingValues.end()};
336 case Instruction::BitCast:
337 case Instruction::AddrSpaceCast:
338 case Instruction::GetElementPtr:
339 return {Op.getOperand(0)};
340 case Instruction::Select:
341 return {Op.getOperand(1), Op.getOperand(2)};
342 case Instruction::Call: {
345 "unexpected intrinsic call");
348 case Instruction::IntToPtr: {
350 auto *P2I = cast<Operator>(Op.getOperand(0));
351 return {P2I->getOperand(0)};
358bool InferAddressSpacesImpl::rewriteIntrinsicOperands(
IntrinsicInst *II,
364 case Intrinsic::objectsize: {
373 case Intrinsic::ptrmask:
387void InferAddressSpacesImpl::collectRewritableIntrinsicOperands(
392 case Intrinsic::ptrmask:
393 case Intrinsic::objectsize:
394 appendsFlatAddressExpressionToPostorderStack(II->
getArgOperand(0),
395 PostorderStack, Visited);
400 for (
int Idx : OpIndexes) {
402 PostorderStack, Visited);
412void InferAddressSpacesImpl::appendsFlatAddressExpressionToPostorderStack(
413 Value *V, PostorderStackTy &PostorderStack,
415 assert(
V->getType()->isPointerTy());
422 PostorderStack.emplace_back(CE,
false);
427 if (
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
429 if (Visited.
insert(V).second) {
430 PostorderStack.emplace_back(V,
false);
433 for (
unsigned I = 0,
E =
Op->getNumOperands();
I !=
E; ++
I) {
436 PostorderStack.emplace_back(CE,
false);
445std::vector<WeakTrackingVH>
446InferAddressSpacesImpl::collectFlatAddressExpressions(
Function &
F)
const {
449 PostorderStackTy PostorderStack;
453 auto PushPtrOperand = [&](
Value *
Ptr) {
454 appendsFlatAddressExpressionToPostorderStack(
Ptr, PostorderStack,
462 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(&
I)) {
463 if (!
GEP->getType()->isVectorTy())
464 PushPtrOperand(
GEP->getPointerOperand());
465 }
else if (
auto *LI = dyn_cast<LoadInst>(&
I))
466 PushPtrOperand(LI->getPointerOperand());
467 else if (
auto *SI = dyn_cast<StoreInst>(&
I))
468 PushPtrOperand(
SI->getPointerOperand());
469 else if (
auto *RMW = dyn_cast<AtomicRMWInst>(&
I))
470 PushPtrOperand(RMW->getPointerOperand());
471 else if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(&
I))
472 PushPtrOperand(CmpX->getPointerOperand());
473 else if (
auto *
MI = dyn_cast<MemIntrinsic>(&
I)) {
475 PushPtrOperand(
MI->getRawDest());
478 if (
auto *MTI = dyn_cast<MemTransferInst>(
MI))
479 PushPtrOperand(MTI->getRawSource());
480 }
else if (
auto *II = dyn_cast<IntrinsicInst>(&
I))
481 collectRewritableIntrinsicOperands(II, PostorderStack, Visited);
482 else if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(&
I)) {
484 if (
Cmp->getOperand(0)->getType()->isPointerTy()) {
485 PushPtrOperand(
Cmp->getOperand(0));
486 PushPtrOperand(
Cmp->getOperand(1));
488 }
else if (
auto *ASC = dyn_cast<AddrSpaceCastInst>(&
I)) {
489 if (!ASC->getType()->isVectorTy())
490 PushPtrOperand(ASC->getPointerOperand());
491 }
else if (
auto *I2P = dyn_cast<IntToPtrInst>(&
I)) {
494 cast<Operator>(I2P->getOperand(0))->getOperand(0));
498 std::vector<WeakTrackingVH> Postorder;
499 while (!PostorderStack.empty()) {
500 Value *TopVal = PostorderStack.back().getPointer();
503 if (PostorderStack.back().getInt()) {
505 Postorder.push_back(TopVal);
506 PostorderStack.pop_back();
510 PostorderStack.back().setInt(
true);
514 appendsFlatAddressExpressionToPostorderStack(PtrOperand, PostorderStack,
526 const Use &OperandUse,
unsigned NewAddrSpace,
528 const PredicatedAddrSpaceMapTy &PredicatedAS,
532 Type *NewPtrTy = PointerType::getWithSamePointeeType(
533 cast<PointerType>(Operand->
getType()), NewAddrSpace);
535 if (
Constant *
C = dyn_cast<Constant>(Operand))
538 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand))
542 auto I = PredicatedAS.find(std::make_pair(Inst, Operand));
543 if (
I != PredicatedAS.end()) {
545 unsigned NewAS =
I->second;
546 Type *NewPtrTy = PointerType::getWithSamePointeeType(
547 cast<PointerType>(Operand->
getType()), NewAS);
549 NewI->insertBefore(Inst);
570Value *InferAddressSpacesImpl::cloneInstructionWithNewAddressSpace(
573 const PredicatedAddrSpaceMapTy &PredicatedAS,
575 Type *NewPtrType = PointerType::getWithSamePointeeType(
576 cast<PointerType>(
I->getType()), NewAddrSpace);
578 if (
I->getOpcode() == Instruction::AddrSpaceCast) {
579 Value *Src =
I->getOperand(0);
583 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
584 if (Src->getType() != NewPtrType)
595 PredicatedAS, UndefUsesToFix);
599 assert(Rewrite != II &&
"cannot modify this pointer operation in place");
610 Type *NewPtrTy = PointerType::getWithSamePointeeType(
611 cast<PointerType>(
I->getType()), AS);
613 NewI->insertAfter(
I);
619 for (
const Use &OperandUse :
I->operands()) {
620 if (!OperandUse.get()->getType()->isPointerTy())
624 OperandUse, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS,
628 switch (
I->getOpcode()) {
629 case Instruction::BitCast:
630 return new BitCastInst(NewPointerOperands[0], NewPtrType);
631 case Instruction::PHI: {
632 assert(
I->getType()->isPointerTy());
642 case Instruction::GetElementPtr: {
645 GEP->getSourceElementType(), NewPointerOperands[0],
650 case Instruction::Select:
651 assert(
I->getType()->isPointerTy());
653 NewPointerOperands[2],
"",
nullptr,
I);
654 case Instruction::IntToPtr: {
656 Value *Src = cast<Operator>(
I->getOperand(0))->getOperand(0);
657 if (Src->getType() == NewPtrType)
677 Type *TargetType = CE->getType()->isPointerTy()
678 ? PointerType::getWithSamePointeeType(
679 cast<PointerType>(CE->getType()), NewAddrSpace)
682 if (CE->getOpcode() == Instruction::AddrSpaceCast) {
686 assert(CE->getOperand(0)->getType()->getPointerAddressSpace() ==
691 if (CE->getOpcode() == Instruction::BitCast) {
692 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(CE->getOperand(0)))
697 if (CE->getOpcode() == Instruction::IntToPtr) {
699 Constant *Src = cast<ConstantExpr>(CE->getOperand(0))->getOperand(0);
700 assert(Src->getType()->getPointerAddressSpace() == NewAddrSpace);
714 if (
Value *NewOperand = ValueWithNewAddrSpace.
lookup(Operand)) {
716 NewOperands.
push_back(cast<Constant>(NewOperand));
719 if (
auto *CExpr = dyn_cast<ConstantExpr>(Operand))
721 CExpr, NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI)) {
723 NewOperands.
push_back(cast<Constant>(NewOperand));
735 if (CE->getOpcode() == Instruction::GetElementPtr) {
738 return CE->getWithOperands(NewOperands, TargetType,
false,
739 cast<GEPOperator>(CE)->getSourceElementType());
742 return CE->getWithOperands(NewOperands, TargetType);
750Value *InferAddressSpacesImpl::cloneValueWithNewAddressSpace(
751 Value *V,
unsigned NewAddrSpace,
753 const PredicatedAddrSpaceMapTy &PredicatedAS,
756 assert(
V->getType()->getPointerAddressSpace() == FlatAddrSpace &&
760 Value *NewV = cloneInstructionWithNewAddressSpace(
761 I, NewAddrSpace, ValueWithNewAddrSpace, PredicatedAS, UndefUsesToFix);
762 if (
Instruction *NewI = dyn_cast_or_null<Instruction>(NewV)) {
763 if (NewI->getParent() ==
nullptr) {
764 NewI->insertBefore(
I);
766 NewI->setDebugLoc(
I->getDebugLoc());
773 cast<ConstantExpr>(V), NewAddrSpace, ValueWithNewAddrSpace,
DL,
TTI);
778unsigned InferAddressSpacesImpl::joinAddressSpaces(
unsigned AS1,
779 unsigned AS2)
const {
780 if (AS1 == FlatAddrSpace || AS2 == FlatAddrSpace)
781 return FlatAddrSpace;
789 return (AS1 == AS2) ? AS1 : FlatAddrSpace;
792bool InferAddressSpacesImpl::run(
Function &
F) {
793 DL = &
F.getParent()->getDataLayout();
805 std::vector<WeakTrackingVH> Postorder = collectFlatAddressExpressions(
F);
809 ValueToAddrSpaceMapTy InferredAddrSpace;
810 PredicatedAddrSpaceMapTy PredicatedAS;
811 inferAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS);
815 return rewriteWithNewAddressSpaces(Postorder, InferredAddrSpace, PredicatedAS,
821void InferAddressSpacesImpl::inferAddressSpaces(
823 ValueToAddrSpaceMapTy &InferredAddrSpace,
824 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
827 for (
Value *V : Postorder)
830 while (!Worklist.empty()) {
831 Value *
V = Worklist.pop_back_val();
835 if (!updateAddressSpace(*V, InferredAddrSpace, PredicatedAS))
840 if (Worklist.count(
User))
843 auto Pos = InferredAddrSpace.find(
User);
846 if (Pos == InferredAddrSpace.end())
852 if (Pos->second == FlatAddrSpace)
855 Worklist.insert(
User);
860unsigned InferAddressSpacesImpl::getPredicatedAddrSpace(
const Value &V,
867 for (
auto &AssumeVH : AC.assumptionsFor(Opnd)) {
870 CallInst *CI = cast<CallInst>(AssumeVH);
884bool InferAddressSpacesImpl::updateAddressSpace(
885 const Value &V, ValueToAddrSpaceMapTy &InferredAddrSpace,
886 PredicatedAddrSpaceMapTy &PredicatedAS)
const {
887 assert(InferredAddrSpace.count(&V));
889 LLVM_DEBUG(
dbgs() <<
"Updating the address space of\n " << V <<
'\n');
896 if (
Op.getOpcode() == Instruction::Select) {
897 Value *Src0 =
Op.getOperand(1);
898 Value *Src1 =
Op.getOperand(2);
900 auto I = InferredAddrSpace.find(Src0);
901 unsigned Src0AS = (
I != InferredAddrSpace.end()) ?
904 auto J = InferredAddrSpace.find(Src1);
905 unsigned Src1AS = (J != InferredAddrSpace.end()) ?
908 auto *C0 = dyn_cast<Constant>(Src0);
909 auto *C1 = dyn_cast<Constant>(Src1);
918 if (C0 && isSafeToCastConstAddrSpace(C0, Src1AS))
920 else if (C1 && isSafeToCastConstAddrSpace(C1, Src0AS))
923 NewAS = joinAddressSpaces(Src0AS, Src1AS);
932 auto I = InferredAddrSpace.find(PtrOperand);
934 if (
I == InferredAddrSpace.end()) {
935 OperandAS = PtrOperand->getType()->getPointerAddressSpace();
936 if (OperandAS == FlatAddrSpace) {
938 unsigned AS = getPredicatedAddrSpace(V, PtrOperand);
941 <<
" deduce operand AS from the predicate addrspace "
945 PredicatedAS[std::make_pair(&V, PtrOperand)] = OperandAS;
949 OperandAS =
I->second;
952 NewAS = joinAddressSpaces(NewAS, OperandAS);
953 if (NewAS == FlatAddrSpace)
959 unsigned OldAS = InferredAddrSpace.lookup(&V);
960 assert(OldAS != FlatAddrSpace);
967 InferredAddrSpace[&
V] = NewAS;
977 Use &U,
unsigned AddrSpace) {
978 User *Inst = U.getUser();
979 unsigned OpNo = U.getOperandNo();
980 bool VolatileIsAllowed =
false;
981 if (
auto *
I = dyn_cast<Instruction>(Inst))
984 if (
auto *LI = dyn_cast<LoadInst>(Inst))
986 (VolatileIsAllowed || !LI->isVolatile());
988 if (
auto *
SI = dyn_cast<StoreInst>(Inst))
990 (VolatileIsAllowed || !
SI->isVolatile());
992 if (
auto *RMW = dyn_cast<AtomicRMWInst>(Inst))
994 (VolatileIsAllowed || !RMW->isVolatile());
996 if (
auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst))
998 (VolatileIsAllowed || !CmpX->isVolatile());
1009 MDNode *TBAA =
MI->getMetadata(LLVMContext::MD_tbaa);
1010 MDNode *ScopeMD =
MI->getMetadata(LLVMContext::MD_alias_scope);
1011 MDNode *NoAliasMD =
MI->getMetadata(LLVMContext::MD_noalias);
1013 if (
auto *MSI = dyn_cast<MemSetInst>(
MI)) {
1014 B.CreateMemSet(NewV, MSI->getValue(), MSI->getLength(), MSI->getDestAlign(),
1016 TBAA, ScopeMD, NoAliasMD);
1017 }
else if (
auto *MTI = dyn_cast<MemTransferInst>(
MI)) {
1018 Value *Src = MTI->getRawSource();
1019 Value *Dest = MTI->getRawDest();
1028 if (isa<MemCpyInlineInst>(MTI)) {
1029 MDNode *TBAAStruct = MTI->getMetadata(LLVMContext::MD_tbaa_struct);
1030 B.CreateMemCpyInline(Dest, MTI->getDestAlign(), Src,
1031 MTI->getSourceAlign(), MTI->getLength(),
1033 TBAA, TBAAStruct, ScopeMD, NoAliasMD);
1034 }
else if (isa<MemCpyInst>(MTI)) {
1035 MDNode *TBAAStruct = MTI->getMetadata(LLVMContext::MD_tbaa_struct);
1036 B.CreateMemCpy(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1039 TBAA, TBAAStruct, ScopeMD, NoAliasMD);
1041 assert(isa<MemMoveInst>(MTI));
1042 B.CreateMemMove(Dest, MTI->getDestAlign(), Src, MTI->getSourceAlign(),
1045 TBAA, ScopeMD, NoAliasMD);
1050 MI->eraseFromParent();
1056bool InferAddressSpacesImpl::isSafeToCastConstAddrSpace(
Constant *
C,
1057 unsigned NewAS)
const {
1060 unsigned SrcAS =
C->getType()->getPointerAddressSpace();
1061 if (SrcAS == NewAS || isa<UndefValue>(
C))
1065 if (SrcAS != FlatAddrSpace && NewAS != FlatAddrSpace)
1068 if (isa<ConstantPointerNull>(
C))
1071 if (
auto *Op = dyn_cast<Operator>(
C)) {
1074 if (
Op->getOpcode() == Instruction::AddrSpaceCast)
1075 return isSafeToCastConstAddrSpace(cast<Constant>(
Op->getOperand(0)), NewAS);
1077 if (
Op->getOpcode() == Instruction::IntToPtr &&
1078 Op->getType()->getPointerAddressSpace() == FlatAddrSpace)
1087 User *CurUser =
I->getUser();
1090 while (
I != End &&
I->getUser() == CurUser)
1096bool InferAddressSpacesImpl::rewriteWithNewAddressSpaces(
1098 const ValueToAddrSpaceMapTy &InferredAddrSpace,
1099 const PredicatedAddrSpaceMapTy &PredicatedAS,
Function *
F)
const {
1106 for (
Value* V : Postorder) {
1107 unsigned NewAddrSpace = InferredAddrSpace.lookup(V);
1114 if (
V->getType()->getPointerAddressSpace() != NewAddrSpace) {
1116 cloneValueWithNewAddressSpace(V, NewAddrSpace, ValueWithNewAddrSpace,
1117 PredicatedAS, &UndefUsesToFix);
1119 ValueWithNewAddrSpace[
V] =
New;
1123 if (ValueWithNewAddrSpace.
empty())
1127 for (
const Use *UndefUse : UndefUsesToFix) {
1128 User *
V = UndefUse->getUser();
1129 User *NewV = cast_or_null<User>(ValueWithNewAddrSpace.
lookup(V));
1133 unsigned OperandNo = UndefUse->getOperandNo();
1135 NewV->
setOperand(OperandNo, ValueWithNewAddrSpace.
lookup(UndefUse->get()));
1142 assert(WVH &&
"value was unexpectedly deleted");
1145 if (NewV ==
nullptr)
1148 LLVM_DEBUG(
dbgs() <<
"Replacing the uses of " << *V <<
"\n with\n "
1151 if (
Constant *
C = dyn_cast<Constant>(V)) {
1155 LLVM_DEBUG(
dbgs() <<
"Inserting replacement const cast: " << Replace
1156 <<
": " << *Replace <<
'\n');
1157 C->replaceAllUsesWith(Replace);
1163 for (
I =
V->use_begin(),
E =
V->use_end();
I !=
E; ) {
1171 *
TTI, U,
V->getType()->getPointerAddressSpace())) {
1179 User *CurUser =
U.getUser();
1181 if (CurUser == NewV)
1184 if (
auto *
MI = dyn_cast<MemIntrinsic>(CurUser)) {
1189 if (
auto *II = dyn_cast<IntrinsicInst>(CurUser)) {
1190 if (rewriteIntrinsicOperands(II, V, NewV))
1194 if (isa<Instruction>(CurUser)) {
1195 if (
ICmpInst *Cmp = dyn_cast<ICmpInst>(CurUser)) {
1203 int SrcIdx =
U.getOperandNo();
1204 int OtherIdx = (SrcIdx == 0) ? 1 : 0;
1205 Value *OtherSrc =
Cmp->getOperand(OtherIdx);
1207 if (
Value *OtherNewV = ValueWithNewAddrSpace.
lookup(OtherSrc)) {
1208 if (OtherNewV->getType()->getPointerAddressSpace() == NewAS) {
1209 Cmp->setOperand(OtherIdx, OtherNewV);
1210 Cmp->setOperand(SrcIdx, NewV);
1216 if (
auto *KOtherSrc = dyn_cast<Constant>(OtherSrc)) {
1217 if (isSafeToCastConstAddrSpace(KOtherSrc, NewAS)) {
1218 Cmp->setOperand(SrcIdx, NewV);
1219 Cmp->setOperand(OtherIdx,
1228 if (ASC->getDestAddressSpace() == NewAS) {
1229 if (!cast<PointerType>(ASC->getType())
1230 ->hasSameElementTypeAs(
1231 cast<PointerType>(NewV->
getType()))) {
1233 if (
Instruction *NewVInst = dyn_cast<Instruction>(NewV))
1234 InsertPos = std::next(NewVInst->getIterator());
1235 else if (
Instruction *VInst = dyn_cast<Instruction>(V))
1236 InsertPos = std::next(VInst->getIterator());
1238 InsertPos = ASC->getIterator();
1241 ASC->getType(),
"", &*InsertPos);
1243 ASC->replaceAllUsesWith(NewV);
1250 if (
Instruction *VInst = dyn_cast<Instruction>(V)) {
1252 if (U == V && isa<AddrSpaceCastInst>(V))
1257 if (
Instruction *NewVInst = dyn_cast<Instruction>(NewV))
1258 InsertPos = std::next(NewVInst->getIterator());
1260 InsertPos = std::next(VInst->getIterator());
1262 while (isa<PHINode>(InsertPos))
1272 if (
V->use_empty()) {
1284bool InferAddressSpaces::runOnFunction(
Function &
F) {
1285 if (skipFunction(
F))
1288 auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
1290 return InferAddressSpacesImpl(
1291 getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
F), DT,
1292 &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F),
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-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 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 Value * operandWithNewAddressSpaceOrCreateUndef(const Use &OperandUse, unsigned NewAddrSpace, const ValueToValueMapTy &ValueWithNewAddrSpace, const PredicatedAddrSpaceMapTy &PredicatedAS, SmallVectorImpl< const Use * > *UndefUsesToFix)
static SmallVector< Value *, 2 > getPointerOperands(const Value &V, const DataLayout &DL, const TargetTransformInfo *TTI)
static Value * cloneConstantExprWithNewAddressSpace(ConstantExpr *CE, unsigned NewAddrSpace, const ValueToValueMapTy &ValueWithNewAddrSpace, const DataLayout *DL, const TargetTransformInfo *TTI)
Infer address static false bool isNoopPtrIntCastPair(const Operator *I2P, 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)
static const unsigned UninitializedAddressSpace
print must be executed print the must be executed context for all instructions
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 * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
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.
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
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
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...
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="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static unsigned getOperandNumForIncomingValue(unsigned i)
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
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="", Instruction *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 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.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
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...
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 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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createInferAddressSpacesPass(unsigned AddressSpace=~0u)
bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI, const DominatorTree *DT=nullptr)
Return true if it is valid to use the assumptions provided by an assume intrinsic,...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)