[vmkit-commits] [vmkit] r67514 - /vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Mon Mar 23 02:01:24 PDT 2009


Author: geoffray
Date: Mon Mar 23 04:01:10 2009
New Revision: 67514

URL: http://llvm.org/viewvc/llvm-project?rev=67514&view=rev
Log:
Allow Escape analysis to run when compiling AOT. Useless for objects for now
because the <init> function is in the way, not being inlined.


Modified:
    vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp

Modified: vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp?rev=67514&r1=67513&r2=67514&view=diff

==============================================================================
--- vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp (original)
+++ vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp Mon Mar 23 04:01:10 2009
@@ -9,8 +9,9 @@
 
 
 #include "llvm/Constants.h"
-#include "llvm/Pass.h"
 #include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Pass.h"
 #include "llvm/Instructions.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
@@ -67,12 +68,16 @@
 
 
 
-static bool escapes(Instruction* Ins, std::map<Instruction*, bool>& visited) {
+static bool escapes(Value* Ins, std::map<Instruction*, bool>& visited) {
   for (Value::use_iterator I = Ins->use_begin(), E = Ins->use_end(); 
        I != E; ++I) {
     if (Instruction* II = dyn_cast<Instruction>(I)) {
-      if (dyn_cast<CallInst>(II)) return true;
-      else if (dyn_cast<InvokeInst>(II)) return true;
+      if (CallInst* CI = dyn_cast<CallInst>(II)) {
+        if (!CI->onlyReadsMemory()) return true;
+      }
+      else if (InvokeInst* CI = dyn_cast<InvokeInst>(II)) {
+        if (!CI->onlyReadsMemory()) return true;
+      }
       else if (dyn_cast<BitCastInst>(II)) {
         if (escapes(II, visited)) return true;
       }
@@ -111,30 +116,46 @@
 bool EscapeAnalysis::processMalloc(Instruction* I, Value* Size, Value* VT) {
   Instruction* Alloc = I;
   
-  ConstantExpr* CE = dyn_cast<ConstantExpr>(VT);
-  if (CE) {
-    ConstantInt* C = dyn_cast<ConstantInt>(CE->getOperand(0));
-    if (!C) return false;
-
-    VirtualTable* Table = (VirtualTable*)C->getZExtValue();
-    ConstantInt* CI = dyn_cast<ConstantInt>(Size);
-    // If the class has a finalize method, do not stack allocate the object.
-    if (!((void**)Table)[0] && CI) {
-      std::map<Instruction*, bool> visited;
-      uint64_t NSize = CI->getZExtValue();
-      if (NSize < pageSize && !(escapes(Alloc, visited))) {
-        AllocaInst* AI = new AllocaInst(Type::Int8Ty, Size, "", Alloc);
-        BitCastInst* BI = new BitCastInst(AI, Alloc->getType(), "", Alloc);
-        DOUT << "escape" << Alloc->getParent()->getParent()->getName() << "\n";
-        Alloc->replaceAllUsesWith(BI);
-        // If it's an invoke, replace the invoke with a direct branch.
-        if (InvokeInst *CI = dyn_cast<InvokeInst>(Alloc)) {
-          BranchInst::Create(CI->getNormalDest(), Alloc);
+  ConstantInt* CI = dyn_cast<ConstantInt>(Size);
+  bool hasFinalizer = true;
+  
+  if (CI) {
+    if (ConstantExpr* CE = dyn_cast<ConstantExpr>(VT)) {
+      if (ConstantInt* C = dyn_cast<ConstantInt>(CE->getOperand(0))) {
+        VirtualTable* Table = (VirtualTable*)C->getZExtValue();
+        hasFinalizer = (((void**)Table)[0] != 0);
+      } else {
+        GlobalVariable* GV = dyn_cast<GlobalVariable>(CE->getOperand(0));
+        if (GV->hasInitializer()) {
+          Constant* Init = GV->getInitializer();
+          if (ConstantArray* CA = dyn_cast<ConstantArray>(Init)) {
+            Constant* V = CA->getOperand(0);
+            hasFinalizer = !V->isNullValue();
+          }
         }
-        Alloc->eraseFromParent();
-        return true;
       }
     }
+  } else {
+    return false;
+  }
+  
+  uint64_t NSize = CI->getZExtValue();
+  // If the class has a finalize method, do not stack allocate the object.
+  if (NSize < pageSize && !hasFinalizer) {
+    std::map<Instruction*, bool> visited;
+    bool esc = escapes(Alloc, visited);
+    if (!esc) {
+      AllocaInst* AI = new AllocaInst(Type::Int8Ty, Size, "", Alloc);
+      BitCastInst* BI = new BitCastInst(AI, Alloc->getType(), "", Alloc);
+      DOUT << "escape" << Alloc->getParent()->getParent()->getName() << "\n";
+      Alloc->replaceAllUsesWith(BI);
+      // If it's an invoke, replace the invoke with a direct branch.
+      if (InvokeInst *CI = dyn_cast<InvokeInst>(Alloc)) {
+        BranchInst::Create(CI->getNormalDest(), Alloc);
+      }
+      Alloc->eraseFromParent();
+      return true;
+    }
   }
   return false;
 }





More information about the vmkit-commits mailing list