27
27
#include " llvm/Analysis/CallGraph.h"
28
28
#include " llvm/Analysis/CallGraphSCCPass.h"
29
29
#include " llvm/Analysis/CaptureTracking.h"
30
+ #include " llvm/Analysis/ValueTracking.h"
30
31
#include " llvm/IR/GlobalVariable.h"
31
32
#include " llvm/IR/InstIterator.h"
32
33
#include " llvm/IR/IntrinsicInst.h"
33
34
#include " llvm/IR/LLVMContext.h"
35
+ #include " llvm/Support/Debug.h"
34
36
#include " llvm/Analysis/TargetLibraryInfo.h"
35
37
using namespace llvm ;
36
38
@@ -42,6 +44,7 @@ STATISTIC(NumNoCapture, "Number of arguments marked nocapture");
42
44
STATISTIC (NumReadNoneArg, " Number of arguments marked readnone" );
43
45
STATISTIC (NumReadOnlyArg, " Number of arguments marked readonly" );
44
46
STATISTIC (NumNoAlias, " Number of function returns marked noalias" );
47
+ STATISTIC (NumNonNullReturn, " Number of function returns marked nonnull" );
45
48
STATISTIC (NumAnnotated, " Number of attributes added to library functions" );
46
49
47
50
namespace {
@@ -67,6 +70,13 @@ namespace {
67
70
// AddNoAliasAttrs - Deduce noalias attributes for the SCC.
68
71
bool AddNoAliasAttrs (const CallGraphSCC &SCC);
69
72
73
+ // / \brief Does this function return null?
74
+ bool ReturnsNonNull (Function *F, SmallPtrSet<Function*, 8 > &,
75
+ bool &Speculative) const ;
76
+
77
+ // / \brief Deduce nonnull attributes for the SCC.
78
+ bool AddNonNullAttrs (const CallGraphSCC &SCC);
79
+
70
80
// Utility methods used by inferPrototypeAttributes to add attributes
71
81
// and maintain annotation statistics.
72
82
@@ -832,6 +842,143 @@ bool FunctionAttrs::AddNoAliasAttrs(const CallGraphSCC &SCC) {
832
842
return MadeChange;
833
843
}
834
844
845
+ bool FunctionAttrs::ReturnsNonNull (Function *F,
846
+ SmallPtrSet<Function*, 8 > &SCCNodes,
847
+ bool &Speculative) const {
848
+ assert (F->getReturnType ()->isPointerTy () &&
849
+ " nonnull only meaningful on pointer types" );
850
+ Speculative = false ;
851
+
852
+ SmallSetVector<Value *, 8 > FlowsToReturn;
853
+ for (BasicBlock &BB : *F)
854
+ if (auto *Ret = dyn_cast<ReturnInst>(BB.getTerminator ()))
855
+ FlowsToReturn.insert (Ret->getReturnValue ());
856
+
857
+ for (unsigned i = 0 ; i != FlowsToReturn.size (); ++i) {
858
+ Value *RetVal = FlowsToReturn[i];
859
+
860
+ // If this value is locally known to be non-null, we're good
861
+ if (isKnownNonNull (RetVal, TLI))
862
+ continue ;
863
+
864
+ // Otherwise, we need to look upwards since we can't make any local
865
+ // conclusions.
866
+ Instruction *RVI = dyn_cast<Instruction>(RetVal);
867
+ if (!RVI)
868
+ return false ;
869
+ switch (RVI->getOpcode ()) {
870
+ // Extend the analysis by looking upwards.
871
+ case Instruction::BitCast:
872
+ case Instruction::GetElementPtr:
873
+ case Instruction::AddrSpaceCast:
874
+ FlowsToReturn.insert (RVI->getOperand (0 ));
875
+ continue ;
876
+ case Instruction::Select: {
877
+ SelectInst *SI = cast<SelectInst>(RVI);
878
+ FlowsToReturn.insert (SI->getTrueValue ());
879
+ FlowsToReturn.insert (SI->getFalseValue ());
880
+ continue ;
881
+ }
882
+ case Instruction::PHI: {
883
+ PHINode *PN = cast<PHINode>(RVI);
884
+ for (int i = 0 , e = PN->getNumIncomingValues (); i != e; ++i)
885
+ FlowsToReturn.insert (PN->getIncomingValue (i));
886
+ continue ;
887
+ }
888
+ case Instruction::Call:
889
+ case Instruction::Invoke: {
890
+ CallSite CS (RVI);
891
+ Function *Callee = CS.getCalledFunction ();
892
+ // A call to a node within the SCC is assumed to return null until
893
+ // proven otherwise
894
+ if (Callee && SCCNodes.count (Callee)) {
895
+ Speculative = true ;
896
+ continue ;
897
+ }
898
+ return false ;
899
+ }
900
+ default :
901
+ return false ; // Unknown source, may be null
902
+ };
903
+ llvm_unreachable (" should have either continued or returned" );
904
+ }
905
+
906
+ return true ;
907
+ }
908
+
909
+ bool FunctionAttrs::AddNonNullAttrs (const CallGraphSCC &SCC) {
910
+ SmallPtrSet<Function*, 8 > SCCNodes;
911
+
912
+ // Fill SCCNodes with the elements of the SCC. Used for quickly
913
+ // looking up whether a given CallGraphNode is in this SCC.
914
+ for (CallGraphSCC::iterator I = SCC.begin (), E = SCC.end (); I != E; ++I)
915
+ SCCNodes.insert ((*I)->getFunction ());
916
+
917
+ // Speculative that all functions in the SCC return only nonnull
918
+ // pointers. We may refute this as we analyze functions.
919
+ bool SCCReturnsNonNull = true ;
920
+
921
+ bool MadeChange = false ;
922
+
923
+ // Check each function in turn, determining which functions return nonnull
924
+ // pointers.
925
+ for (CallGraphSCC::iterator I = SCC.begin (), E = SCC.end (); I != E; ++I) {
926
+ Function *F = (*I)->getFunction ();
927
+
928
+ if (!F || F->hasFnAttribute (Attribute::OptimizeNone))
929
+ // External node or node we don't want to optimize - skip it;
930
+ return false ;
931
+
932
+ // Already nonnull.
933
+ if (F->getAttributes ().hasAttribute (AttributeSet::ReturnIndex,
934
+ Attribute::NonNull))
935
+ continue ;
936
+
937
+ // Definitions with weak linkage may be overridden at linktime, so
938
+ // treat them like declarations.
939
+ if (F->isDeclaration () || F->mayBeOverridden ())
940
+ return false ;
941
+
942
+ // We annotate nonnull return values, which are only applicable to
943
+ // pointer types.
944
+ if (!F->getReturnType ()->isPointerTy ())
945
+ continue ;
946
+
947
+ bool Speculative = false ;
948
+ if (ReturnsNonNull (F, SCCNodes, Speculative)) {
949
+ if (!Speculative) {
950
+ // Mark the function eagerly since we may discover a function
951
+ // which prevents us from speculating about the entire SCC
952
+ DEBUG (dbgs () << " Eagerly marking " << F->getName () << " as nonnull\n " );
953
+ F->addAttribute (AttributeSet::ReturnIndex, Attribute::NonNull);
954
+ ++NumNonNullReturn;
955
+ MadeChange = true ;
956
+ }
957
+ continue ;
958
+ }
959
+ // At least one function returns something which could be null, can't
960
+ // speculate any more.
961
+ SCCReturnsNonNull = false ;
962
+ }
963
+
964
+ if (SCCReturnsNonNull) {
965
+ for (CallGraphSCC::iterator I = SCC.begin (), E = SCC.end (); I != E; ++I) {
966
+ Function *F = (*I)->getFunction ();
967
+ if (F->getAttributes ().hasAttribute (AttributeSet::ReturnIndex,
968
+ Attribute::NonNull) ||
969
+ !F->getReturnType ()->isPointerTy ())
970
+ continue ;
971
+
972
+ DEBUG (dbgs () << " SCC marking " << F->getName () << " as nonnull\n " );
973
+ F->addAttribute (AttributeSet::ReturnIndex, Attribute::NonNull);
974
+ ++NumNonNullReturn;
975
+ MadeChange = true ;
976
+ }
977
+ }
978
+
979
+ return MadeChange;
980
+ }
981
+
835
982
// / inferPrototypeAttributes - Analyze the name and prototype of the
836
983
// / given function and set any applicable attributes. Returns true
837
984
// / if any attributes were set and false otherwise.
@@ -1707,5 +1854,6 @@ bool FunctionAttrs::runOnSCC(CallGraphSCC &SCC) {
1707
1854
Changed |= AddReadAttrs (SCC);
1708
1855
Changed |= AddArgumentAttrs (SCC);
1709
1856
Changed |= AddNoAliasAttrs (SCC);
1857
+ Changed |= AddNonNullAttrs (SCC);
1710
1858
return Changed;
1711
1859
}
0 commit comments