[vmkit-commits] [vmkit] r77319 - in /vmkit/trunk/lib: JnJVM/Compiler/JavaJIT.cpp JnJVM/Compiler/JavaJIT.h JnJVM/Compiler/JavaJITOpcodes.cpp JnJVM/Compiler/JnjvmModule.cpp Mvm/Compiler/LoopSafePoints.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Tue Jul 28 07:53:20 PDT 2009


Author: geoffray
Date: Tue Jul 28 09:53:06 2009
New Revision: 77319

URL: http://llvm.org/viewvc/llvm-project?rev=77319&view=rev
Log:
Add safe points in loops during an LLVM pass, not directly. This way,
we can benefit from llvm loop optimization passes.


Added:
    vmkit/trunk/lib/Mvm/Compiler/LoopSafePoints.cpp
Modified:
    vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.h
    vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp
    vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp?rev=77319&r1=77318&r2=77319&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.cpp Tue Jul 28 09:53:06 2009
@@ -859,7 +859,6 @@
     
 }
 
-
 llvm::Function* JavaJIT::javaCompile() {
   PRINT_DEBUG(JNJVM_COMPILE, 1, COLOR_NORMAL, "compiling %s.%s\n",
               UTF8Buffer(compilingClass->name).cString(),
@@ -1045,28 +1044,6 @@
   if (returnType != Type::VoidTy) {
     endNode = llvm::PHINode::Create(returnType, "", endBlock);
   }
- 
-  if (TheCompiler->useCooperativeGC()) {
-    Value* threadId = getCurrentThread();
-     
-    Value* YieldPtr = 
-      GetElementPtrInst::Create(threadId,
-                                module->OffsetDoYieldInThreadConstant,
-                                "", currentBlock);
-
-    Value* Yield = new LoadInst(YieldPtr, "", currentBlock);
-
-    BasicBlock* continueBlock = createBasicBlock("After safe point");
-    BasicBlock* yieldBlock = createBasicBlock("In safe point");
-    BranchInst::Create(yieldBlock, continueBlock, Yield, currentBlock);
-
-    currentBlock = yieldBlock;
-    CallInst::Create(module->conditionalSafePoint, "", currentBlock);
-    BranchInst::Create(continueBlock, currentBlock);
-
-    currentBlock = continueBlock;
-  }
-
   
   if (isSynchro(compilingMethod->access))
     beginSynchronize();
@@ -1093,6 +1070,28 @@
     throwException(module->StackOverflowErrorFunction, 0, 0);
     currentBlock = noStackOverflow;
   }
+  
+  if (TheCompiler->useCooperativeGC()) {
+    Value* threadId = getCurrentThread();
+    
+    Value* GEP[2] = { module->constantZero, 
+                      module->OffsetDoYieldInThreadConstant };
+    
+    Value* YieldPtr = GetElementPtrInst::Create(threadId, GEP, GEP + 2, "",
+                                                currentBlock);
+
+    Value* Yield = new LoadInst(YieldPtr, "", currentBlock);
+
+    BasicBlock* continueBlock = createBasicBlock("After safe point");
+    BasicBlock* yieldBlock = createBasicBlock("In safe point");
+    BranchInst::Create(yieldBlock, continueBlock, Yield, currentBlock);
+
+    currentBlock = yieldBlock;
+    CallInst::Create(module->conditionalSafePoint, "", currentBlock);
+    BranchInst::Create(continueBlock, currentBlock);
+
+    currentBlock = continueBlock;
+  }
 
   compileOpcodes(&compilingClass->bytes->elements[start], codeLen); 
   

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.h?rev=77319&r1=77318&r2=77319&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.h (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJIT.h Tue Jul 28 09:53:06 2009
@@ -52,10 +52,6 @@
   ///
   bool handler;
 
-  /// backEdge - If the instruction is the first instruction of a basic block
-  /// where a forward opcode branches to, consider the block as a back edge.
-  ///
-  bool backEdge;
 };
 
 

Modified: vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp?rev=77319&r1=77318&r2=77319&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JavaJITOpcodes.cpp Tue Jul 28 09:53:06 2009
@@ -2423,9 +2423,6 @@
         uint16 index = tmp + readU2(bytecodes, i);
         if (!(opcodeInfos[index].newBlock))
           opcodeInfos[index].newBlock = createBasicBlock("GOTO or IF*");
-
-        if (index <= tmp) opcodeInfos[index].backEdge = true;
-
         break;
       }
       
@@ -2458,9 +2455,6 @@
           BasicBlock* block = createBasicBlock("tableswitch");
           opcodeInfos[index].newBlock = block;
         }
-        
-        if (index <= tmp) opcodeInfos[index].backEdge = true;
-        
         uint32 low = readU4(bytecodes, i);
         uint32 high = readU4(bytecodes, i) + 1;
         uint32 depl = high - low;
@@ -2470,7 +2464,6 @@
             BasicBlock* block = createBasicBlock("tableswitch");
             opcodeInfos[index2].newBlock = block;
           }
-          if (index2 <= tmp) opcodeInfos[index2].backEdge = true;
         }
         i = tmp + 12 + filled + (depl << 2);
         break;
@@ -2485,8 +2478,6 @@
           BasicBlock* block = createBasicBlock("tableswitch");
           opcodeInfos[index].newBlock = block;
         }
-        if (index <= tmp) opcodeInfos[index].backEdge = true;
-        
         uint32 nbs = readU4(bytecodes, i);
         for (uint32 cur = 0; cur < nbs; ++cur) {
           i += 4;
@@ -2495,7 +2486,6 @@
             BasicBlock* block = createBasicBlock("tableswitch");
             opcodeInfos[index2].newBlock = block;
           }
-          if (index2 <= tmp) opcodeInfos[index2].backEdge = true;
         }
         
         i = tmp + 8 + filled + (nbs << 3);
@@ -2567,7 +2557,6 @@
         uint16 index = tmp + readU2(bytecodes, i);
         if (!(opcodeInfos[index].newBlock))
           opcodeInfos[index].newBlock = createBasicBlock("true IF*NULL");
-        if (index <= tmp) opcodeInfos[index].backEdge = true;
         break;
       }
 

Modified: vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp?rev=77319&r1=77318&r2=77319&view=diff

==============================================================================
--- vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp (original)
+++ vmkit/trunk/lib/JnJVM/Compiler/JnjvmModule.cpp Tue Jul 28 09:53:06 2009
@@ -14,6 +14,7 @@
 #include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
 #include "llvm/PassManager.h"
+#include "llvm/Analysis/LoopPass.h"
 #include "llvm/Target/TargetData.h"
 
 #include "mvm/JIT.h"
@@ -356,6 +357,7 @@
 
 namespace mvm {
   llvm::FunctionPass* createEscapeAnalysisPass();
+  llvm::LoopPass* createLoopSafePointsPass();
 }
 
 namespace jnjvm {
@@ -371,6 +373,9 @@
   
   JavaFunctionPasses = new FunctionPassManager(TheModuleProvider);
   JavaFunctionPasses->add(new TargetData(TheModule));
+  if (cooperativeGC)
+    JavaFunctionPasses->add(mvm::createLoopSafePointsPass());
+
   JavaFunctionPasses->add(mvm::createEscapeAnalysisPass());
   JavaFunctionPasses->add(createLowerConstantCallsPass());
 }

Added: vmkit/trunk/lib/Mvm/Compiler/LoopSafePoints.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Compiler/LoopSafePoints.cpp?rev=77319&view=auto

==============================================================================
--- vmkit/trunk/lib/Mvm/Compiler/LoopSafePoints.cpp (added)
+++ vmkit/trunk/lib/Mvm/Compiler/LoopSafePoints.cpp Tue Jul 28 09:53:06 2009
@@ -0,0 +1,126 @@
+//===------- LoopSafePoints.cpp - Add safe points in loop headers ---------===//
+//
+//                     The VMKit project
+//
+// This file is distributed under the University of Illinois Open Source 
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/Compiler.h"
+
+using namespace llvm;
+
+namespace {
+
+  class VISIBILITY_HIDDEN LoopSafePoints : public LoopPass {
+  public:
+    static char ID;
+    
+    LoopSafePoints() : LoopPass((intptr_t)&ID) {}
+
+    virtual bool runOnLoop(Loop* L, LPPassManager& LPM);
+
+  private:
+    void insertSafePoint(BasicBlock* BB, Function* SafeFunction,
+                         Value* YieldPtr);
+  };
+
+  char LoopSafePoints::ID = 0;
+  RegisterPass<LoopSafePoints> X("LoopSafePoints",
+                                 "Add safe points in loop headers");
+
+void LoopSafePoints::insertSafePoint(BasicBlock* BB, Function* SafeFunction,
+                                     Value* YieldPtr) {
+  Instruction* I = BB->getFirstNonPHI();
+  BasicBlock* NBB = BB->splitBasicBlock(I);
+
+  NBB = NBB->getSinglePredecessor();
+  I = NBB->getTerminator();
+  BasicBlock* SU = (static_cast<BranchInst*>(I))->getSuccessor(0);
+  I->eraseFromParent();
+  
+  Value* Ld = new LoadInst(YieldPtr, "", NBB);
+  BasicBlock* yield = BasicBlock::Create("", BB->getParent());
+  BranchInst::Create(yield, SU, Ld, NBB);
+
+  CallInst::Create(SafeFunction, "", yield);
+  BranchInst::Create(SU, yield);
+}
+
+bool LoopSafePoints::runOnLoop(Loop* L, LPPassManager& LPM) {
+ 
+  BasicBlock* Header = L->getHeader();
+  Function *F = Header->getParent();  
+  Function* SafeFunction =
+    F->getParent()->getFunction("conditionalSafePoint");
+  if (!SafeFunction) return false;
+
+  Value* YieldPtr = 0;
+  
+  // Lookup the yield pointer.
+  for (Function::iterator BI = F->begin(), BE = F->end(); BI != BE; BI++) { 
+    BasicBlock *Cur = BI;
+
+    for (BasicBlock::iterator II = Cur->begin(), IE = Cur->end(); II != IE;) {
+      Instruction *I = II;
+      II++;
+      CallSite Call = CallSite::get(I);
+      if (Call.getInstruction() && Call.getCalledValue() == SafeFunction) {
+        if (BasicBlock* Incoming = Cur->getSinglePredecessor()) {
+          if (BranchInst* T = dyn_cast<BranchInst>(Incoming->getTerminator())) {
+            if (LoadInst* LI = dyn_cast<LoadInst>(T->getCondition())) {
+              YieldPtr = LI->getPointerOperand();
+              break;
+            }
+          }
+        }
+      }
+    }
+    if (YieldPtr) break;
+  }
+
+  assert(YieldPtr && "Could not find initial yield pointer.");
+
+  TerminatorInst* TI = Header->getTerminator();
+  
+  // Insert the check after the entry block if the entry block does the
+  // loop exit.
+  if (BranchInst* BI = dyn_cast<BranchInst>(TI)) {
+    if (BI->isConditional()) {
+
+      BasicBlock* First = BI->getSuccessor(0);
+      BasicBlock* Second = BI->getSuccessor(1);
+
+      bool containsFirst = L->contains(First);
+      bool containsSecond = L->contains(Second);
+
+      if (!containsFirst) {
+        insertSafePoint(Second, SafeFunction, YieldPtr);
+        return true;
+      }
+      
+      if (!containsSecond) {
+        insertSafePoint(First, SafeFunction, YieldPtr);
+        return true;
+      }
+    }
+  }
+  
+  insertSafePoint(Header, SafeFunction, YieldPtr);
+  return true;
+}
+
+}
+
+
+namespace mvm {
+
+LoopPass* createLoopSafePointsPass() {
+  return new LoopSafePoints();
+}
+
+}





More information about the vmkit-commits mailing list