From 8c94d616e111372658237b82035dc5b024e4901b Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 17 Apr 2020 10:10:53 -0700 Subject: [PATCH] Revert "[CallSite removal][MemCpyOptimizer] Replace CallSite with CallBase. NFC" There were extra changes that weren't supposed to be in there This reverts commit b91f78db370bb8161472acd75a67916d033c3348. --- llvm/include/llvm/Transforms/IPO/Attributor.h | 27 +++- .../llvm/Transforms/Scalar/MemCpyOptimizer.h | 3 +- llvm/lib/Transforms/IPO/Attributor.cpp | 91 +++++------ llvm/lib/Transforms/IPO/AttributorAttributes.cpp | 174 +++++++++++---------- llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp | 34 ++-- 5 files changed, 176 insertions(+), 153 deletions(-) diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index 9998977..2363a74 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -217,6 +217,23 @@ struct IRPosition { return IRPosition(const_cast(CB), Kind(ArgNo)); } + /// Create a position describing the function scope of \p ICS. + static const IRPosition callsite_function(ImmutableCallSite ICS) { + return IRPosition::callsite_function(cast(*ICS.getInstruction())); + } + + /// Create a position describing the returned value of \p ICS. + static const IRPosition callsite_returned(ImmutableCallSite ICS) { + return IRPosition::callsite_returned(cast(*ICS.getInstruction())); + } + + /// Create a position describing the argument of \p ICS at position \p ArgNo. + static const IRPosition callsite_argument(ImmutableCallSite ICS, + unsigned ArgNo) { + return IRPosition::callsite_argument(cast(*ICS.getInstruction()), + ArgNo); + } + /// Create a position describing the argument of \p ACS at position \p ArgNo. static const IRPosition callsite_argument(AbstractCallSite ACS, unsigned ArgNo) { @@ -401,9 +418,9 @@ struct IRPosition { return; AttributeList AttrList; - auto *CB = dyn_cast(&getAnchorValue()); - if (CB) - AttrList = CB->getAttributes(); + CallSite CS = CallSite(&getAnchorValue()); + if (CS) + AttrList = CS.getAttributes(); else AttrList = getAssociatedFunction()->getAttributes(); @@ -411,8 +428,8 @@ struct IRPosition { for (Attribute::AttrKind AK : AKs) AttrList = AttrList.removeAttribute(Ctx, getAttrIdx(), AK); - if (CB) - CB->setAttributes(AttrList); + if (CS) + CS.setAttributes(AttrList); else getAssociatedFunction()->setAttributes(AttrList); } diff --git a/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h b/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h index 41180c5..5386f58 100644 --- a/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h +++ b/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h @@ -16,6 +16,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/IR/BasicBlock.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/PassManager.h" #include #include @@ -65,7 +66,7 @@ private: bool processMemCpyMemCpyDependence(MemCpyInst *M, MemCpyInst *MDep); bool processMemSetMemCpyDependence(MemCpyInst *M, MemSetInst *MDep); bool performMemCpyToMemSetOptzn(MemCpyInst *M, MemSetInst *MDep); - bool processByValArgument(CallBase &CB, unsigned ArgNo); + bool processByValArgument(CallSite CS, unsigned ArgNo); Instruction *tryMergingIntoMemset(Instruction *I, Value *StartPtr, Value *ByteVal); diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 9304a92..da1cbcc 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -228,7 +228,7 @@ IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP, case IRPosition::IRP_CALL_SITE: case IRPosition::IRP_CALL_SITE_RETURNED: case IRPosition::IRP_CALL_SITE_ARGUMENT: - Attrs = cast(IRP.getAnchorValue()).getAttributes(); + Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes(); break; } @@ -253,7 +253,7 @@ IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP, case IRPosition::IRP_CALL_SITE: case IRPosition::IRP_CALL_SITE_RETURNED: case IRPosition::IRP_CALL_SITE_ARGUMENT: - cast(IRP.getAnchorValue()).setAttributes(Attrs); + CallSite(&IRP.getAnchorValue()).setAttributes(Attrs); break; case IRPosition::IRP_INVALID: case IRPosition::IRP_FLOAT: @@ -269,7 +269,7 @@ const IRPosition IRPosition::TombstoneKey(256); SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) { IRPositions.emplace_back(IRP); - const auto *CB = dyn_cast(&IRP.getAnchorValue()); + ImmutableCallSite ICS(&IRP.getAnchorValue()); switch (IRP.getPositionKind()) { case IRPosition::IRP_INVALID: case IRPosition::IRP_FLOAT: @@ -280,40 +280,41 @@ SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) { IRPositions.emplace_back(IRPosition::function(*IRP.getAnchorScope())); return; case IRPosition::IRP_CALL_SITE: - assert(CB && "Expected call site!"); + assert(ICS && "Expected call site!"); // TODO: We need to look at the operand bundles similar to the redirection // in CallBase. - if (!CB->hasOperandBundles()) - if (const Function *Callee = CB->getCalledFunction()) + if (!ICS.hasOperandBundles()) + if (const Function *Callee = ICS.getCalledFunction()) IRPositions.emplace_back(IRPosition::function(*Callee)); return; case IRPosition::IRP_CALL_SITE_RETURNED: - assert(CB && "Expected call site!"); + assert(ICS && "Expected call site!"); // TODO: We need to look at the operand bundles similar to the redirection // in CallBase. - if (!CB->hasOperandBundles()) { - if (const Function *Callee = CB->getCalledFunction()) { + if (!ICS.hasOperandBundles()) { + if (const Function *Callee = ICS.getCalledFunction()) { IRPositions.emplace_back(IRPosition::returned(*Callee)); IRPositions.emplace_back(IRPosition::function(*Callee)); for (const Argument &Arg : Callee->args()) if (Arg.hasReturnedAttr()) { IRPositions.emplace_back( - IRPosition::callsite_argument(*CB, Arg.getArgNo())); + IRPosition::callsite_argument(ICS, Arg.getArgNo())); IRPositions.emplace_back( - IRPosition::value(*CB->getArgOperand(Arg.getArgNo()))); + IRPosition::value(*ICS.getArgOperand(Arg.getArgNo()))); IRPositions.emplace_back(IRPosition::argument(Arg)); } } } - IRPositions.emplace_back(IRPosition::callsite_function(*CB)); + IRPositions.emplace_back( + IRPosition::callsite_function(cast(*ICS.getInstruction()))); return; case IRPosition::IRP_CALL_SITE_ARGUMENT: { int ArgNo = IRP.getArgNo(); - assert(CB && ArgNo >= 0 && "Expected call site!"); + assert(ICS && ArgNo >= 0 && "Expected call site!"); // TODO: We need to look at the operand bundles similar to the redirection // in CallBase. - if (!CB->hasOperandBundles()) { - const Function *Callee = CB->getCalledFunction(); + if (!ICS.hasOperandBundles()) { + const Function *Callee = ICS.getCalledFunction(); if (Callee && Callee->arg_size() > unsigned(ArgNo)) IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo))); if (Callee) @@ -368,8 +369,8 @@ bool IRPosition::getAttrsFromIRAttr(Attribute::AttrKind AK, return false; AttributeList AttrList; - if (const auto *CB = dyn_cast(&getAnchorValue())) - AttrList = CB->getAttributes(); + if (ImmutableCallSite ICS = ImmutableCallSite(&getAnchorValue())) + AttrList = ICS.getAttributes(); else AttrList = getAssociatedFunction()->getAttributes(); @@ -509,12 +510,12 @@ bool Attributor::isAssumedDead(const Use &U, return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA, CheckBBLivenessOnly, DepClass); - if (auto *CB = dyn_cast(UserI)) { + if (CallSite CS = CallSite(UserI)) { // For call site argument uses we can check if the argument is // unused/dead. - if (CB->isArgOperand(&U)) { + if (CS.isArgOperand(&U)) { const IRPosition &CSArgPos = - IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)); + IRPosition::callsite_argument(CS, CS.getArgumentNo(&U)); return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA, CheckBBLivenessOnly, DepClass); } @@ -1616,8 +1617,8 @@ void InformationCache::initializeInformationCache(const Function &CF, // Note: There are no concrete attributes now so this is initially empty. switch (I.getOpcode()) { default: - assert(!isa(&I) && - "New call base instruction type needs to be known in the " + assert((!ImmutableCallSite(&I)) && (!isa(&I)) && + "New call site/base instruction type needs to be known in the " "Attributor."); break; case Instruction::Call: @@ -1686,8 +1687,8 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) { InformationCache::FunctionInfo &FI = InfoCache.getFunctionInfo(F); if (!isModulePass() && !FI.CalledViaMustTail) { for (const Use &U : F.uses()) - if (const auto *CB = dyn_cast(U.getUser())) - if (CB->isCallee(&U) && CB->isMustTailCall()) + if (ImmutableCallSite ICS = ImmutableCallSite(U.getUser())) + if (ICS.isCallee(&U) && ICS.isMustTailCall()) FI.CalledViaMustTail = true; } @@ -1799,14 +1800,14 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) { } auto CallSitePred = [&](Instruction &I) -> bool { - auto *CB = dyn_cast(&I); - IRPosition CBRetPos = IRPosition::callsite_returned(*CB); + CallSite CS(&I); + IRPosition CSRetPos = IRPosition::callsite_returned(CS); // Call sites might be dead if they do not have side effects and no live // users. The return value might be dead if there are no live users. - getOrCreateAAFor(CBRetPos); + getOrCreateAAFor(CSRetPos); - Function *Callee = CB->getCalledFunction(); + Function *Callee = CS.getCalledFunction(); // TODO: Even if the callee is not known now we might be able to simplify // the call/callee. if (!Callee) @@ -1818,46 +1819,46 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) { !Callee->hasMetadata(LLVMContext::MD_callback)) return true; - if (!Callee->getReturnType()->isVoidTy() && !CB->use_empty()) { + if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) { - IRPosition CBRetPos = IRPosition::callsite_returned(*CB); + IRPosition CSRetPos = IRPosition::callsite_returned(CS); // Call site return integer values might be limited by a constant range. if (Callee->getReturnType()->isIntegerTy()) - getOrCreateAAFor(CBRetPos); + getOrCreateAAFor(CSRetPos); } - for (int i = 0, e = CB->getNumArgOperands(); i < e; i++) { + for (int i = 0, e = CS.getNumArgOperands(); i < e; i++) { - IRPosition CBArgPos = IRPosition::callsite_argument(*CB, i); + IRPosition CSArgPos = IRPosition::callsite_argument(CS, i); // Every call site argument might be dead. - getOrCreateAAFor(CBArgPos); + getOrCreateAAFor(CSArgPos); // Call site argument might be simplified. - getOrCreateAAFor(CBArgPos); + getOrCreateAAFor(CSArgPos); - if (!CB->getArgOperand(i)->getType()->isPointerTy()) + if (!CS.getArgument(i)->getType()->isPointerTy()) continue; // Call site argument attribute "non-null". - getOrCreateAAFor(CBArgPos); + getOrCreateAAFor(CSArgPos); // Call site argument attribute "no-alias". - getOrCreateAAFor(CBArgPos); + getOrCreateAAFor(CSArgPos); // Call site argument attribute "dereferenceable". - getOrCreateAAFor(CBArgPos); + getOrCreateAAFor(CSArgPos); // Call site argument attribute "align". - getOrCreateAAFor(CBArgPos); + getOrCreateAAFor(CSArgPos); // Call site argument attribute // "readnone/readonly/writeonly/..." - getOrCreateAAFor(CBArgPos); + getOrCreateAAFor(CSArgPos); // Call site argument attribute "nofree". - getOrCreateAAFor(CBArgPos); + getOrCreateAAFor(CSArgPos); } return true; }; @@ -1982,9 +1983,9 @@ static bool runAttributorOnFunctions(InformationCache &InfoCache, // do it eagerly. if (F->hasLocalLinkage()) { if (llvm::all_of(F->uses(), [&Functions](const Use &U) { - const auto *CB = dyn_cast(U.getUser()); - return CB && CB->isCallee(&U) && - Functions.count(const_cast(CB->getCaller())); + ImmutableCallSite ICS(U.getUser()); + return ICS && ICS.isCallee(&U) && + Functions.count(const_cast(ICS.getCaller())); })) continue; } diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 9c58b3f..9ea314f 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -280,11 +280,11 @@ static bool genericValueTraversal( if (V->getType()->isPointerTy()) { NewV = V->stripPointerCasts(); } else { - auto *CB = dyn_cast(V); - if (CB && CB->getCalledFunction()) { - for (Argument &Arg : CB->getCalledFunction()->args()) + CallSite CS(V); + if (CS && CS.getCalledFunction()) { + for (Argument &Arg : CS.getCalledFunction()->args()) if (Arg.hasReturnedAttr()) { - NewV = CB->getArgOperand(Arg.getArgNo()); + NewV = CS.getArgOperand(Arg.getArgNo()); break; } } @@ -688,9 +688,9 @@ struct AANoUnwindImpl : AANoUnwind { if (!I.mayThrow()) return true; - if (const auto *CB = dyn_cast(&I)) { + if (ImmutableCallSite ICS = ImmutableCallSite(&I)) { const auto &NoUnwindAA = - A.getAAFor(*this, IRPosition::callsite_function(*CB)); + A.getAAFor(*this, IRPosition::callsite_function(ICS)); return NoUnwindAA.isAssumedNoUnwind(); } return false; @@ -1273,7 +1273,8 @@ bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) { } bool AANoSyncImpl::isVolatile(Instruction *I) { - assert(!isa(I) && "Calls should not be checked here"); + assert(!ImmutableCallSite(I) && !isa(I) && + "Calls should not be checked here"); switch (I->getOpcode()) { case Instruction::AtomicRMW: @@ -1298,12 +1299,12 @@ ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) { if (isa(&I) && isNoSyncIntrinsic(&I)) return true; - if (const auto *CB = dyn_cast(&I)) { - if (CB->hasFnAttr(Attribute::NoSync)) + if (ImmutableCallSite ICS = ImmutableCallSite(&I)) { + if (ICS.hasFnAttr(Attribute::NoSync)) return true; const auto &NoSyncAA = - A.getAAFor(*this, IRPosition::callsite_function(*CB)); + A.getAAFor(*this, IRPosition::callsite_function(ICS)); if (NoSyncAA.isAssumedNoSync()) return true; return false; @@ -1322,7 +1323,7 @@ ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) { return true; // non-convergent and readnone imply nosync. - return !cast(I).isConvergent(); + return !ImmutableCallSite(&I).isConvergent(); }; if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) || @@ -1376,12 +1377,12 @@ struct AANoFreeImpl : public AANoFree { /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { auto CheckForNoFree = [&](Instruction &I) { - const auto &CB = cast(I); - if (CB.hasFnAttr(Attribute::NoFree)) + ImmutableCallSite ICS(&I); + if (ICS.hasFnAttr(Attribute::NoFree)) return true; const auto &NoFreeAA = - A.getAAFor(*this, IRPosition::callsite_function(CB)); + A.getAAFor(*this, IRPosition::callsite_function(ICS)); return NoFreeAA.isAssumedNoFree(); }; @@ -1558,17 +1559,17 @@ static int64_t getKnownNonNullAndDerefBytesForUse( bool NullPointerIsDefined = F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true; const DataLayout &DL = A.getInfoCache().getDL(); - if (const auto *CB = dyn_cast(I)) { - if (CB->isBundleOperand(U)) + if (ImmutableCallSite ICS = ImmutableCallSite(I)) { + if (ICS.isBundleOperand(U)) return 0; - if (CB->isCallee(U)) { + if (ICS.isCallee(U)) { IsNonNull |= !NullPointerIsDefined; return 0; } - unsigned ArgNo = CB->getArgOperandNo(U); - IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); + unsigned ArgNo = ICS.getArgumentNo(U); + IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo); // As long as we only use known information there is no need to track // dependences here. auto &DerefAA = A.getAAFor(QueryingAA, IRP, @@ -1802,17 +1803,17 @@ struct AANoRecurseFunction final : AANoRecurseImpl { // If the above check does not hold anymore we look at the calls. auto CheckForNoRecurse = [&](Instruction &I) { - const auto &CB = cast(I); - if (CB.hasFnAttr(Attribute::NoRecurse)) + ImmutableCallSite ICS(&I); + if (ICS.hasFnAttr(Attribute::NoRecurse)) return true; const auto &NoRecurseAA = - A.getAAFor(*this, IRPosition::callsite_function(CB)); + A.getAAFor(*this, IRPosition::callsite_function(ICS)); if (!NoRecurseAA.isAssumedNoRecurse()) return false; // Recursion to the same function - if (CB.getCalledFunction() == getAnchorScope()) + if (ICS.getCalledFunction() == getAnchorScope()) return false; return true; @@ -2113,7 +2114,7 @@ struct AAWillReturnImpl : public AAWillReturn { /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { auto CheckForWillReturn = [&](Instruction &I) { - IRPosition IPos = IRPosition::callsite_function(cast(I)); + IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I)); const auto &WillReturnAA = A.getAAFor(*this, IPos); if (WillReturnAA.isKnownWillReturn()) return true; @@ -2320,8 +2321,8 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl { /// See AbstractAttribute::initialize(...). void initialize(Attributor &A) override { // See callsite argument attribute and callee argument attribute. - const auto &CB = cast(getAnchorValue()); - if (CB.paramHasAttr(getArgNo(), Attribute::NoAlias)) + ImmutableCallSite ICS(&getAnchorValue()); + if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias)) indicateOptimisticFixpoint(); Value &Val = getAssociatedValue(); if (isa(Val) && @@ -2334,32 +2335,32 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl { /// \p OtherArgNo of \p ICS (= the underlying call site). bool mayAliasWithArgument(Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA, - const CallBase &CB, unsigned OtherArgNo) { + ImmutableCallSite ICS, unsigned OtherArgNo) { // We do not need to worry about aliasing with the underlying IRP. if (this->getArgNo() == (int)OtherArgNo) return false; // If it is not a pointer or pointer vector we do not alias. - const Value *ArgOp = CB.getArgOperand(OtherArgNo); + const Value *ArgOp = ICS.getArgOperand(OtherArgNo); if (!ArgOp->getType()->isPtrOrPtrVectorTy()) return false; - auto &CBArgMemBehaviorAA = A.getAAFor( - *this, IRPosition::callsite_argument(CB, OtherArgNo), + auto &ICSArgMemBehaviorAA = A.getAAFor( + *this, IRPosition::callsite_argument(ICS, OtherArgNo), /* TrackDependence */ false); // If the argument is readnone, there is no read-write aliasing. - if (CBArgMemBehaviorAA.isAssumedReadNone()) { - A.recordDependence(CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); + if (ICSArgMemBehaviorAA.isAssumedReadNone()) { + A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); return false; } // If the argument is readonly and the underlying value is readonly, there // is no read-write aliasing. bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly(); - if (CBArgMemBehaviorAA.isAssumedReadOnly() && IsReadOnly) { + if (ICSArgMemBehaviorAA.isAssumedReadOnly() && IsReadOnly) { A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL); - A.recordDependence(CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); + A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); return false; } @@ -2456,10 +2457,10 @@ struct AANoAliasCallSiteArgument final : AANoAliasImpl { // Check there is no other pointer argument which could alias with the // value passed at this call site. // TODO: AbstractCallSite - const auto &CB = cast(getAnchorValue()); - for (unsigned OtherArgNo = 0; OtherArgNo < CB.getNumArgOperands(); + ImmutableCallSite ICS(&getAnchorValue()); + for (unsigned OtherArgNo = 0; OtherArgNo < ICS.getNumArgOperands(); OtherArgNo++) - if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo)) + if (mayAliasWithArgument(A, AAR, MemBehaviorAA, ICS, OtherArgNo)) return false; return true; @@ -2510,8 +2511,8 @@ struct AANoAliasReturned final : AANoAliasImpl { /// For now, we can only deduce noalias if we have call sites. /// FIXME: add more support. - const auto *CB = dyn_cast(&RV); - if (!CB) + ImmutableCallSite ICS(&RV); + if (!ICS) return false; const IRPosition &RVPos = IRPosition::value(RV); @@ -2983,8 +2984,8 @@ struct AAIsDeadFunction : public AAIsDead { // is a performance optimization for blocks with calls to a lot of internal // functions. It can however cause dead functions to be treated as live. for (const Instruction &I : BB) - if (const auto *CB = dyn_cast(&I)) - if (const Function *F = CB->getCalledFunction()) + if (ImmutableCallSite ICS = ImmutableCallSite(&I)) + if (const Function *F = ICS.getCalledFunction()) if (F->hasLocalLinkage()) A.markLiveInternalFunction(*F); return true; @@ -3476,12 +3477,12 @@ static unsigned getKnownAlignForUse(Attributor &A, } MaybeAlign MA; - if (const auto *CB = dyn_cast(I)) { - if (CB->isBundleOperand(U) || CB->isCallee(U)) + if (ImmutableCallSite ICS = ImmutableCallSite(I)) { + if (ICS.isBundleOperand(U) || ICS.isCallee(U)) return 0; - unsigned ArgNo = CB->getArgOperandNo(U); - IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); + unsigned ArgNo = ICS.getArgumentNo(U); + IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo); // As long as we only use known information there is no need to track // dependences here. auto &AlignAA = A.getAAFor(QueryingAA, IRP, @@ -3984,13 +3985,13 @@ struct AACaptureUseTracker final : public CaptureTracker { // For now we only use special logic for call sites. However, the tracker // itself knows about a lot of other non-capturing cases already. - auto *CB = dyn_cast(UInst); - if (!CB || !CB->isArgOperand(U)) + CallSite CS(UInst); + if (!CS || !CS.isArgOperand(U)) return isCapturedIn(/* Memory */ true, /* Integer */ true, /* Return */ true); - unsigned ArgNo = CB->getArgOperandNo(U); - const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo); + unsigned ArgNo = CS.getArgumentNo(U); + const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo); // If we have a abstract no-capture attribute for the argument we can use // it to justify a non-capture attribute here. This allows recursion! auto &ArgNoCaptureAA = A.getAAFor(NoCaptureAA, CSArgPos); @@ -3998,7 +3999,7 @@ struct AACaptureUseTracker final : public CaptureTracker { return isCapturedIn(/* Memory */ false, /* Integer */ false, /* Return */ false); if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) { - addPotentialCopy(*CB); + addPotentialCopy(CS); return isCapturedIn(/* Memory */ false, /* Integer */ false, /* Return */ false); } @@ -4009,7 +4010,9 @@ struct AACaptureUseTracker final : public CaptureTracker { } /// Register \p CS as potential copy of the value we are checking. - void addPotentialCopy(CallBase &CB) { PotentialCopies.push_back(&CB); } + void addPotentialCopy(CallSite CS) { + PotentialCopies.push_back(CS.getInstruction()); + } /// See CaptureTracker::shouldExplore(...). bool shouldExplore(const Use *U) override { @@ -4989,9 +4992,10 @@ struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl { // Helper to check if for the given call site the associated argument is // passed to a callback where the privatization would be different. - auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) { + auto IsCompatiblePrivArgOfCallback = [&](CallSite CS) { SmallVector CallbackUses; - AbstractCallSite::getCallbackUses(CB, CallbackUses); + AbstractCallSite::getCallbackUses(cast(*CS.getInstruction()), + CallbackUses); for (const Use *U : CallbackUses) { AbstractCallSite CBACS(U); assert(CBACS && CBACS.isCallbackCall()); @@ -5008,7 +5012,7 @@ struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl { << CBArgNo << "@" << CBACS.getCalledFunction()->getName() << ")\n[AAPrivatizablePtr] " << CBArg << " : " << CBACS.getCallArgOperand(CBArg) << " vs " - << CB.getArgOperand(ArgNo) << "\n" + << CS.getArgOperand(ArgNo) << "\n" << "[AAPrivatizablePtr] " << CBArg << " : " << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n"; }); @@ -5090,7 +5094,7 @@ struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl { // here. auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) { if (ACS.isDirectCall()) - return IsCompatiblePrivArgOfCallback(*ACS.getInstruction()); + return IsCompatiblePrivArgOfCallback(CallSite(ACS.getInstruction())); if (ACS.isCallbackCall()) return IsCompatiblePrivArgOfDirectCS(ACS); return false; @@ -5723,9 +5727,9 @@ ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) { // If the instruction has an own memory behavior state, use it to restrict // the local state. No further analysis is required as the other memory // state is as optimistic as it gets. - if (const auto *CB = dyn_cast(&I)) { + if (ImmutableCallSite ICS = ImmutableCallSite(&I)) { const auto &MemBehaviorAA = A.getAAFor( - *this, IRPosition::callsite_function(*CB)); + *this, IRPosition::callsite_function(ICS)); intersectAssumedBits(MemBehaviorAA.getAssumed()); return !isAtFixpoint(); } @@ -5823,8 +5827,8 @@ bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U, // By default we follow all uses assuming UserI might leak information on U, // we have special handling for call sites operands though. - const auto *CB = dyn_cast(UserI); - if (!CB || !CB->isArgOperand(U)) + ImmutableCallSite ICS(UserI); + if (!ICS || !ICS.isArgOperand(U)) return true; // If the use is a call argument known not to be captured, the users of @@ -5834,9 +5838,9 @@ bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U, // call might the argument "through return", which we allow and for which we // need to check call users. if (U->get()->getType()->isPointerTy()) { - unsigned ArgNo = CB->getArgOperandNo(U); + unsigned ArgNo = ICS.getArgumentNo(U); const auto &ArgNoCaptureAA = A.getAAFor( - *this, IRPosition::callsite_argument(*CB, ArgNo), + *this, IRPosition::callsite_argument(ICS, ArgNo), /* TrackDependence */ true, DepClassTy::OPTIONAL); return !ArgNoCaptureAA.isAssumedNoCapture(); } @@ -5870,17 +5874,17 @@ void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U, case Instruction::Invoke: { // For call sites we look at the argument memory behavior attribute (this // could be recursive!) in order to restrict our own state. - const auto *CB = cast(UserI); + ImmutableCallSite ICS(UserI); // Give up on operand bundles. - if (CB->isBundleOperand(U)) { + if (ICS.isBundleOperand(U)) { indicatePessimisticFixpoint(); return; } // Calling a function does read the function pointer, maybe write it if the // function is self-modifying. - if (CB->isCallee(U)) { + if (ICS.isCallee(U)) { removeAssumedBits(NO_READS); break; } @@ -5889,9 +5893,9 @@ void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U, // argument. IRPosition Pos; if (U->get()->getType()->isPointerTy()) - Pos = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(U)); + Pos = IRPosition::callsite_argument(ICS, ICS.getArgumentNo(U)); else - Pos = IRPosition::callsite_function(*CB); + Pos = IRPosition::callsite_function(ICS); const auto &MemBehaviorAA = A.getAAFor( *this, Pos, /* TrackDependence */ true, DepClassTy::OPTIONAL); @@ -6180,9 +6184,9 @@ void AAMemoryLocationImpl::categorizePtrValue( Changed); return true; } - if (const auto *CB = dyn_cast(&V)) { + if (ImmutableCallSite ICS = ImmutableCallSite(&V)) { const auto &NoAliasAA = - A.getAAFor(*this, IRPosition::callsite_returned(*CB)); + A.getAAFor(*this, IRPosition::callsite_returned(ICS)); if (NoAliasAA.isAssumedNoAlias()) { updateStateAndAccessesMap(T, AccessKindAccessesMap, NO_MALLOCED_MEM, &I, &V, Changed); @@ -6222,32 +6226,32 @@ AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I, AAMemoryLocation::StateType AccessedLocs; AccessedLocs.intersectAssumedBits(NO_LOCATIONS); - if (auto *CB = dyn_cast(&I)) { + if (ImmutableCallSite ICS = ImmutableCallSite(&I)) { // First check if we assume any memory is access is visible. - const auto &CBMemLocationAA = - A.getAAFor(*this, IRPosition::callsite_function(*CB)); + const auto &ICSMemLocationAA = + A.getAAFor(*this, IRPosition::callsite_function(ICS)); LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I - << " [" << CBMemLocationAA << "]\n"); + << " [" << ICSMemLocationAA << "]\n"); - if (CBMemLocationAA.isAssumedReadNone()) + if (ICSMemLocationAA.isAssumedReadNone()) return NO_LOCATIONS; - if (CBMemLocationAA.isAssumedInaccessibleMemOnly()) { + if (ICSMemLocationAA.isAssumedInaccessibleMemOnly()) { updateStateAndAccessesMap(AccessedLocs, AccessKindAccessesMap, NO_INACCESSIBLE_MEM, &I, nullptr, Changed); return AccessedLocs.getAssumed(); } - uint32_t CBAssumedNotAccessedLocs = - CBMemLocationAA.getAssumedNotAccessedLocation(); + uint32_t ICSAssumedNotAccessedLocs = + ICSMemLocationAA.getAssumedNotAccessedLocation(); // Set the argmemonly and global bit as we handle them separately below. - uint32_t CBAssumedNotAccessedLocsNoArgMem = - CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM; + uint32_t ICSAssumedNotAccessedLocsNoArgMem = + ICSAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM; for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) { - if (CBAssumedNotAccessedLocsNoArgMem & CurMLK) + if (ICSAssumedNotAccessedLocsNoArgMem & CurMLK) continue; updateStateAndAccessesMap(AccessedLocs, AccessKindAccessesMap, CurMLK, &I, nullptr, Changed); @@ -6255,7 +6259,7 @@ AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I, // Now handle global memory if it might be accessed. This is slightly tricky // as NO_GLOBAL_MEM has multiple bits set. - bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM); + bool HasGlobalAccesses = ((~ICSAssumedNotAccessedLocs) & NO_GLOBAL_MEM); if (HasGlobalAccesses) { auto AccessPred = [&](const Instruction *, const Value *Ptr, AccessKind Kind, MemoryLocationsKind MLK) { @@ -6263,7 +6267,7 @@ AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I, Ptr, Changed); return true; }; - if (!CBMemLocationAA.checkForAllAccessesToMemoryKind( + if (!ICSMemLocationAA.checkForAllAccessesToMemoryKind( AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false))) return AccessedLocs.getWorstState(); } @@ -6273,18 +6277,18 @@ AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I, << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n"); // Now handle argument memory if it might be accessed. - bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM); + bool HasArgAccesses = ((~ICSAssumedNotAccessedLocs) & NO_ARGUMENT_MEM); if (HasArgAccesses) { - for (unsigned ArgNo = 0, e = CB->getNumArgOperands(); ArgNo < e; + for (unsigned ArgNo = 0, e = ICS.getNumArgOperands(); ArgNo < e; ++ArgNo) { // Skip non-pointer arguments. - const Value *ArgOp = CB->getArgOperand(ArgNo); + const Value *ArgOp = ICS.getArgOperand(ArgNo); if (!ArgOp->getType()->isPtrOrPtrVectorTy()) continue; // Skip readnone arguments. - const IRPosition &ArgOpIRP = IRPosition::callsite_argument(*CB, ArgNo); + const IRPosition &ArgOpIRP = IRPosition::callsite_argument(ICS, ArgNo); const auto &ArgOpMemLocationAA = A.getAAFor( *this, ArgOpIRP, /* TrackDependence */ true, DepClassTy::OPTIONAL); diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 7c1610f..0987cd6 100644 --- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -1242,15 +1242,15 @@ bool MemCpyOptPass::processMemMove(MemMoveInst *M) { } /// This is called on every byval argument in call sites. -bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) { - const DataLayout &DL = CB.getCaller()->getParent()->getDataLayout(); +bool MemCpyOptPass::processByValArgument(CallSite CS, unsigned ArgNo) { + const DataLayout &DL = CS.getCaller()->getParent()->getDataLayout(); // Find out what feeds this byval argument. - Value *ByValArg = CB.getArgOperand(ArgNo); + Value *ByValArg = CS.getArgument(ArgNo); Type *ByValTy = cast(ByValArg->getType())->getElementType(); uint64_t ByValSize = DL.getTypeAllocSize(ByValTy); MemDepResult DepInfo = MD->getPointerDependencyFrom( MemoryLocation(ByValArg, LocationSize::precise(ByValSize)), true, - CB.getIterator(), CB.getParent()); + CS.getInstruction()->getIterator(), CS.getInstruction()->getParent()); if (!DepInfo.isClobber()) return false; @@ -1269,16 +1269,16 @@ bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) { // Get the alignment of the byval. If the call doesn't specify the alignment, // then it is some target specific value that we can't know. - MaybeAlign ByValAlign = CB.getParamAlign(ArgNo); - if (!ByValAlign) return false; + unsigned ByValAlign = CS.getParamAlignment(ArgNo); + if (ByValAlign == 0) return false; // If it is greater than the memcpy, then we check to see if we can force the // source of the memcpy to the alignment we need. If we fail, we bail out. AssumptionCache &AC = LookupAssumptionCache(); DominatorTree &DT = LookupDomTree(); - if (MDep->getSourceAlign() < ByValAlign && - getOrEnforceKnownAlignment(MDep->getSource(), ByValAlign->value(), DL, - &CB, &AC, &DT) < ByValAlign->value()) + if (MDep->getSourceAlignment() < ByValAlign && + getOrEnforceKnownAlignment(MDep->getSource(), ByValAlign, DL, + CS.getInstruction(), &AC, &DT) < ByValAlign) return false; // The address space of the memcpy source must match the byval argument @@ -1297,14 +1297,14 @@ bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) { // not just the defining memcpy. MemDepResult SourceDep = MD->getPointerDependencyFrom( MemoryLocation::getForSource(MDep), false, - CB.getIterator(), MDep->getParent()); + CS.getInstruction()->getIterator(), MDep->getParent()); if (!SourceDep.isClobber() || SourceDep.getInst() != MDep) return false; Value *TmpCast = MDep->getSource(); if (MDep->getSource()->getType() != ByValArg->getType()) { BitCastInst *TmpBitCast = new BitCastInst(MDep->getSource(), ByValArg->getType(), - "tmpcast", &CB); + "tmpcast", CS.getInstruction()); // Set the tmpcast's DebugLoc to MDep's TmpBitCast->setDebugLoc(MDep->getDebugLoc()); TmpCast = TmpBitCast; @@ -1312,10 +1312,10 @@ bool MemCpyOptPass::processByValArgument(CallBase &CB, unsigned ArgNo) { LLVM_DEBUG(dbgs() << "MemCpyOptPass: Forwarding memcpy to byval:\n" << " " << *MDep << "\n" - << " " << CB << "\n"); + << " " << *CS.getInstruction() << "\n"); // Otherwise we're good! Update the byval argument. - CB.setArgOperand(ArgNo, TmpCast); + CS.setArgument(ArgNo, TmpCast); ++NumMemCpyInstr; return true; } @@ -1349,10 +1349,10 @@ bool MemCpyOptPass::iterateOnFunction(Function &F) { RepeatInstruction = processMemCpy(M); else if (MemMoveInst *M = dyn_cast(I)) RepeatInstruction = processMemMove(M); - else if (auto *CB = dyn_cast(I)) { - for (unsigned I = 0, E = CB->arg_size(); I != E; ++I) - if (CB->isByValArgument(I)) - MadeChange |= processByValArgument(*CB, I); + else if (auto CS = CallSite(I)) { + for (unsigned i = 0, e = CS.arg_size(); i != e; ++i) + if (CS.isByValArgument(i)) + MadeChange |= processByValArgument(CS, i); } // Reprocess the instruction if desired. -- 2.7.4