@@ -485,12 +485,39 @@ static bool allCallersPassValidPointerForArgument(
485
485
});
486
486
}
487
487
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
+
488
515
// / Determine that this argument is safe to promote, and find the argument
489
516
// / parts it can be promoted into.
490
517
static bool findArgParts (Argument *Arg, const DataLayout &DL, AAResults &AAR,
491
518
unsigned MaxElements, bool IsRecursive,
492
519
SmallVectorImpl<OffsetAndArgPart> &ArgPartsVec,
493
- bool ArgNotModified ) {
520
+ FunctionAnalysisManager &FAM ) {
494
521
// Quick exit for unused arguments
495
522
if (Arg->use_empty ())
496
523
return true ;
@@ -712,17 +739,21 @@ static bool findArgParts(Argument *Arg, const DataLayout &DL, AAResults &AAR,
712
739
713
740
// If store instructions are allowed, the path from the entry of the function
714
741
// 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)
719
744
return true ;
720
745
721
746
// 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 ;
725
754
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.
726
757
for (LoadInst *Load : Loads) {
727
758
// Check to see if the load is invalidated from the start of the block to
728
759
// the load itself.
@@ -763,33 +794,6 @@ static bool areTypesABICompatible(ArrayRef<Type *> Types, const Function &F,
763
794
});
764
795
}
765
796
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
-
793
797
// / PromoteArguments - This method checks the specified function to see if there
794
798
// / are any promotable arguments and if it is safe to promote the function (for
795
799
// / example, all callers are direct). If safe to promote some arguments, it
@@ -820,13 +824,11 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
820
824
return nullptr ;
821
825
822
826
// 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 ())
830
832
return nullptr ;
831
833
832
834
// Second check: make sure that all callers are direct callers. We can't
@@ -861,8 +863,7 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
861
863
// add it to ArgsToPromote.
862
864
DenseMap<Argument *, SmallVector<OffsetAndArgPart, 4 >> ArgsToPromote;
863
865
unsigned NumArgsAfterPromote = F->getFunctionType ()->getNumParams ();
864
- for (const auto &ArgIdx : PointerArgNos) {
865
- Argument *PtrArg = F->getArg (ArgIdx);
866
+ for (Argument *PtrArg : PointerArgs) {
866
867
// Replace sret attribute with noalias. This reduces register pressure by
867
868
// avoiding a register copy.
868
869
if (PtrArg->hasStructRetAttr ()) {
@@ -876,15 +877,11 @@ static Function *promoteArguments(Function *F, FunctionAnalysisManager &FAM,
876
877
}
877
878
}
878
879
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
-
883
880
// If we can promote the pointer to its value.
884
881
SmallVector<OffsetAndArgPart, 4 > ArgParts;
885
882
886
883
if (findArgParts (PtrArg, DL, AAR, MaxElements, IsRecursive, ArgParts,
887
- ArgNotModified )) {
884
+ FAM )) {
888
885
SmallVector<Type *, 4 > Types;
889
886
for (const auto &Pair : ArgParts)
890
887
Types.push_back (Pair.second .Ty );
0 commit comments