[pypy-svn] r35510 - in pypy/dist/pypy/jit/codegen/llvm: . test
ericvrp at codespeak.net
ericvrp at codespeak.net
Fri Dec 8 22:24:09 CET 2006
Author: ericvrp
Date: Fri Dec 8 22:24:06 2006
New Revision: 35510
Modified:
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py
Log:
llvmjit use alloca's to store local variables to avoid having to deal with phi
nodes. Alloca returns a pointer to a stack variable. Its return value is
assigned only once (so valid SSA form) but the data it points to can be read
and written to many times. Thereby avoiding some difficulties.
Not more passing tests this time but at least the remaining failures are valid
SSA form now.
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Fri Dec 8 22:24:06 2006
@@ -36,8 +36,9 @@
class VarAddr(Var):
- def __init__(self, var):
- self.name = var.name + '_'
+ def __init__(self, v, asm):
+ self.name = '%p' + v.name[2:]
+ asm.append(' %s=alloca %s' % (self.operand2(), v.type())) #note: sideeffect!
def type(self):
return 'int*'
@@ -212,7 +213,7 @@
#log(self.rgenop.asms)
asm_string = ''
for asm in self.rgenop.asms:
- asm_string += '\n'.join(asm) + '\n\n'
+ asm_string += '\n'.join(asm) + '\n'
self.rgenop.asms = None #XXX or [] ?
log(asm_string)
llvmjit.parse(asm_string)
@@ -230,15 +231,14 @@
inputargs_gv_ = []
for v in inputargs_gv:
- v_ = VarAddr(v)
- inputargs_gv_.append(v_)
- self.asm.append(' %s=alloca %s' % (v_.operand2(), v.type()))
+ v_ = VarAddr(v, self.asm)
self.asm.append(' store %s,%s %s' % (v.operand(), v_.type(), v_.operand2()))
+ inputargs_gv_.append(v_)
#self.asm.append(self.label.operand2())
#note: alloca's should be appended to self.rgenop.asms[0]
self.asm = self.rgenop.open_asm() #note: previous self.asm already appended to self.asms
- return inputargs_gv #XXX make this inputargs_gv_
+ return inputargs_gv_ #XXX make this inputargs_gv_
def _close(self):
log('%s Builder._close' % self.label.operand2())
@@ -271,10 +271,42 @@
def _rgenop2_generic(self, llvm_opcode, gv_arg1, gv_arg2):
log('%s Builder._rgenop2_generic %s %s,%s' % (
self.label.operand2(), llvm_opcode, gv_arg1.operand(), gv_arg2.operand2()))
+
+ #XXX can't this be shorter?
+ if gv_arg1.is_const or isinstance(gv_arg1, VarAddr):
+ gv_arg1_ = gv_arg1
+ else:
+ gv_arg1_ = VarAddr(gv_arg1, self.rgenop.asms[0])
+ if isinstance(gv_arg1_, VarAddr):
+ gv_arg1_tmp = Var()
+ self.asm.append(' %s=load %s' % (gv_arg1_tmp.operand2(), gv_arg1_.operand()))
+ else:
+ gv_arg1_tmp = gv_arg1_
+
+ if gv_arg2.is_const or isinstance(gv_arg2, VarAddr):
+ gv_arg2_ = gv_arg2
+ else:
+ gv_arg2_ = VarAddr(gv_arg2, self.rgenop.asms[0])
+ if isinstance(gv_arg2_, VarAddr):
+ gv_arg2_tmp = Var()
+ self.asm.append(' %s=load %s' % (gv_arg2_tmp.operand2(), gv_arg2_.operand()))
+ else:
+ gv_arg2_tmp = gv_arg2_
+
gv_result = Var()
self.asm.append(' %s=%s %s,%s' % (
- gv_result.operand2(), llvm_opcode, gv_arg1.operand(), gv_arg2.operand2()))
- return gv_result
+ gv_result.operand2(), llvm_opcode, gv_arg1_tmp.operand(), gv_arg2_tmp.operand2()))
+
+ if llvm_opcode[:3] == 'set': #HACK
+ #XXX We assume there will always be a jump_if_true/false right after an op_int_eq/etc.
+ # Because we don't yet keep track of non-ints it will be difficult to do the
+ # right thing in jump_if_true/false. So this is a hack we want to fix later!
+ return gv_result
+
+ gv_result_ = VarAddr(gv_result, self.rgenop.asms[0])
+ self.asm.append(' store %s,%s' % (gv_result.operand(), gv_result_.operand()))
+
+ return gv_result_
def op_int_add(self, gv_x, gv_y): return self._rgenop2_generic('add' , gv_x, gv_y)
def op_int_sub(self, gv_x, gv_y): return self._rgenop2_generic('sub' , gv_x, gv_y)
@@ -301,8 +333,9 @@
def enter_next_block(self, kinds, args_gv):
label = Label()
- log('%s Builder.enter_next_block (was %s), prev_block_closed=%s' % (
- label.operand2(), self.label.operand2(), str(self.prev_block_closed)))
+ log('%s Builder.enter_next_block (was %s), prev_block_closed=%s, %s' % (
+ label.operand2(), self.label.operand2(), str(self.prev_block_closed),
+ [v.operand() for v in args_gv]))
self.label = label
if not self.prev_block_closed: #there are not always explicit branches to blocks
self.asm.append(' br ' + self.label.operand() + ' ;fixup')
@@ -359,8 +392,13 @@
#self.mc.JNE(rel32(targetbuilder.mc.tell()))
return targetbuilder
- def op_int_is_true(self, gv_x):
- log('%s Build.op_int_is_true %s' % (self.label.operand2(), gv_x.operand()))
+ def op_int_is_true(self, gv_x_):
+ log('%s Build.op_int_is_true %s' % (self.label.operand2(), gv_x_.operand()))
+ if isinstance(gv_x_, VarAddr):
+ gv_x = Var()
+ self.asm.append(' %s=load %s' % (gv_x.operand2(), gv_x_.operand()))
+ else:
+ gv_x = gv_x_
gv_result = Var() #XXX need to mark it a 'bool' somehow
self.asm.append(' %s=trunc %s to bool' % (gv_result.operand2(), gv_x.operand()))
return gv_result
@@ -377,9 +415,15 @@
','.join([v.operand() for v in args_gv])))
return gv_returnvar
- def finish_and_return(self, sigtoken, gv_returnvar):
+ def finish_and_return(self, sigtoken, gv_returnvar_):
log('%s Builder.finish_and_return %s,%s' % (
- self.label.operand2(), sigtoken, gv_returnvar.operand()))
+ self.label.operand2(), sigtoken, gv_returnvar_.operand()))
+
+ if isinstance(gv_returnvar_, VarAddr):
+ gv_returnvar = Var()
+ self.asm.append(' %s=load %s' % (gv_returnvar.operand2(), gv_returnvar_.operand()))
+ else:
+ gv_returnvar = gv_returnvar_
self.asm.append(' ret ' + gv_returnvar.operand())
#numargs = sigtoken # for now
#initialstackdepth = numargs + 1
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py Fri Dec 8 22:24:06 2006
@@ -28,4 +28,3 @@
test_fact_direct = skip
test_fact_compile = skip
-
More information about the Pypy-commit
mailing list