@@ -489,7 +489,8 @@ static bool allCallersPassValidPointerForArgument(
489
489
// / parts it can be promoted into.
490
490
static bool findArgParts (Argument *Arg, const DataLayout &DL, AAResults &AAR,
491
491
unsigned MaxElements, bool IsRecursive,
492
- SmallVectorImpl<OffsetAndArgPart> &ArgPartsVec) {
492
+ SmallVectorImpl<OffsetAndArgPart> &ArgPartsVec,
493
+ bool ArgNotModified) {
493
494
// Quick exit for unused arguments
494
495
if (Arg->use_empty ())
495
496
return true ;
@@ -711,8 +712,10 @@ static bool findArgParts(Argument *Arg, const DataLayout &DL, AAResults &AAR,
711
712
712
713
// If store instructions are allowed, the path from the entry of the function
713
714
// 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)
716
719
return true ;
717
720
718
721
// 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,
760
763
});
761
764
}
762
765
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
+
763
793
// / PromoteArguments - This method checks the specified function to see if there
764
794
// / are any promotable arguments and if it is safe to promote the function (for
765
795
// / example, all callers are direct). If safe to promote some arguments, it
@@ -790,11 +820,13 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
790
820
return nullptr ;
791
821
792
822
// 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 ())
798
830
return nullptr ;
799
831
800
832
// Second check: make sure that all callers are direct callers. We can't
@@ -829,7 +861,8 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
829
861
// add it to ArgsToPromote.
830
862
DenseMap<Argument *, SmallVector<OffsetAndArgPart, 4 >> ArgsToPromote;
831
863
unsigned NumArgsAfterPromote = F->getFunctionType ()->getNumParams ();
832
- for (Argument *PtrArg : PointerArgs) {
864
+ for (const auto &ArgIdx : PointerArgNos) {
865
+ Argument *PtrArg = F->getArg (ArgIdx);
833
866
// Replace sret attribute with noalias. This reduces register pressure by
834
867
// avoiding a register copy.
835
868
if (PtrArg->hasStructRetAttr ()) {
@@ -843,10 +876,15 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
843
876
}
844
877
}
845
878
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
+
846
883
// If we can promote the pointer to its value.
847
884
SmallVector<OffsetAndArgPart, 4 > ArgParts;
848
885
849
- if (findArgParts (PtrArg, DL, AAR, MaxElements, IsRecursive, ArgParts)) {
886
+ if (findArgParts (PtrArg, DL, AAR, MaxElements, IsRecursive, ArgParts,
887
+ ArgNotModified)) {
850
888
SmallVector<Type *, 4 > Types;
851
889
for (const auto &Pair : ArgParts)
852
890
Types.push_back (Pair.second .Ty );
0 commit comments