@@ -485,12 +485,39 @@ static bool allCallersPassValidPointerForArgument(
485485 });
486486}
487487
488+ // Try to prove that all Calls to F do not modify the memory pointed to by Arg,
489+ // using alias analysis local to each caller of F.
490+ static bool isArgUnmodifiedByAllCalls (Function *F, unsigned ArgNo,
491+ FunctionAnalysisManager &FAM) {
492+ // Check if all Users of F are Calls which do not modify Arg.
493+ for (User *U : F->users ()) {
494+
495+ // Bail if we find an unexpected (non CallInst) use of the function.
496+ auto *Call = dyn_cast<CallInst>(U);
497+ if (!Call)
498+ return false ;
499+
500+ Value *ArgOp = Call->getArgOperand (ArgNo);
501+ assert (ArgOp->getType ()->isPointerTy () && " Argument must be Pointer Type!" );
502+
503+ MemoryLocation Loc = MemoryLocation::getForArgument (Call, ArgNo, nullptr );
504+
505+ AAResults &AAR = FAM.getResult <AAManager>(*Call->getFunction ());
506+ // Bail as soon as we find a Call where Arg may be modified.
507+ if (isModSet (AAR.getModRefInfo (Call, Loc)))
508+ return false ;
509+ }
510+
511+ // All Users are Calls which do not modify the Arg.
512+ return true ;
513+ }
514+
488515// / Determine that this argument is safe to promote, and find the argument
489516// / parts it can be promoted into.
490517static bool findArgParts (Argument *Arg, const DataLayout &DL, AAResults &AAR,
491518 unsigned MaxElements, bool IsRecursive,
492519 SmallVectorImpl<OffsetAndArgPart> &ArgPartsVec,
493- bool ArgNotModified ) {
520+ FunctionAnalysisManager &FAM ) {
494521 // Quick exit for unused arguments
495522 if (Arg->use_empty ())
496523 return true ;
@@ -712,17 +739,21 @@ static bool findArgParts(Argument *Arg, const DataLayout &DL, AAResults &AAR,
712739
713740 // If store instructions are allowed, the path from the entry of the function
714741 // to each load may be not free of instructions that potentially invalidate
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)
742+ // the load, and this is an admissible situation.
743+ if (AreStoresAllowed)
719744 return true ;
720745
721746 // Okay, now we know that the argument is only used by load instructions, and
722- // it is safe to unconditionally perform all of them. Use alias analysis to
723- // check to see if the pointer is guaranteed to not be modified from entry of
724- // the function to each of the load instructions.
747+ // it is safe to unconditionally perform all of them.
748+
749+ // If we can determine that no call to the Function modifies the memory
750+ // pointed to by Arg, through alias analysis using actual arguments in the
751+ // callers, we know that it is guaranteed to be safe to promote the argument.
752+ if (isArgUnmodifiedByAllCalls (Arg->getParent (), Arg->getArgNo (), FAM))
753+ return true ;
725754
755+ // Otherwise, use alias analysis to check if the pointer is guaranteed to not
756+ // be modified from entry of the function to each of the load instructions.
726757 for (LoadInst *Load : Loads) {
727758 // Check to see if the load is invalidated from the start of the block to
728759 // the load itself.
@@ -763,33 +794,6 @@ static bool areTypesABICompatible(ArrayRef<Type *> Types, const Function &F,
763794 });
764795}
765796
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-
793797// / PromoteArguments - This method checks the specified function to see if there
794798// / are any promotable arguments and if it is safe to promote the function (for
795799// / example, all callers are direct). If safe to promote some arguments, it
@@ -820,13 +824,11 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
820824 return nullptr ;
821825
822826 // First check: see if there are any pointer arguments! If not, quick exit.
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 ())
827+ SmallVector<Argument *, 16 > PointerArgs;
828+ for (Argument &I : F->args ())
829+ if (I.getType ()->isPointerTy ())
830+ PointerArgs.push_back (&I);
831+ if (PointerArgs.empty ())
830832 return nullptr ;
831833
832834 // Second check: make sure that all callers are direct callers. We can't
@@ -861,8 +863,7 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
861863 // add it to ArgsToPromote.
862864 DenseMap<Argument *, SmallVector<OffsetAndArgPart, 4 >> ArgsToPromote;
863865 unsigned NumArgsAfterPromote = F->getFunctionType ()->getNumParams ();
864- for (const auto &ArgIdx : PointerArgNos) {
865- Argument *PtrArg = F->getArg (ArgIdx);
866+ for (Argument *PtrArg : PointerArgs) {
866867 // Replace sret attribute with noalias. This reduces register pressure by
867868 // avoiding a register copy.
868869 if (PtrArg->hasStructRetAttr ()) {
@@ -876,15 +877,11 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
876877 }
877878 }
878879
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-
883880 // If we can promote the pointer to its value.
884881 SmallVector<OffsetAndArgPart, 4 > ArgParts;
885882
886883 if (findArgParts (PtrArg, DL, AAR, MaxElements, IsRecursive, ArgParts,
887- ArgNotModified )) {
884+ FAM )) {
888885 SmallVector<Type *, 4 > Types;
889886 for (const auto &Pair : ArgParts)
890887 Types.push_back (Pair.second .Ty );
0 commit comments