[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