[llvm-commits] [poolalloc] r102718 - in /poolalloc/branches/release_26: include/poolalloc/PoolAllocate.h lib/DSA/DataStructure.cpp lib/DSA/EquivClassGraphs.cpp lib/PoolAllocate/PoolAllocate.cpp lib/PoolAllocate/TransformFunctionBody.cpp lib/rDSA/ lib/rDSA/CMakeLists.txt runtime/FL2Allocator/CMakeLists.txt runtime/FL2Allocator/PoolAllocator.cpp runtime/FL2Allocator/PoolAllocator.h
Patrick Simmons
simmon12 at illinois.edu
Fri Apr 30 09:28:28 PDT 2010
Author: psimmons
Date: Fri Apr 30 11:28:28 2010
New Revision: 102718
URL: http://llvm.org/viewvc/llvm-project?rev=102718&view=rev
Log:
Make pool allocation runtime thread-safe.
Add support for pthreads (USE_DYNCALL macro must be set).
Minor fixups & corrections to comments.
Added:
poolalloc/branches/release_26/lib/rDSA/
- copied from r96246, poolalloc/trunk/lib/rDSA/
Modified:
poolalloc/branches/release_26/include/poolalloc/PoolAllocate.h
poolalloc/branches/release_26/lib/DSA/DataStructure.cpp
poolalloc/branches/release_26/lib/DSA/EquivClassGraphs.cpp
poolalloc/branches/release_26/lib/PoolAllocate/PoolAllocate.cpp
poolalloc/branches/release_26/lib/PoolAllocate/TransformFunctionBody.cpp
poolalloc/branches/release_26/lib/rDSA/CMakeLists.txt
poolalloc/branches/release_26/runtime/FL2Allocator/CMakeLists.txt
poolalloc/branches/release_26/runtime/FL2Allocator/PoolAllocator.cpp
poolalloc/branches/release_26/runtime/FL2Allocator/PoolAllocator.h
Modified: poolalloc/branches/release_26/include/poolalloc/PoolAllocate.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/release_26/include/poolalloc/PoolAllocate.h?rev=102718&r1=102717&r2=102718&view=diff
==============================================================================
--- poolalloc/branches/release_26/include/poolalloc/PoolAllocate.h (original)
+++ poolalloc/branches/release_26/include/poolalloc/PoolAllocate.h Fri Apr 30 11:28:28 2010
@@ -55,7 +55,7 @@
/// maps to the original function...
///
struct FuncInfo {
- FuncInfo(Function &f) : F(f), Clone(0) {}
+ FuncInfo(Function &f) : F(f), Clone(0), rev_pool_desc_map_computed(false) {}
/// MarkedNodes - The set of nodes which are not locally pool allocatable in
/// the current function.
@@ -84,6 +84,23 @@
/// function.
std::map<const DSNode*, Value*> PoolDescriptors;
+ //Reverse mapping for PoolDescriptors, needed by TPPA
+ std::map<Value*, const DSNode*> ReversePoolDescriptors;
+
+ //This is a hack -- a function should be added which maintains these in parallel
+ //and all of PoolAlloc and SafeCode should be updated to use it instead of adding
+ //to either map directly.
+ bool rev_pool_desc_map_computed;
+ void calculate_reverse_pool_descriptors()
+ {
+ if(rev_pool_desc_map_computed)
+ return;
+ rev_pool_desc_map_computed = true;
+
+ for(std::map<const DSNode*, Value*>::iterator i = PoolDescriptors.begin(); i!=PoolDescriptors.end(); i++)
+ ReversePoolDescriptors[i->second] = i->first;
+ }
+
/// This is a map from Old to New Values (the reverse of NewToOldValueMap).
/// SAFECode uses this for check insertion.
std::map<const Value*, Value*> ValueMap;
@@ -145,6 +162,7 @@
return Graphs->getGlobalsGraph ();
}
+ /* Return value is of type PoolDescPtrTy */
virtual Value * getPool (const DSNode * N, Function & F) {return 0;}
virtual Value * getGlobalPool (const DSNode * Node) {return 0;}
@@ -168,7 +186,7 @@
std::map<const Function*, Function*> CloneToOrigMap;
public:
- Constant *PoolInit, *PoolDestroy, *PoolAlloc, *PoolRealloc, *PoolMemAlign;
+ Constant *PoolInit, *PoolDestroy, *PoolAlloc, *PoolRealloc, *PoolMemAlign, *PoolThreadWrapper;
Constant *PoolFree;
Constant *PoolCalloc;
Constant *PoolStrdup;
Modified: poolalloc/branches/release_26/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/release_26/lib/DSA/DataStructure.cpp?rev=102718&r1=102717&r2=102718&view=diff
==============================================================================
--- poolalloc/branches/release_26/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/branches/release_26/lib/DSA/DataStructure.cpp Fri Apr 30 11:28:28 2010
@@ -2609,8 +2609,8 @@
}
-/// computeGToGGMapping - Compute the mapping of nodes in the global graph to
-/// nodes in this graph.
+/// computeGToGGMapping - Compute the mapping of global nodes in this graph to
+/// nodes in the globals graph.
void DSGraph::computeGToGGMapping(NodeMapTy &NodeMap) {
DSGraph &GG = *getGlobalsGraph();
Modified: poolalloc/branches/release_26/lib/DSA/EquivClassGraphs.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/release_26/lib/DSA/EquivClassGraphs.cpp?rev=102718&r1=102717&r2=102718&view=diff
==============================================================================
--- poolalloc/branches/release_26/lib/DSA/EquivClassGraphs.cpp (original)
+++ poolalloc/branches/release_26/lib/DSA/EquivClassGraphs.cpp Fri Apr 30 11:28:28 2010
@@ -64,6 +64,8 @@
for (EquivalenceClasses<const GlobalValue*>::member_iterator MI = GlobalECs.member_begin(EQSI);
MI != GlobalECs.member_end(); ++MI) {
if (const Function* F = dyn_cast<Function>(*MI)) {
+ if(F->isDeclaration()) //ignore functions with no body
+ continue;
if (!BaseGraph) {
BaseGraph = getOrCreateGraph(F);
BaseGraph->getFunctionArgumentsForCall(F, Args);
Modified: poolalloc/branches/release_26/lib/PoolAllocate/PoolAllocate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/release_26/lib/PoolAllocate/PoolAllocate.cpp?rev=102718&r1=102717&r2=102718&view=diff
==============================================================================
--- poolalloc/branches/release_26/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/branches/release_26/lib/PoolAllocate/PoolAllocate.cpp Fri Apr 30 11:28:28 2010
@@ -269,6 +269,15 @@
//Get the poolregister function
PoolRegister = M->getOrInsertFunction("poolregister", VoidType,
PoolDescPtrTy, VoidPtrTy, Int32Type, NULL);
+
+ Function* pthread_create_func = M->getFunction("pthread_create");
+ Function::arg_iterator i = pthread_create_func->arg_begin();
+ vector<const Type*> non_vararg_params;
+ non_vararg_params.push_back(i++->getType());
+ non_vararg_params.push_back(i++->getType());
+ non_vararg_params.push_back(i++->getType());
+ non_vararg_params.push_back(Int32Type);
+ PoolThreadWrapper = M->getOrInsertFunction("poolalloc_pthread_create",FunctionType::get(Int32Type,non_vararg_params,true));
}
static void getCallsOf(Constant *C, std::vector<CallInst*> &Calls) {
Modified: poolalloc/branches/release_26/lib/PoolAllocate/TransformFunctionBody.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/release_26/lib/PoolAllocate/TransformFunctionBody.cpp?rev=102718&r1=102717&r2=102718&view=diff
==============================================================================
--- poolalloc/branches/release_26/lib/PoolAllocate/TransformFunctionBody.cpp (original)
+++ poolalloc/branches/release_26/lib/PoolAllocate/TransformFunctionBody.cpp Fri Apr 30 11:28:28 2010
@@ -545,6 +545,7 @@
void FuncTransform::visitCallSite(CallSite& CS) {
const Function *CF = CS.getCalledFunction();
Instruction *TheCall = CS.getInstruction();
+ bool thread_creation_point = false;
// If the called function is casted from one function type to another, peer
// into the cast instruction and pull out the actual function being called.
@@ -583,6 +584,21 @@
} else if (CF->getName() == "valloc") {
std::cerr << "VALLOC USED BUT NOT HANDLED!\n";
abort();
+ } else if (CF->getName() == "pthread_create") {
+ thread_creation_point = true;
+ //Get DSNode representing the void* passed to the callee
+ DSNodeHandle passed_dsnode_handle = G->getNodeForValue(CS.getArgument(3));
+
+ //Get DSNode representing the DSNode of the function pointer Value of the pthread_create call
+ DSNode* thread_callee_node = G->getNodeForValue(CS.getArgument(2)).getNode();
+ if(!thread_callee_node)
+ {
+ FuncInfo *CFI = PAInfo.getFuncInfo(*CF);
+ thread_callee_node = G->getNodeForValue(CFI->MapValueToOriginal(CS.getArgument(2))).getNode();
+ }
+
+ //Fill in CF with the name of one of the functions in thread_callee_node
+ CF = const_cast<Function*>(dyn_cast<Function>(*thread_callee_node->globals_begin()));
}
}
@@ -754,8 +770,9 @@
Args.push_back(ArgVal);
}
- // Add the rest of the arguments...
- Args.insert(Args.end(), CS.arg_begin(), CS.arg_end());
+ // Add the rest of the arguments unless we're a thread creation point, in which case we only need the pools
+ if(!thread_creation_point)
+ Args.insert(Args.end(), CS.arg_begin(), CS.arg_end());
//
// There are circumstances where a function is casted to another type and
@@ -776,7 +793,27 @@
std::string Name = TheCall->getName(); TheCall->setName("");
- if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) {
+ if(thread_creation_point) {
+ Module *M = CS.getInstruction()->getParent()->getParent()->getParent();
+ Value* pthread_replacement = M->getFunction("poolalloc_pthread_create");
+ vector<Value*> thread_args;
+
+ //Push back original thread arguments through the callee
+ thread_args.push_back(CS.getArgument(0));
+ thread_args.push_back(CS.getArgument(1));
+ thread_args.push_back(CS.getArgument(2));
+
+ //Push back the integer argument saying how many uses there are
+ thread_args.push_back(Constant::getIntegerValue(llvm::Type::getInt32Ty(M->getContext()),APInt(32,Args.size())));
+ thread_args.insert(thread_args.end(),Args.begin(),Args.end());
+ thread_args.push_back(CS.getArgument(3));
+
+ //Make the thread creation call
+ NewCall = CallInst::Create(pthread_replacement,
+ thread_args.begin(),thread_args.end(),
+ Name,TheCall);
+ }
+ else if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) {
NewCall = InvokeInst::Create (NewCallee, II->getNormalDest(),
II->getUnwindDest(),
Args.begin(), Args.end(), Name, TheCall);
Modified: poolalloc/branches/release_26/lib/rDSA/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/release_26/lib/rDSA/CMakeLists.txt?rev=102718&r1=96246&r2=102718&view=diff
==============================================================================
--- poolalloc/branches/release_26/lib/rDSA/CMakeLists.txt (original)
+++ poolalloc/branches/release_26/lib/rDSA/CMakeLists.txt Fri Apr 30 11:28:28 2010
@@ -1,2 +1,2 @@
file(GLOB sources *.cpp)
-add_llvm_library( LLVMDataStructure ${sources} )
+add_llvm_library( rDSA ${sources} )
Modified: poolalloc/branches/release_26/runtime/FL2Allocator/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/release_26/runtime/FL2Allocator/CMakeLists.txt?rev=102718&r1=102717&r2=102718&view=diff
==============================================================================
--- poolalloc/branches/release_26/runtime/FL2Allocator/CMakeLists.txt (original)
+++ poolalloc/branches/release_26/runtime/FL2Allocator/CMakeLists.txt Fri Apr 30 11:28:28 2010
@@ -1,2 +1,9 @@
+include_directories(/localhome/simmon12/progs/dyncall-0.5/dyncall)
+link_directories(/localhome/simmon12/progs/dyncall-0.5/dyncall/build_out/linux_x86_gcc_release)
file(GLOB sources *.cpp)
-add_llvm_library( poolalloc_rt ${sources} )
\ No newline at end of file
+add_llvm_library( poolalloc_rt ${sources} )
+set_property(
+ TARGET poolalloc_rt
+ PROPERTY COMPILE_DEFINITIONS USE_DYNCALL
+ )
+target_link_libraries( poolalloc_rt dyncall_s )
Modified: poolalloc/branches/release_26/runtime/FL2Allocator/PoolAllocator.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/release_26/runtime/FL2Allocator/PoolAllocator.cpp?rev=102718&r1=102717&r2=102718&view=diff
==============================================================================
--- poolalloc/branches/release_26/runtime/FL2Allocator/PoolAllocator.cpp (original)
+++ poolalloc/branches/release_26/runtime/FL2Allocator/PoolAllocator.cpp Fri Apr 30 11:28:28 2010
@@ -366,6 +366,7 @@
void poolinit_bp(PoolTy<NormalPoolTraits> *Pool, unsigned ObjAlignment) {
DO_IF_PNP(memset(Pool, 0, sizeof(PoolTy<NormalPoolTraits>)));
+ pthread_mutex_init(&Pool->pool_lock,NULL);
Pool->Slabs = 0;
if (ObjAlignment < 4) ObjAlignment = __alignof(double);
Pool->AllocSize = INITIAL_SLAB_SIZE;
@@ -392,6 +393,8 @@
getPoolNumber(Pool), NumBytes));
DO_IF_PNP(if (Pool->NumObjects == 0) ++PoolCounter); // Track # pools.
+ pthread_mutex_lock(&Pool->pool_lock);
+
if (NumBytes >= LARGE_SLAB_SIZE)
goto LargeObject;
@@ -415,6 +418,7 @@
// Update bump ptr.
Pool->ObjFreeList = (FreedNodeHeader<NormalPoolTraits>*)(BumpPtr+NumBytes);
DO_IF_TRACE(fprintf(stderr, "%p\n", Result));
+ pthread_mutex_unlock(&Pool->pool_lock);
return Result;
}
@@ -431,6 +435,7 @@
LAH->Marker = ~0U;
LAH->LinkIntoList(&Pool->LargeArrays);
DO_IF_TRACE(fprintf(stderr, "%p [large]\n", LAH+1));
+ pthread_mutex_unlock(&Pool->pool_lock);
return LAH+1;
}
@@ -444,6 +449,8 @@
#endif
DO_IF_POOLDESTROY_STATS(PrintPoolStats(Pool));
+ pthread_mutex_destroy(&Pool->pool_lock);
+
// Free all allocated slabs.
PoolSlab<NormalPoolTraits> *PS = Pool->Slabs;
while (PS) {
@@ -476,6 +483,7 @@
unsigned DeclaredSize, unsigned ObjAlignment) {
assert(Pool && "Null pool pointer passed into poolinit!\n");
memset(Pool, 0, sizeof(PoolTy<PoolTraits>));
+ pthread_mutex_init(&Pool->pool_lock,NULL);
Pool->AllocSize = INITIAL_SLAB_SIZE;
if (ObjAlignment < 4) ObjAlignment = __alignof(double);
@@ -516,6 +524,7 @@
//
void pooldestroy(PoolTy<NormalPoolTraits> *Pool) {
assert(Pool && "Null pool pointer passed in to pooldestroy!\n");
+ pthread_mutex_destroy(&Pool->pool_lock);
#ifdef ENABLE_POOL_IDS
unsigned PID;
@@ -858,29 +867,73 @@
void *poolalloc(PoolTy<NormalPoolTraits> *Pool, unsigned NumBytes) {
DO_IF_FORCE_MALLOCFREE(return malloc(NumBytes));
- return poolalloc_internal(Pool, NumBytes);
+ pthread_mutex_lock(&Pool->pool_lock);
+ void* to_return = poolalloc_internal(Pool, NumBytes);
+ pthread_mutex_unlock(&Pool->pool_lock);
+ return to_return;
}
void *poolmemalign(PoolTy<NormalPoolTraits> *Pool,
unsigned Alignment, unsigned NumBytes) {
//punt and use pool alloc.
//I don't know if this is safe or breaks any assumptions in the runtime
+ pthread_mutex_lock(&Pool->pool_lock);
intptr_t base = (intptr_t)poolalloc_internal(Pool, NumBytes + Alignment - 1);
+ pthread_mutex_unlock(&Pool->pool_lock);
return (void*)((base + (Alignment - 1)) & ~((intptr_t)Alignment -1));
}
void poolfree(PoolTy<NormalPoolTraits> *Pool, void *Node) {
DO_IF_FORCE_MALLOCFREE(free(Node); return);
+ pthread_mutex_lock(&Pool->pool_lock);
poolfree_internal(Pool, Node);
+ pthread_mutex_unlock(&Pool->pool_lock);
}
void *poolrealloc(PoolTy<NormalPoolTraits> *Pool, void *Node,
unsigned NumBytes) {
DO_IF_FORCE_MALLOCFREE(return realloc(Node, NumBytes));
- return poolrealloc_internal(Pool, Node, NumBytes);
+ pthread_mutex_lock(&Pool->pool_lock);
+ void* to_return = poolrealloc_internal(Pool, Node, NumBytes);
+ pthread_mutex_unlock(&Pool->pool_lock);
}
+#ifdef USE_DYNCALL
+#include <dyncall.h>
+#include <pthread.h>
+#include <stdarg.h>
+
+void* poolalloc_thread_start(void* arg_)
+{
+ void** arg = (void**)arg_;
+ DCCallVM* callVM = dcNewCallVM((size_t)arg[1]*sizeof(size_t)+108);
+ int i;
+ for(i=0; i<(size_t)arg[1]; i++)
+ dcArgPointer(callVM,arg[2+i]);
+ dcArgPointer(callVM,arg[2+i]);
+ void* to_return = dcCallPointer(callVM,arg[0]);
+ dcFree(callVM);
+ return to_return;
+}
+int poolalloc_pthread_create(pthread_t* thread,
+ const pthread_attr_t* attr,
+ void *(*start_routine)(void*), int num_pools, ...)
+{
+ void** arg_array = (void**)malloc(sizeof(void*)*(2+num_pools));
+ arg_array[0] = (void*)start_routine;
+ arg_array[1] = (void*)num_pools;
+ va_list argpools;
+ va_start(argpools,num_pools);
+ int i;
+ for(i=0; i<num_pools; i++)
+ arg_array[2+i]=va_arg(argpools,void*);
+ arg_array[2+i]=va_arg(argpools,void*);
+ va_end(argpools);
+ return pthread_create(thread,attr,poolalloc_thread_start,arg_array);
+}
+
+#endif
//===----------------------------------------------------------------------===//
// Pointer Compression runtime library. Most of these are just wrappers
@@ -945,6 +998,7 @@
void pooldestroy_pc(PoolTy<CompressedPoolTraits> *Pool) {
assert(Pool && "Null pool pointer passed in to pooldestroy!\n");
+ pthread_mutex_destroy(&Pool->pool_lock);
if (Pool->Slabs == 0)
return; // no memory allocated from this pool.
@@ -970,17 +1024,23 @@
unsigned long long poolalloc_pc(PoolTy<CompressedPoolTraits> *Pool,
unsigned NumBytes) {
+ pthread_mutex_lock(&Pool->pool_lock);
void *Result = poolalloc_internal(Pool, NumBytes);
+ pthread_mutex_unlock(&Pool->pool_lock);
return (char*)Result-(char*)Pool->Slabs;
}
void poolfree_pc(PoolTy<CompressedPoolTraits> *Pool, unsigned long long Node) {
+ pthread_mutex_lock(&Pool->pool_lock);
poolfree_internal(Pool, (char*)Pool->Slabs+Node);
+ pthread_mutex_unlock(&Pool->pool_lock);
}
unsigned long long poolrealloc_pc(PoolTy<CompressedPoolTraits> *Pool,
unsigned long long Node, unsigned NumBytes) {
+ pthread_mutex_lock(&Pool->pool_lock);
void *Result = poolrealloc_internal(Pool, (char*)Pool->Slabs+Node, NumBytes);
+ pthread_mutex_unlock(&Pool->pool_lock);
return (char*)Result-(char*)Pool->Slabs;
}
@@ -998,18 +1058,26 @@
void* poolalloc_pca(PoolTy<CompressedPoolTraits> *Pool, unsigned NumBytes)
{
- return poolalloc_internal(Pool, NumBytes);
+ pthread_mutex_lock(&Pool->pool_lock);
+ void* to_return = poolalloc_internal(Pool, NumBytes);
+ pthread_mutex_unlock(&Pool->pool_lock);
+ return to_return;
}
void poolfree_pca(PoolTy<CompressedPoolTraits> *Pool, void* Node)
{
+ pthread_mutex_lock(&Pool->pool_lock);
poolfree_internal(Pool, Node);
+ pthread_mutex_unlock(&Pool->pool_lock);
}
void* poolrealloc_pca(PoolTy<CompressedPoolTraits> *Pool, void* Node,
unsigned NumBytes)
{
- return poolrealloc_internal(Pool, Node, NumBytes);
+ pthread_mutex_lock(&Pool->pool_lock);
+ void* to_return = poolrealloc_internal(Pool, Node, NumBytes);
+ pthread_mutex_unlock(&Pool->pool_lock);
+ return to_return;
}
//===----------------------------------------------------------------------===//
Modified: poolalloc/branches/release_26/runtime/FL2Allocator/PoolAllocator.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/release_26/runtime/FL2Allocator/PoolAllocator.h?rev=102718&r1=102717&r2=102718&view=diff
==============================================================================
--- poolalloc/branches/release_26/runtime/FL2Allocator/PoolAllocator.h (original)
+++ poolalloc/branches/release_26/runtime/FL2Allocator/PoolAllocator.h Fri Apr 30 11:28:28 2010
@@ -23,6 +23,7 @@
#define POOLALLOCATOR_RUNTIME_H
#include <assert.h>
+#include <pthread.h>
template<typename PoolTraits>
struct PoolSlab;
@@ -174,6 +175,9 @@
// BytesAllocated - The total number of bytes ever allocated from this pool.
// Together with NumObjects, allows us to calculate average object size.
unsigned BytesAllocated;
+
+ // Lock for the pool
+ pthread_mutex_t pool_lock;
};
extern "C" {
@@ -229,6 +233,13 @@
// Access tracing runtime library support.
void poolaccesstraceinit(void);
void poolaccesstrace(void *Ptr, void *PD);
+
+ // Auxiliary functions for thread support
+#ifdef USE_DYNCALL
+ int poolalloc_pthread_create(pthread_t* thread,
+ const pthread_attr_t* attr,
+ void *(*start_routine)(void*), int num_pools, ...);
+#endif
}
#endif
More information about the llvm-commits
mailing list