[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