[cfe-commits] r70660 - /cfe/trunk/lib/Analysis/CFRefCount.cpp

Ted Kremenek kremenek at apple.com
Sat May 2 22:20:51 PDT 2009


Author: kremenek
Date: Sun May  3 00:20:50 2009
New Revision: 70660

URL: http://llvm.org/viewvc/llvm-project?rev=70660&view=rev
Log:
Convert ArgEffects from an std::vector to an ImmutableMap.  This will make it much easier to clean up the summary generation logic with annotations.

Modified:
    cfe/trunk/lib/Analysis/CFRefCount.cpp

Modified: cfe/trunk/lib/Analysis/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFRefCount.cpp?rev=70660&r1=70659&r2=70660&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Sun May  3 00:20:50 2009
@@ -222,29 +222,24 @@
 // Primitives used for constructing summaries for function/method calls.
 //===----------------------------------------------------------------------===//
 
-namespace {
 /// ArgEffect is used to summarize a function/method call's effect on a
 /// particular argument.
 enum ArgEffect { Autorelease, Dealloc, DecRef, DecRefMsg, DoNothing,
                  DoNothingByRef, IncRefMsg, IncRef, MakeCollectable, MayEscape,
                  NewAutoreleasePool, SelfOwn, StopTracking };
 
-/// ArgEffects summarizes the effects of a function/method call on all of
-/// its arguments.
-typedef std::vector<std::pair<unsigned,ArgEffect> > ArgEffects;
-}
-
 namespace llvm {
-template <> struct FoldingSetTrait<ArgEffects> {
-  static void Profile(const ArgEffects& X, FoldingSetNodeID& ID) {
-    for (ArgEffects::const_iterator I = X.begin(), E = X.end(); I!= E; ++I) {
-      ID.AddInteger(I->first);
-      ID.AddInteger((unsigned) I->second);
-    }
-  }    
+template <> struct FoldingSetTrait<ArgEffect> {
+static inline void Profile(const ArgEffect X, FoldingSetNodeID& ID) {
+  ID.AddInteger((unsigned) X);
+}
 };
 } // end llvm namespace
 
+/// ArgEffects summarizes the effects of a function/method call on all of
+/// its arguments.
+typedef llvm::ImmutableMap<unsigned,ArgEffect> ArgEffects;
+
 namespace {
 
 ///  RetEffect is used to summarize a function/method call's behavior with
@@ -310,7 +305,7 @@
   /// Args - an ordered vector of (index, ArgEffect) pairs, where index
   ///  specifies the argument (starting from 0).  This can be sparsely
   ///  populated; arguments with no entry in Args use 'DefaultArgEffect'.
-  ArgEffects* Args;
+  ArgEffects Args;
   
   /// DefaultArgEffect - The default ArgEffect to apply to arguments that
   ///  do not have an entry in Args.
@@ -330,8 +325,7 @@
   bool EndPath;
   
 public:
-  
-  RetainSummary(ArgEffects* A, RetEffect R, ArgEffect defaultEff,
+  RetainSummary(ArgEffects A, RetEffect R, ArgEffect defaultEff,
                 ArgEffect ReceiverEff, bool endpath = false)
     : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R),
       EndPath(endpath) {}  
@@ -339,31 +333,14 @@
   /// getArg - Return the argument effect on the argument specified by
   ///  idx (starting from 0).
   ArgEffect getArg(unsigned idx) const {
-
-    if (!Args)
-      return DefaultArgEffect;
-    
-    // If Args is present, it is likely to contain only 1 element.
-    // Just do a linear search.  Do it from the back because functions with
-    // large numbers of arguments will be tail heavy with respect to which
-    // argument they actually modify with respect to the reference count.    
-    for (ArgEffects::reverse_iterator I=Args->rbegin(), E=Args->rend();
-           I!=E; ++I) {
-      
-      if (idx > I->first)
-        return DefaultArgEffect;
-      
-      if (idx == I->first)
-        return I->second;
-    }
+    if (const ArgEffect *AE = Args.lookup(idx))
+      return *AE;
     
     return DefaultArgEffect;
   }
   
   /// getRetEffect - Returns the effect on the return value of the call.
-  RetEffect getRetEffect() const {
-    return Ret;
-  }
+  RetEffect getRetEffect() const { return Ret; }
   
   /// isEndPath - Returns true if executing the given method/function should
   ///  terminate the path.
@@ -371,19 +348,17 @@
   
   /// getReceiverEffect - Returns the effect on the receiver of the call.
   ///  This is only meaningful if the summary applies to an ObjCMessageExpr*.
-  ArgEffect getReceiverEffect() const {
-    return Receiver;
-  }
+  ArgEffect getReceiverEffect() const { return Receiver; }
   
-  typedef ArgEffects::const_iterator ExprIterator;
+  typedef ArgEffects::iterator ExprIterator;
   
-  ExprIterator begin_args() const { return Args->begin(); }
-  ExprIterator end_args()   const { return Args->end(); }
+  ExprIterator begin_args() const { return Args.begin(); }
+  ExprIterator end_args()   const { return Args.end(); }
   
-  static void Profile(llvm::FoldingSetNodeID& ID, ArgEffects* A,
+  static void Profile(llvm::FoldingSetNodeID& ID, ArgEffects A,
                       RetEffect RetEff, ArgEffect DefaultEff,
                       ArgEffect ReceiverEff, bool EndPath) {
-    ID.AddPointer(A);
+    ID.Add(A);
     ID.Add(RetEff);
     ID.AddInteger((unsigned) DefaultEff);
     ID.AddInteger((unsigned) ReceiverEff);
@@ -555,9 +530,6 @@
   //  Typedefs.
   //==-----------------------------------------------------------------==//
   
-  typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<ArgEffects> >
-          ArgEffectsSetTy;
-  
   typedef llvm::FoldingSet<RetainSummary>
           SummarySetTy;
   
@@ -593,13 +565,13 @@
   /// ObjCMethodSummaries - A map from selectors to summaries.
   ObjCMethodSummariesTy ObjCMethodSummaries;
 
-  /// ArgEffectsSet - A FoldingSet of uniqued ArgEffects.
-  ArgEffectsSetTy ArgEffectsSet;
-  
   /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,
   ///  and all other data used by the checker.
   llvm::BumpPtrAllocator BPAlloc;
   
+  /// AF - A factory for ArgEffects objects.
+  ArgEffects::Factory AF;  
+  
   /// ScratchArgs - A holding buffer for construct ArgEffects.
   ArgEffects ScratchArgs;
   
@@ -611,7 +583,7 @@
   
   /// getArgEffects - Returns a persistent ArgEffects object based on the
   ///  data in ScratchArgs.
-  ArgEffects*   getArgEffects();
+  ArgEffects getArgEffects();
 
   enum UnaryFuncKind { cfretain, cfrelease, cfmakecollectable };  
   
@@ -622,7 +594,7 @@
   RetainSummary* getCFSummaryGetRule(FunctionDecl* FD);  
   RetainSummary* getCFCreateGetRuleSummary(FunctionDecl* FD, const char* FName);
   
-  RetainSummary* getPersistentSummary(ArgEffects* AE, RetEffect RetEff,
+  RetainSummary* getPersistentSummary(ArgEffects AE, RetEffect RetEff,
                                       ArgEffect ReceiverEff = DoNothing,
                                       ArgEffect DefaultEff = MayEscape,
                                       bool isEndPath = false);
@@ -716,7 +688,8 @@
   }
 
   void addPanicSummary(const char* Cls, ...) {
-    RetainSummary* Summ = getPersistentSummary(0, RetEffect::MakeNoRet(),
+    RetainSummary* Summ = getPersistentSummary(AF.GetEmptyMap(),
+                                               RetEffect::MakeNoRet(),
                                                DoNothing,  DoNothing, true);
     va_list argp;
     va_start (argp, Cls);
@@ -729,7 +702,8 @@
   RetainSummaryManager(ASTContext& ctx, bool gcenabled)
    : Ctx(ctx),
      CFDictionaryCreateII(&ctx.Idents.get("CFDictionaryCreate")),
-     GCEnabled(gcenabled), StopSummary(0) {
+     GCEnabled(gcenabled), AF(BPAlloc), ScratchArgs(AF.GetEmptyMap()),
+     StopSummary(0) {
 
     InitializeClassMethodSummaries();
     InitializeMethodSummaries();
@@ -795,48 +769,16 @@
 // Implementation of checker data structures.
 //===----------------------------------------------------------------------===//
 
-RetainSummaryManager::~RetainSummaryManager() {
-  
-  // FIXME: The ArgEffects could eventually be allocated from BPAlloc, 
-  //   mitigating the need to do explicit cleanup of the
-  //   Argument-Effect summaries.
-  
-  for (ArgEffectsSetTy::iterator I = ArgEffectsSet.begin(), 
-                                 E = ArgEffectsSet.end(); I!=E; ++I)
-    I->getValue().~ArgEffects();
-}
-
-ArgEffects* RetainSummaryManager::getArgEffects() {
-
-  if (ScratchArgs.empty())
-    return NULL;
-  
-  // Compute a profile for a non-empty ScratchArgs.
-  llvm::FoldingSetNodeID profile;
-  profile.Add(ScratchArgs);
-  void* InsertPos;
-  
-  // Look up the uniqued copy, or create a new one.
-  llvm::FoldingSetNodeWrapper<ArgEffects>* E =
-    ArgEffectsSet.FindNodeOrInsertPos(profile, InsertPos);
-  
-  if (E) {
-    ScratchArgs.clear();
-    return &E->getValue();
-  }
-  
-  E = (llvm::FoldingSetNodeWrapper<ArgEffects>*)
-        BPAlloc.Allocate<llvm::FoldingSetNodeWrapper<ArgEffects> >();
-                       
-  new (E) llvm::FoldingSetNodeWrapper<ArgEffects>(ScratchArgs);
-  ArgEffectsSet.InsertNode(E, InsertPos);
+RetainSummaryManager::~RetainSummaryManager() {}
 
-  ScratchArgs.clear();
-  return &E->getValue();
+ArgEffects RetainSummaryManager::getArgEffects() {
+  ArgEffects AE = ScratchArgs;
+  ScratchArgs = AF.GetEmptyMap();
+  return AE;
 }
 
 RetainSummary*
-RetainSummaryManager::getPersistentSummary(ArgEffects* AE, RetEffect RetEff,
+RetainSummaryManager::getPersistentSummary(ArgEffects AE, RetEffect RetEff,
                                            ArgEffect ReceiverEff,
                                            ArgEffect DefaultEff,
                                            bool isEndPath) {
@@ -947,8 +889,8 @@
       // FIXES: <rdar://problem/6326900>
       // This should be addressed using a API table.  This strcmp is also
       // a little gross, but there is no need to super optimize here.
-      assert (ScratchArgs.empty());
-      ScratchArgs.push_back(std::make_pair(1, DecRef));
+      assert (ScratchArgs.isEmpty());
+      ScratchArgs = AF.Add(ScratchArgs, 1, DecRef);
       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
       break;
     }
@@ -1020,7 +962,7 @@
       if (isRelease(FD, FName))
         S = getUnarySummary(FT, cfrelease);
       else {
-        assert (ScratchArgs.empty());
+        assert (ScratchArgs.isEmpty());
         // Remaining CoreFoundation and CoreGraphics functions.
         // We use to assume that they all strictly followed the ownership idiom
         // and that ownership cannot be transferred.  While this is technically
@@ -1074,23 +1016,23 @@
   if (!FTP || FTP->getNumArgs() != 1)
     return getPersistentStopSummary();
   
-  assert (ScratchArgs.empty());
+  assert (ScratchArgs.isEmpty());
   
   switch (func) {
-    case cfretain: {      
-      ScratchArgs.push_back(std::make_pair(0, IncRef));
+    case cfretain: {
+      ScratchArgs = AF.Add(ScratchArgs, 0, IncRef);
       return getPersistentSummary(RetEffect::MakeAlias(0),
                                   DoNothing, DoNothing);
     }
       
     case cfrelease: {
-      ScratchArgs.push_back(std::make_pair(0, DecRef));
+      ScratchArgs = AF.Add(ScratchArgs, 0, DecRef);
       return getPersistentSummary(RetEffect::MakeNoRet(),
                                   DoNothing, DoNothing);
     }
       
     case cfmakecollectable: {
-      ScratchArgs.push_back(std::make_pair(0, MakeCollectable));
+      ScratchArgs = AF.Add(ScratchArgs, 0, MakeCollectable);
       return getPersistentSummary(RetEffect::MakeAlias(0),DoNothing, DoNothing);    
     }
       
@@ -1101,18 +1043,18 @@
 }
 
 RetainSummary* RetainSummaryManager::getCFSummaryCreateRule(FunctionDecl* FD) {
-  assert (ScratchArgs.empty());
+  assert (ScratchArgs.isEmpty());
   
   if (FD->getIdentifier() == CFDictionaryCreateII) {
-    ScratchArgs.push_back(std::make_pair(1, DoNothingByRef));
-    ScratchArgs.push_back(std::make_pair(2, DoNothingByRef));
+    ScratchArgs = AF.Add(ScratchArgs, 1, DoNothingByRef);
+    ScratchArgs = AF.Add(ScratchArgs, 2, DoNothingByRef);
   }
   
   return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
 }
 
 RetainSummary* RetainSummaryManager::getCFSummaryGetRule(FunctionDecl* FD) {
-  assert (ScratchArgs.empty());  
+  assert (ScratchArgs.isEmpty());  
   return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF),
                               DoNothing, DoNothing);
 }
@@ -1123,7 +1065,7 @@
 
 RetainSummary*
 RetainSummaryManager::getInitMethodSummary(QualType RetTy) {
-  assert(ScratchArgs.empty());
+  assert(ScratchArgs.isEmpty());
     
   // 'init' methods only return an alias if the return type is a location type.
   return getPersistentSummary(Loc::IsLocType(RetTy)
@@ -1136,7 +1078,7 @@
   if (!MD)
     return 0;
   
-  assert(ScratchArgs.empty());
+  assert(ScratchArgs.isEmpty());
   
   // Determine if there is a special return effect for this method.
   bool hasEffect = false;
@@ -1159,23 +1101,23 @@
   for (ObjCMethodDecl::param_iterator I = MD->param_begin(),
        E = MD->param_end(); I != E; ++I, ++i) {
     if ((*I)->getAttr<ObjCOwnershipRetainAttr>()) {
-      ScratchArgs.push_back(std::make_pair(i, IncRefMsg));
+      ScratchArgs = AF.Add(ScratchArgs, i, IncRefMsg);
       hasEffect = true;
     }
     else if ((*I)->getAttr<ObjCOwnershipCFRetainAttr>()) {
-      ScratchArgs.push_back(std::make_pair(i, IncRef));
+      ScratchArgs = AF.Add(ScratchArgs, i, IncRef);
       hasEffect = true;
     }
     else if ((*I)->getAttr<ObjCOwnershipReleaseAttr>()) {
-      ScratchArgs.push_back(std::make_pair(i, DecRefMsg));
+      ScratchArgs = AF.Add(ScratchArgs, i, DecRefMsg);
       hasEffect = true;
     }
     else if ((*I)->getAttr<ObjCOwnershipCFReleaseAttr>()) {
-      ScratchArgs.push_back(std::make_pair(i, DecRef));
+      ScratchArgs = AF.Add(ScratchArgs, i, DecRef);
       hasEffect = true;
     }
     else if ((*I)->getAttr<ObjCOwnershipMakeCollectableAttr>()) {
-      ScratchArgs.push_back(std::make_pair(i, MakeCollectable));
+      ScratchArgs = AF.Add(ScratchArgs, i, MakeCollectable);
       hasEffect = true;
     }    
   }
@@ -1212,7 +1154,7 @@
       if (ParmVarDecl *PD = *I) {
         QualType Ty = Ctx.getCanonicalType(PD->getType());
         if (Ty.getUnqualifiedType() == Ctx.VoidPtrTy)
-          ScratchArgs.push_back(std::make_pair(i, StopTracking));
+          ScratchArgs = AF.Add(ScratchArgs, i, StopTracking);
       }
   }
   
@@ -1231,7 +1173,7 @@
   
   // Look for methods that return an owned object.
   if (!isTrackedObjCObjectType(RetTy)) {
-    if (ScratchArgs.empty() && ReceiverEff == DoNothing)
+    if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing)
       return 0;
     
     return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff,
@@ -1263,7 +1205,7 @@
   if (I != ObjCMethodSummaries.end())
     return I->second;
 
-  assert(ScratchArgs.empty());
+  assert(ScratchArgs.isEmpty());
 
   // Annotations take precedence over all other ways to derive
   // summaries.
@@ -1308,7 +1250,7 @@
 
 void RetainSummaryManager::InitializeClassMethodSummaries() {
   
-  assert (ScratchArgs.empty());
+  assert (ScratchArgs.isEmpty());
   
   RetEffect E = isGCEnabled() ? RetEffect::MakeGCNotOwned()
                               : RetEffect::MakeOwned(RetEffect::ObjC, true);  
@@ -1327,7 +1269,7 @@
                 getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC)));
   
   // Create the [NSAutoreleasePool addObject:] summary.
-  ScratchArgs.push_back(std::make_pair(0, Autorelease));
+  ScratchArgs = AF.Add(ScratchArgs, 0, Autorelease);
   addClsMethSummary(&Ctx.Idents.get("NSAutoreleasePool"),
                     GetUnarySelector("addObject", Ctx),
                     getPersistentSummary(RetEffect::MakeNoRet(),
@@ -1358,7 +1300,7 @@
 
 void RetainSummaryManager::InitializeMethodSummaries() {
   
-  assert (ScratchArgs.empty());  
+  assert (ScratchArgs.isEmpty());  
   
   // Create the "init" selector.  It just acts as a pass-through for the
   // receiver.





More information about the cfe-commits mailing list