[llvm-commits] [poolalloc] r128652 - in /poolalloc/trunk: include/dsa/AllocatorIdentification.h lib/DSA/AllocatorIdentification.cpp

Arushi Aggarwal aggarwa4 at illinois.edu
Thu Mar 31 11:37:05 PDT 2011


Author: aggarwa4
Date: Thu Mar 31 13:37:05 2011
New Revision: 128652

URL: http://llvm.org/viewvc/llvm-project?rev=128652&view=rev
Log:
Analysis pass to recognize allocator/deallocator
wrappers.

Added:
    poolalloc/trunk/include/dsa/AllocatorIdentification.h
    poolalloc/trunk/lib/DSA/AllocatorIdentification.cpp

Added: poolalloc/trunk/include/dsa/AllocatorIdentification.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/AllocatorIdentification.h?rev=128652&view=auto
==============================================================================
--- poolalloc/trunk/include/dsa/AllocatorIdentification.h (added)
+++ poolalloc/trunk/include/dsa/AllocatorIdentification.h Thu Mar 31 13:37:05 2011
@@ -0,0 +1,53 @@
+//===-- AllocatorIdentification.h - Identify alloc wrappers --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Identify malloc/free wrappers.
+//===----------------------------------------------------------------------===//
+
+#ifndef _ALLOCATORIDENTIFICATION_H
+#define	_ALLOCATORIDENTIFICATION_H
+
+namespace llvm {
+  class Function;
+  class Module;
+  class Instruction;
+
+
+#include <string>
+#include "llvm/Pass.h"
+
+  class AllocIdentify : public llvm::ModulePass {
+  protected:
+    std::set<std::string> allocators;
+    std::set<std::string> deallocators;
+    bool flowsFrom(Value *Dest,Value *Src);
+
+  public:
+    std::set<std::string>::iterator alloc_begin() {
+      return allocators.begin();
+    }
+    std::set<std::string>::iterator alloc_end() {
+      return allocators.end();
+    }
+    std::set<std::string>::iterator dealloc_begin() {
+      return deallocators.begin();
+    }
+    std::set<std::string>::iterator dealloc_end() {
+      return deallocators.end();
+    }
+    static char ID;
+    AllocIdentify();
+    virtual ~AllocIdentify();
+    bool runOnModule(llvm::Module&);
+    virtual void getAnalysisUsage(llvm::AnalysisUsage &Info) const;
+  };
+
+}
+
+#endif	/* _ALLOCATORIDENTIFICATION_H */
+

Added: poolalloc/trunk/lib/DSA/AllocatorIdentification.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/AllocatorIdentification.cpp?rev=128652&view=auto
==============================================================================
--- poolalloc/trunk/lib/DSA/AllocatorIdentification.cpp (added)
+++ poolalloc/trunk/lib/DSA/AllocatorIdentification.cpp Thu Mar 31 13:37:05 2011
@@ -0,0 +1,196 @@
+//===-- AllocatorIdentification.cpp - Identify wrappers to allocators -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// A pass to identify functions that act as wrappers to malloc and other 
+// allocators.
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "allocator-identify"
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Debug.h"
+
+#include <set>
+#include <map>
+#include <vector>
+#include <string>
+
+#include "dsa/AllocatorIdentification.h"
+
+using namespace llvm;
+
+STATISTIC(numAllocators, "Number of malloc-like allocators");
+STATISTIC(numDeallocators, "Number of free-like deallocators");
+
+  bool AllocIdentify::flowsFrom(Value *Dest,Value *Src) {
+    if(Dest == Src)
+      return true;
+    if(ReturnInst *Ret = dyn_cast<ReturnInst>(Dest)) {    
+      return flowsFrom(Ret->getReturnValue(), Src);
+    } 
+    if(PHINode *PN = dyn_cast<PHINode>(Dest)) {
+      Function *F = PN->getParent()->getParent();
+      LoopInfo &LI = getAnalysis<LoopInfo>(*F);
+      // If this is a loop phi, ignore.
+      if(LI.isLoopHeader(PN->getParent()))
+        return false;
+      bool ret = true;
+      for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+        ret = ret && flowsFrom(PN->getIncomingValue(i), Src);
+      }
+      return ret;
+    }
+    if(BitCastInst *BI = dyn_cast<BitCastInst>(Dest)) {
+      return flowsFrom(BI->getOperand(0), Src);
+    }
+    if(isa<ConstantPointerNull>(Dest))
+      return true;
+    return false;
+  }
+
+ bool isNotStored(Value *V) {
+  // check that V is not stroed to a location taht is accessible outside this fn
+  for(Value::use_iterator ui = V->use_begin(), ue = V->use_end();
+      ui != ue; ++ui) {
+    if(isa<StoreInst>(ui))
+      return false;
+    if(isa<ICmpInst>(ui))
+      continue;
+    if(isa<ReturnInst>(ui))
+      continue;
+    if(BitCastInst *BI = dyn_cast<BitCastInst>(ui)) {
+      if(isNotStored(BI))
+        continue;
+      else 
+        return false;
+    }
+    if(PHINode *PN = dyn_cast<PHINode>(ui)) {
+      if(isNotStored(PN))
+        continue;
+      else 
+        return false;
+    }
+
+    return false;
+  }
+  return true;
+}
+
+AllocIdentify::AllocIdentify() : ModulePass(&ID) {}
+AllocIdentify::~AllocIdentify() {}
+bool AllocIdentify::runOnModule(Module& M) {
+
+  allocators.insert("malloc");
+  allocators.insert("calloc");
+  //allocators.insert("realloc");
+  //allocators.insert("memset");
+  deallocators.insert("free");
+  deallocators.insert("cfree");
+
+  bool changed;
+  do {
+    changed = false;
+    std::set<std::string> TempAllocators;
+    TempAllocators.insert( allocators.begin(), allocators.end());
+    std::set<std::string>::iterator it;
+    for(it = TempAllocators.begin(); it != TempAllocators.end(); ++it) {
+      Function* F = M.getFunction(*it);
+      if(!F)
+        continue;
+      for(Value::use_iterator ui = F->use_begin(), ue = F->use_end();
+          ui != ue; ++ui) {
+        // iterate though all calls to malloc
+        if (CallInst* CI = dyn_cast<CallInst>(ui)) {
+          // The function that calls malloc could be a potential allocator
+          Function *WrapperF = CI->getParent()->getParent();
+          if(WrapperF->doesNotReturn())
+            continue;
+          if(!(WrapperF->getReturnType()->isPointerTy()))
+            continue;
+          bool isWrapper = true;
+          for (Function::iterator BBI = WrapperF->begin(), E = WrapperF->end(); BBI != E; ) {
+            BasicBlock &BB = *BBI++;
+
+            // Only look at return blocks.
+            ReturnInst *Ret = dyn_cast<ReturnInst>(BB.getTerminator());
+            if (Ret == 0) continue;
+
+            //check for ALL return values
+            if(flowsFrom(Ret, CI)) {
+              continue;
+            } else {
+              isWrapper = false;
+              break;
+            }
+            // if true for all return add to list of allocators
+          }
+          if(isWrapper)
+            isWrapper = isWrapper && isNotStored(CI);
+          if(isWrapper) {
+            changed = (allocators.find(WrapperF->getName()) == allocators.end());
+            if(changed) {
+              ++numAllocators;
+              allocators.insert(WrapperF->getName());
+              DEBUG(errs() << WrapperF->getNameStr() << "\n");
+            }
+          }
+        }
+      }
+    }
+  } while(changed);
+
+  do {
+    changed = false;
+    std::set<std::string> TempDeallocators;
+    TempDeallocators.insert( deallocators.begin(), deallocators.end());
+    std::set<std::string>::iterator it;
+    for(it = TempDeallocators.begin(); it != TempDeallocators.end(); ++it) {
+      Function* F = M.getFunction(*it);
+
+      if(!F)
+        continue;
+      for(Value::use_iterator ui = F->use_begin(), ue = F->use_end();
+          ui != ue; ++ui) {
+        // iterate though all calls to malloc
+        if (CallInst* CI = dyn_cast<CallInst>(ui)) {
+          // The function that calls malloc could be a potential allocator
+          Function *WrapperF = CI->getParent()->getParent();
+
+          if(WrapperF->arg_size() != 1)
+            continue;
+          if(!WrapperF->arg_begin()->getType()->isPointerTy())
+            continue;
+          Argument *arg = dyn_cast<Argument>(WrapperF->arg_begin());
+          if(flowsFrom(CI->getOperand(1), arg)) {
+            changed = (deallocators.find(WrapperF->getName()) == deallocators.end());
+            if(changed) {
+              ++numDeallocators;
+              deallocators.insert(WrapperF->getName());
+              DEBUG(errs() << WrapperF->getNameStr() << "\n");
+            }
+          }
+        }
+      }
+    }
+  } while(changed);
+  return false;
+}
+void AllocIdentify::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequiredTransitive<LoopInfo>();
+  AU.setPreservesAll();
+}
+
+char AllocIdentify::ID = 0;
+static RegisterPass<AllocIdentify>
+X("alloc-identify", "Identify allocator wrapper functions");





More information about the llvm-commits mailing list