[pypy-svn] r65010 - in pypy/branch/pyjitpl5/pypy/jit/backend/llvm: . test

arigo at codespeak.net arigo at codespeak.net
Sun May 3 23:04:46 CEST 2009


Author: arigo
Date: Sun May  3 23:04:43 2009
New Revision: 65010

Modified:
   pypy/branch/pyjitpl5/pypy/jit/backend/llvm/llvm_rffi.py
   pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py
   pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_runner.py
Log:
Add some mess with phi nodes instead of doing tail calls.
Solves at least in simple cases the issue of loops consuming
the stack.


Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/llvm_rffi.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/llvm_rffi.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/llvm_rffi.py	Sun May  3 23:04:43 2009
@@ -68,6 +68,13 @@
     SLT = 40     # signed less than
     SLE = 41     # signed less or equal
 
+class CallConv:
+    C           = 0
+    Fast        = 8
+    Cold        = 9
+    X86Stdcall  = 64
+    X86Fastcall = 65
+
 # ____________________________________________________________
 
 LLVMDisposeMessage = llexternal('LLVMDisposeMessage', [rffi.CCHARP],
@@ -106,6 +113,10 @@
                               rffi.CCHARP,                  # name
                               LLVMTypeRef],                 # function type
                              LLVMValueRef)
+LLVMSetFunctionCallConv = llexternal('LLVMSetFunctionCallConv',
+                                     [LLVMValueRef,         # function
+                                      rffi.UINT],           # new call conv
+                                     lltype.Void)
 LLVMGetParam = llexternal('LLVMGetParam',
                           [LLVMValueRef,                    # function
                            rffi.UINT],                      # index
@@ -120,18 +131,28 @@
                              [LLVMValueRef,        # call instruction
                               rffi.INT],           # flag: is_tail
                              lltype.Void)
-
+LLVMAddIncoming = llexternal('LLVMAddIncoming',
+                             [LLVMValueRef,                 # phi node
+                              rffi.CArrayPtr(LLVMValueRef), # incoming values
+                              rffi.CArrayPtr(LLVMBasicBlockRef), # incom.blocks
+                              rffi.UINT],                   # count
+                             lltype.Void)
 LLVMCreateBuilder = llexternal('LLVMCreateBuilder', [], LLVMBuilderRef)
 LLVMPositionBuilderAtEnd = llexternal('LLVMPositionBuilderAtEnd',
                                       [LLVMBuilderRef,      # builder
                                        LLVMBasicBlockRef],  # block
                                       lltype.Void)
+LLVMGetInsertBlock = llexternal('LLVMGetInsertBlock', [LLVMBuilderRef],
+                                LLVMBasicBlockRef)
 LLVMDisposeBuilder = llexternal('LLVMDisposeBuilder', [LLVMBuilderRef],
                                 lltype.Void)
 
 LLVMBuildRet = llexternal('LLVMBuildRet', [LLVMBuilderRef,  # builder,
                                            LLVMValueRef],   # result
                           LLVMValueRef)
+LLVMBuildBr = llexternal('LLVMBuildBr', [LLVMBuilderRef,    # builder,
+                                         LLVMBasicBlockRef],# destination block
+                         LLVMValueRef)
 LLVMBuildCondBr = llexternal('LLVMBuildCondBr',
                              [LLVMBuilderRef,      # builder
                               LLVMValueRef,        # condition
@@ -178,6 +199,11 @@
                             LLVMValueRef,    # right-hand side
                             rffi.CCHARP],    # name of result
                            LLVMValueRef)
+LLVMBuildPhi = llexternal('LLVMBuildPhi',
+                          [LLVMBuilderRef,   # builder
+                           LLVMTypeRef,      # type of value
+                           rffi.CCHARP],     # name of result
+                          LLVMValueRef)
 LLVMBuildCall = llexternal('LLVMBuildCall',
                            [LLVMBuilderRef,               # builder
                             LLVMValueRef,                 # function

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/runner.py	Sun May  3 23:04:43 2009
@@ -70,14 +70,45 @@
         func = llvm_rffi.LLVMAddFunction(self.module, "", ty_func)
         loop._llvm_func = func
         self.vars = {}
-        for i in range(len(loop.inputargs)):
-            self.vars[loop.inputargs[i]] = llvm_rffi.LLVMGetParam(func, i)
         self.builder = llvm_rffi.LLVMCreateBuilder()
-        bb_start = llvm_rffi.LLVMAppendBasicBlock(func, "entry")
-        self.pending_blocks = [(loop.operations, bb_start)]
+        bb_entry = llvm_rffi.LLVMAppendBasicBlock(func, "entry")
+        bb_start_code = llvm_rffi.LLVMAppendBasicBlock(func, "")
+        self.bb_start_code = bb_start_code
+        llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_entry)
+        llvm_rffi.LLVMBuildBr(self.builder, bb_start_code)
+        #
+        llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_start_code)
+        self.phi_incoming_blocks = [bb_entry]
+        self.phi_incoming_values = []
+        for i in range(len(loop.inputargs)):
+            phi = llvm_rffi.LLVMBuildPhi(self.builder, self.ty_int, "")
+            incoming = [llvm_rffi.LLVMGetParam(func, i)]
+            self.phi_incoming_values.append(incoming)
+            self.vars[loop.inputargs[i]] = phi
+        #
+        self.pending_blocks = [(loop.operations, bb_start_code)]
         while self.pending_blocks:
             operations, bb = self.pending_blocks.pop()
             self._generate_branch(operations, bb)
+        #
+        incoming_blocks = lltype.malloc(
+            rffi.CArray(llvm_rffi.LLVMBasicBlockRef),
+            len(self.phi_incoming_blocks), flavor='raw')
+        incoming_values = lltype.malloc(
+            rffi.CArray(llvm_rffi.LLVMValueRef),
+            len(self.phi_incoming_blocks), flavor='raw')
+        for j in range(len(self.phi_incoming_blocks)):
+            incoming_blocks[j] = self.phi_incoming_blocks[j]
+        for i in range(len(loop.inputargs)):
+            phi = self.vars[loop.inputargs[i]]
+            incoming = self.phi_incoming_values[i]
+            for j in range(len(self.phi_incoming_blocks)):
+                incoming_values[j] = incoming[j]
+            llvm_rffi.LLVMAddIncoming(phi, incoming_values, incoming_blocks,
+                                      len(self.phi_incoming_blocks))
+        lltype.free(incoming_values, flavor='raw')
+        lltype.free(incoming_blocks, flavor='raw')
+        #
         llvm_rffi.LLVMDisposeBuilder(self.builder)
         self.vars = None
         #...
@@ -208,15 +239,24 @@
         llvm_rffi.LLVMPositionBuilderAtEnd(self.builder, bb_on_track)
 
     def generate_JUMP(self, op):
-        args = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), len(op.args),
-                             flavor='raw')
-        for i in range(len(op.args)):
-            args[i] = self.getintarg(op.args[i])
-        res = llvm_rffi.LLVMBuildCall(self.builder, op.jump_target._llvm_func,
-                                      args, len(op.args), "")
-        llvm_rffi.LLVMBuildRet(self.builder, res)
-        llvm_rffi.LLVMSetTailCall(res, True)
-        lltype.free(args, flavor='raw')
+        if op.jump_target is self.compiling_loop:
+            basicblock = llvm_rffi.LLVMGetInsertBlock(self.builder)
+            self.phi_incoming_blocks.append(basicblock)
+            for i in range(len(op.args)):
+                incoming = self.phi_incoming_values[i]
+                incoming.append(self.getintarg(op.args[i]))
+            llvm_rffi.LLVMBuildBr(self.builder, self.bb_start_code)
+        else:
+            args = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef),
+                                 len(op.args), flavor='raw')
+            for i in range(len(op.args)):
+                args[i] = self.getintarg(op.args[i])
+            res = llvm_rffi.LLVMBuildCall(self.builder,
+                                          op.jump_target._llvm_func,
+                                          args, len(op.args), "")
+            llvm_rffi.LLVMSetTailCall(res, True)     # XXX no effect :-(
+            llvm_rffi.LLVMBuildRet(self.builder, res)
+            lltype.free(args, flavor='raw')
 
     def generate_FAIL(self, op):
         self._ensure_out_args(len(op.args))

Modified: pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_runner.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/llvm/test/test_runner.py	Sun May  3 23:04:43 2009
@@ -45,8 +45,8 @@
     cpu = LLVMCPU(None)
     cpu.setup_once()
     cpu.compile_operations(loop)
-    cpu.set_future_value_int(0, 7)
-    cpu.set_future_value_int(1, 6)
+    cpu.set_future_value_int(0, 2**29)
+    cpu.set_future_value_int(1, 3)
     cpu.set_future_value_int(2, 0)
     cpu.execute_operations(loop)
-    assert cpu.get_latest_value_int(0) == 42
+    assert cpu.get_latest_value_int(0) == 3*(2**29)



More information about the Pypy-commit mailing list