Added code to merge metapools together for objects allocated out of the
same kmem_cache_t.
Re-ordered header files per LLVM coding standards.

llvm-svn: 72121
diff --git a/poolalloc/lib/DSA/TopDownClosure.cpp b/poolalloc/lib/DSA/TopDownClosure.cpp
index a4abe6f..9098adb 100644
--- a/poolalloc/lib/DSA/TopDownClosure.cpp
+++ b/poolalloc/lib/DSA/TopDownClosure.cpp
@@ -14,14 +14,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "dsa/DataStructure.h"
-#include "llvm/Module.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Instructions.h"
 #include "llvm/DerivedTypes.h"
-#include "dsa/DSGraph.h"
+#include "llvm/Module.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Timer.h"
-#include "llvm/ADT/Statistic.h"
+
+#include "dsa/DataStructure.h"
+#include "dsa/DSGraph.h"
+
 #include <iostream>
+
 using namespace llvm;
 
 #if 0
@@ -149,7 +153,57 @@
 	   ii != ee; ++ii)
 	ii->getMP()->addFlags(ii->getNodeFlags());
     }
-      
+
+#ifdef LLVA_KERNEL
+  //
+  // Ugly hack:
+  //
+  // Memory objects returned from kmem_cache_alloc() alias if they are
+  // allocated from the same kernel pool.  This code forces them to have the
+  // same MetaPool.
+  //
+  Function* KMA = M.getNamedFunction("kmem_cache_alloc");
+  if (KMA) {
+    // Map from kmem_cache_t's metapool to the metapool of its return value
+    std::map<MetaPool*, MetaPool*> locs;
+
+    for (Value::use_iterator ii = KMA->use_begin(), ee = KMA->use_end();
+         ii != ee; ++ii) {
+      CallInst* CI = dyn_cast<CallInst>(*ii);
+      if ((CI) && (CI->getCalledFunction() == KMA)) {
+        // Function in which the call statement resides
+        Function * F = CI->getParent()->getParent();
+
+        // The pointer to the kmem_cache_t
+        Value* CacheT = CI->getOperand(1);
+
+        //
+        // Get the metapool for the kmem_cache_t
+        //
+        DSNodeHandle DSCacheT = DSInfo[F]->getNodeForValue(CacheT);
+        MetaPoolHandle MPCacheT (DSCacheT.getNode()->getMP());
+
+        //
+        // Get the DSNode handle of the object being allocated.
+        //
+        DSNodeHandle DSH = DSInfo[F]->getNodeForValue(CI);
+        MetaPoolHandle MPNode (DSH.getNode()->getMP());
+
+        //
+        // If the allocated object does not belong to the same metapool as
+        // other objects allocated from this kmem_cache_t, merge their
+        // metapools so that they do.
+        //
+        if (locs[MPCacheT.getPool()] != MPNode.getPool()) {
+          std::cerr << "kmem_cache_alloc recovered merge\n";
+          DSH.getNode()->getMP()->merge(locs[MPCacheT.getPool()]);
+        }
+        locs[MPCacheT.getPool()] = DSH.getNode()->getMP();
+      }
+    }
+  }
+#endif
+     
   return false;
 }