[llvm-commits] [poolalloc] r122526 - in /poolalloc/trunk: include/dsa/DSCallGraph.h lib/DSA/DSCallGraph.cpp lib/DSA/DSGraph.cpp lib/PoolAllocate/PoolAllocate.cpp test/pa/clone/Incomplete.ll

Arushi Aggarwal aggarwa4 at illinois.edu
Thu Dec 23 15:32:09 PST 2010


Author: aggarwa4
Date: Thu Dec 23 17:32:09 2010
New Revision: 122526

URL: http://llvm.org/viewvc/llvm-project?rev=122526&view=rev
Log:
Make sure that poolallocation does not pass
pool arguments to functions that can be
called from an unresolved call site. Upgrade
DSCallgraph to provide this information.


Added:
    poolalloc/trunk/test/pa/clone/Incomplete.ll
Modified:
    poolalloc/trunk/include/dsa/DSCallGraph.h
    poolalloc/trunk/lib/DSA/DSCallGraph.cpp
    poolalloc/trunk/lib/DSA/DSGraph.cpp
    poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp

Modified: poolalloc/trunk/include/dsa/DSCallGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSCallGraph.h?rev=122526&r1=122525&r2=122526&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSCallGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSCallGraph.h Thu Dec 23 17:32:09 2010
@@ -46,6 +46,10 @@
 
   // Functions we know about that aren't called
   svset<const llvm::Function*> knownRoots;
+  
+  // Functions that might be called from an incomplete
+  // unresolved call site.
+  svset<const llvm::Function*> IncompleteCalleeSet;
 
   svset<llvm::CallSite> completeCS;
 
@@ -152,6 +156,10 @@
     return ii->second.size();
   }
 
+  bool called_from_incomplete_site(const llvm::Function *F) const {
+    return !(IncompleteCalleeSet.find(F) 
+             == IncompleteCalleeSet.end()); 
+  }
   void callee_mark_complete(llvm::CallSite CS) {
     completeCS.insert(CS);
   }
@@ -175,6 +183,8 @@
   void buildSCCs();
 
   void buildRoots();
+  
+  void buildIncompleteCalleeSet(svset<const llvm::Function*> callees);
 
   void dump();
 

Modified: poolalloc/trunk/lib/DSA/DSCallGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSCallGraph.cpp?rev=122526&r1=122525&r2=122526&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DSCallGraph.cpp (original)
+++ poolalloc/trunk/lib/DSA/DSCallGraph.cpp Thu Dec 23 17:32:09 2010
@@ -170,6 +170,10 @@
                      std::inserter(knownRoots, knownRoots.begin()));
 }
 
+void DSCallGraph::buildIncompleteCalleeSet(svset<const llvm::Function*> callees) {
+  IncompleteCalleeSet.insert(callees.begin(), callees.end());
+}
+
 template <class T>
 void printNameOrPtr(T& Out, const llvm::Function* F) {
   if (F->hasName())

Modified: poolalloc/trunk/lib/DSA/DSGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DSGraph.cpp?rev=122526&r1=122525&r2=122526&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DSGraph.cpp (original)
+++ poolalloc/trunk/lib/DSA/DSGraph.cpp Thu Dec 23 17:32:09 2010
@@ -1666,7 +1666,8 @@
     }
   }
 }
-void DSGraph::buildCompleteCallGraph(DSCallGraph& DCG, std::vector<const Function*>& GlobalFunctionList, bool filter) const {
+void DSGraph::buildCompleteCallGraph(DSCallGraph& DCG, 
+                                     std::vector<const Function*>& GlobalFunctionList, bool filter) const {
   //
   // Get the list of unresolved call sites.
   //
@@ -1702,6 +1703,9 @@
         else
           ++NumFiltered;
       }
-     }
+    }
   }
+  svset<const llvm::Function*> callees;
+  callees.insert(GlobalFunctionList.begin(), GlobalFunctionList.end());
+  DCG.buildIncompleteCalleeSet(callees);
 }

Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=122526&r1=122525&r2=122526&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Thu Dec 23 17:32:09 2010
@@ -701,9 +701,21 @@
           Functions.push_back (*sccii);
         }
       }
-      if(!externFunctionFound) 
-        FindFunctionPoolArgs (Functions);
-      else {
+      bool doNotPassPools = externFunctionFound;
+      // go through the list of functions to check if any is external
+      // or callable from an incomplete call site. Then no pool args 
+      // are needed; else find pool args. 
+      if(!doNotPassPools){
+        for (unsigned index = 0; index < Functions.size(); ++index) {
+          const Function * F = Functions[index];
+          if (callgraph.called_from_incomplete_site(F)){
+            doNotPassPools = true;
+            break;
+          }
+        }
+      }
+       
+      if(doNotPassPools) {
         // For functions that are in the same equivalence class as an 
         // external function, we cannot pass pool args. Because we 
         // cannot know which function the call site calls, the 
@@ -718,47 +730,12 @@
           }
           FunctionInfo.insert(std::make_pair(F, FuncInfo(*F))).first->second;
         }
+      } else {
+        FindFunctionPoolArgs (Functions);
       }
-
     }
   }
   
-  /*
-  EquivalenceClasses<const GlobalValue*> & GlobalECs = Graphs->getGlobalECs();
-  EquivalenceClasses<const GlobalValue*>::iterator EQSI = GlobalECs.begin();
-  EquivalenceClasses<const GlobalValue*>::iterator EQSE = GlobalECs.end();
-  for (;EQSI != EQSE; ++EQSI) {
-    //
-    // If this element is not a leader, then skip it.
-    //
-    if (!EQSI->isLeader()) continue;
-
-    //
-    // Iterate through all members of this equivalence class, looking for
-    // functions.  Record all of those functions which need to be processed.
-    //
-    std::vector<const Function *> Functions;
-    EquivalenceClasses<const GlobalValue*>::member_iterator MI;
-    for (MI=GlobalECs.member_begin(EQSI); MI != GlobalECs.member_end(); ++MI) {
-      if (const Function* F = dyn_cast<Function>(*MI)) {
-        //
-        // If the function has no body, then it has no DSGraph.
-        //
-        // FIXME: I don't believe this is correct; the stdlib pass can assign
-        //        DSGraphs to C standard library functions.
-        //
-        if (!(F->isDeclaration()))
-          Functions.push_back (F);
-      }
-    }
-
-    //
-    // Find the pool arguments for all of the functions in the equivalence
-    // class and construct the FuncInfo structure for each one.
-    //
-    FindFunctionPoolArgs (Functions);
-  }*/
-
   //
   // Make sure every function has a FuncInfo structure.
   //

Added: poolalloc/trunk/test/pa/clone/Incomplete.ll
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/test/pa/clone/Incomplete.ll?rev=122526&view=auto
==============================================================================
--- poolalloc/trunk/test/pa/clone/Incomplete.ll (added)
+++ poolalloc/trunk/test/pa/clone/Incomplete.ll Thu Dec 23 17:32:09 2010
@@ -0,0 +1,65 @@
+;This test checks that functions callable from incomplete call sites 
+;are not cloned.
+;RUN: paopt %s -paheur-AllButUnreachableFromMemory -poolalloc -o %t.bc |& grep "Pool allocating.*nodes!"
+;RUN: llvm-dis %t.bc -o %t.ll
+;Make sure address taken functions A and C are not cloned
+;RUN: cat %t.ll | grep -v "A_clone"
+;RUN: cat %t.ll | grep -v "C_clone"
+;But ensure that B is cloned.
+;RUN: cat %t.ll | grep  "B_clone"
+
+; ModuleID = 'fptr.o'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @A(void (i8*)** %f) nounwind {
+entry:
+  %f_addr = alloca void (i8*)**                   ; <void (i8*)***> [#uses=1]
+  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
+  store void (i8*)** %f, void (i8*)*** %f_addr
+  br label %return
+
+return:                                           ; preds = %entry
+  ret void
+}
+
+define void @B(void (i8*)** %f) nounwind {
+entry:
+  %f_addr = alloca void (i8*)**                   ; <void (i8*)***> [#uses=1]
+  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
+  store void (i8*)** %f, void (i8*)*** %f_addr
+  br label %return
+
+return:                                           ; preds = %entry
+  ret void
+}
+
+define void @C(void (i8*)** %f) nounwind {
+entry:
+  %f_addr = alloca void (i8*)**                   ; <void (i8*)***> [#uses=1]
+  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
+  store void (i8*)** %f, void (i8*)*** %f_addr
+  br label %return
+
+return:                                           ; preds = %entry
+  ret void
+}
+
+define i32 @main() nounwind {
+entry:
+  %retval = alloca i32                            ; <i32*> [#uses=1]
+  %F = alloca void (i8*)*                         ; <void (i8*)**> [#uses=4]
+  %F1 = alloca void (i8*)*                        ; <void (i8*)**> [#uses=1]
+  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
+  store void (i8*)* bitcast (void (void (i8*)**)* @A to void (i8*)*), void (i8*)** %F, align 8
+  store void (i8*)* bitcast (void (void (i8*)**)* @C to void (i8*)*), void (i8*)** %F1, align 8
+  %0 = load void (i8*)** %F, align 8              ; <void (i8*)*> [#uses=1]
+  %F2 = bitcast void (i8*)** %F to i8*            ; <i8*> [#uses=1]
+  call void %0(i8* %F2) nounwind
+  call void @B(void (i8*)** %F) nounwind
+  br label %return
+
+return:                                           ; preds = %entry
+  %retval3 = load i32* %retval                    ; <i32> [#uses=1]
+  ret i32 %retval3
+}





More information about the llvm-commits mailing list