@@ -489,7 +489,8 @@ static bool allCallersPassValidPointerForArgument(
489489// / parts it can be promoted into.
490490static bool findArgParts (Argument *Arg, const DataLayout &DL, AAResults &AAR,
491491 unsigned MaxElements, bool IsRecursive,
492- SmallVectorImpl<OffsetAndArgPart> &ArgPartsVec) {
492+ SmallVectorImpl<OffsetAndArgPart> &ArgPartsVec,
493+ bool ArgNotModified) {
493494 // Quick exit for unused arguments
494495 if (Arg->use_empty ())
495496 return true ;
@@ -711,8 +712,10 @@ static bool findArgParts(Argument *Arg, const DataLayout &DL, AAResults &AAR,
711712
712713 // If store instructions are allowed, the path from the entry of the function
713714 // to each load may be not free of instructions that potentially invalidate
714- // the load, and this is an admissible situation.
715- if (AreStoresAllowed)
715+ // the load, and this is an admissible situation. If we have already
716+ // determined that the pointer Arg is not modified in the function (for all
717+ // Calls) then we can similarly conclude analysis here.
718+ if (AreStoresAllowed || ArgNotModified)
716719 return true ;
717720
718721 // Okay, now we know that the argument is only used by load instructions, and
@@ -760,6 +763,33 @@ static bool areTypesABICompatible(ArrayRef<Type *> Types, const Function &F,
760763 });
761764}
762765
766+ // Try to prove that all Calls to F do not modify the memory pointed to by Arg.
767+ // This can provide us with more opportunities to perform Argument Promotion in
768+ // cases where simply looking at a Function's instructions is insufficient to
769+ // prove that the pointer argument is not invalidated before all loads from it.
770+ static bool callDoesNotModifyArg (Function *F, unsigned ArgNo,
771+ FunctionAnalysisManager &FAM) {
772+ // Find all Users of F that are Calls, and see if they may modify Arg.
773+ for (User *U : F->users ()) {
774+ auto *Call = dyn_cast<CallInst>(U);
775+ if (!Call)
776+ continue ;
777+
778+ Value *ArgOp = Call->getArgOperand (ArgNo);
779+ assert (ArgOp->getType ()->isPointerTy () && " Argument must be Pointer Type!" );
780+
781+ MemoryLocation Loc = MemoryLocation::getForArgument (Call, ArgNo, nullptr );
782+
783+ AAResults &AAR = FAM.getResult <AAManager>(*Call->getFunction ());
784+ // Bail out as soon as we find a Call where Arg may be modified.
785+ if (isModSet (AAR.getModRefInfo (Call, Loc)))
786+ return false ;
787+ }
788+
789+ // All Calls do not modify the Arg.
790+ return true ;
791+ }
792+
763793// / PromoteArguments - This method checks the specified function to see if there
764794// / are any promotable arguments and if it is safe to promote the function (for
765795// / example, all callers are direct). If safe to promote some arguments, it
@@ -790,11 +820,13 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
790820 return nullptr ;
791821
792822 // First check: see if there are any pointer arguments! If not, quick exit.
793- SmallVector<Argument *, 16 > PointerArgs;
794- for (Argument &I : F->args ())
795- if (I.getType ()->isPointerTy ())
796- PointerArgs.push_back (&I);
797- if (PointerArgs.empty ())
823+ SmallVector<unsigned , 16 > PointerArgNos;
824+ for (unsigned I = 0 ; I < F->arg_size (); ++I) {
825+ Argument *Arg = F->getArg (I);
826+ if (Arg->getType ()->isPointerTy ())
827+ PointerArgNos.push_back (I);
828+ }
829+ if (PointerArgNos.empty ())
798830 return nullptr ;
799831
800832 // Second check: make sure that all callers are direct callers. We can't
@@ -829,7 +861,8 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
829861 // add it to ArgsToPromote.
830862 DenseMap<Argument *, SmallVector<OffsetAndArgPart, 4 >> ArgsToPromote;
831863 unsigned NumArgsAfterPromote = F->getFunctionType ()->getNumParams ();
832- for (Argument *PtrArg : PointerArgs) {
864+ for (const auto &ArgIdx : PointerArgNos) {
865+ Argument *PtrArg = F->getArg (ArgIdx);
833866 // Replace sret attribute with noalias. This reduces register pressure by
834867 // avoiding a register copy.
835868 if (PtrArg->hasStructRetAttr ()) {
@@ -843,10 +876,15 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
843876 }
844877 }
845878
879+ // Check if we can determine ahead of time that the argument is never
880+ // modified by a call to this function.
881+ bool ArgNotModified = callDoesNotModifyArg (F, ArgIdx, FAM);
882+
846883 // If we can promote the pointer to its value.
847884 SmallVector<OffsetAndArgPart, 4 > ArgParts;
848885
849- if (findArgParts (PtrArg, DL, AAR, MaxElements, IsRecursive, ArgParts)) {
886+ if (findArgParts (PtrArg, DL, AAR, MaxElements, IsRecursive, ArgParts,
887+ ArgNotModified)) {
850888 SmallVector<Type *, 4 > Types;
851889 for (const auto &Pair : ArgParts)
852890 Types.push_back (Pair.second .Ty );
0 commit comments