[pypy-commit] pypy libgccjit-backend: Get test_field_basic to pass

dmalcolm noreply at buildbot.pypy.org
Tue Dec 23 15:13:56 CET 2014


Author: David Malcolm <dmalcolm at redhat.com>
Branch: libgccjit-backend
Changeset: r75081:7842cdbb5db6
Date: 2014-12-23 09:21 -0500
http://bitbucket.org/pypy/pypy/changeset/7842cdbb5db6/

Log:	Get test_field_basic to pass

diff --git a/rpython/jit/backend/libgccjit/assembler.py b/rpython/jit/backend/libgccjit/assembler.py
--- a/rpython/jit/backend/libgccjit/assembler.py
+++ b/rpython/jit/backend/libgccjit/assembler.py
@@ -4,7 +4,7 @@
 from rpython.jit.backend.llsupport.regalloc import FrameManager
 from rpython.jit.backend.model import CompiledLoopToken
 from rpython.jit.backend.libgccjit.rffi_bindings import make_eci, Library, make_param_array, make_field_array, Context, Type
-from rpython.jit.metainterp.history import BoxInt, ConstInt, BoxFloat, ConstFloat
+from rpython.jit.metainterp.history import BoxInt, ConstInt, BoxFloat, ConstFloat, BoxPtr, ConstPtr
 from rpython.jit.metainterp.resoperation import *
 from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref, cast_object_to_ptr
 from rpython.rtyper.lltypesystem.rffi import *
@@ -196,12 +196,15 @@
         self.t_bool = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_BOOL)
         self.t_void_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID_PTR)
         self.t_void = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_VOID)
+        self.t_char_ptr = self.ctxt.get_type(self.lib.GCC_JIT_TYPE_CHAR).get_pointer()
 
         self.u_signed = self.ctxt.new_field(self.t_Signed, "u_signed")
         self.u_float = self.ctxt.new_field(self.t_float, "u_float")
+        self.u_ptr = self.ctxt.new_field(self.t_void_ptr, "u_ptr")
         self.t_any = self.ctxt.new_union_type ("any",
                                                [self.u_signed,
-                                                self.u_float])
+                                                self.u_float,
+                                                self.u_ptr])
 
     def setup(self, looptoken):
         allblocks = self.get_asmmemmgr_blocks(looptoken)
@@ -429,7 +432,7 @@
         print(' %s' % expr.__dict__)
         """
 
-        if isinstance(expr, (BoxInt, BoxFloat)):
+        if isinstance(expr, (BoxInt, BoxFloat, BoxPtr)):
             return self.get_box_as_lvalue(expr).as_rvalue()
         elif isinstance(expr, ConstInt):
             #print('value: %r' % expr.value)
@@ -441,6 +444,11 @@
             #print('type(value): %r' % type(expr.value))
             return self.ctxt.new_rvalue_from_double(self.t_float,
                                                     expr.value)#r_double(expr.value))
+        elif isinstance(expr, ConstPtr):
+            #print('value: %r' % expr.value)
+            #print('type(value): %r' % type(expr.value))
+            return self.ctxt.new_rvalue_from_ptr(self.t_void_ptr,
+                                                 expr.value)
         raise ValueError('unhandled expr: %s %s' % (expr, type(expr)))
 
     def get_box_as_lvalue(self, box):
@@ -463,7 +471,7 @@
         print(' %s' % dir(expr))
         print(' %s' % expr.__dict__)
         """
-        if isinstance(expr, (BoxInt, BoxFloat)):
+        if isinstance(expr, (BoxInt, BoxFloat, BoxPtr)):
             return self.get_box_as_lvalue(expr)
             
         raise ValueError('unhandled expr: %s' % expr)
@@ -473,6 +481,8 @@
             return self.t_Signed;
         elif isinstance(box, BoxFloat):
             return self.t_float;
+        elif isinstance(box, BoxPtr):
+            return self.t_void_ptr;
         else:
             raise ValueError('unhandled box: %s %s' % (box, type(box)))
 
@@ -481,6 +491,8 @@
             return self.u_signed;
         elif isinstance(expr, (BoxFloat, ConstFloat)):
             return self.u_float;
+        elif isinstance(expr, (BoxPtr, ConstPtr)):
+            return self.u_ptr;
         else:
             raise ValueError('unhandled expr: %s %s' % (expr, type(expr)))        
 
@@ -788,3 +800,72 @@
         self.impl_float_cmp(resop, self.lib.GCC_JIT_COMPARISON_GT)
     def emit_float_ge(self, resop):
         self.impl_float_cmp(resop, self.lib.GCC_JIT_COMPARISON_GE)
+
+    def impl_get_lvalue_for_field(self, ptr_expr, fielddescr):
+        assert isinstance(ptr_expr, (BoxPtr, ConstPtr))
+        #print(fielddescr)
+        #print(dir(fielddescr))
+        #print('fielddescr.field_size: %r' % fielddescr.field_size)
+
+        ptr = self.expr_to_rvalue(ptr_expr)
+
+        # Cast to (char *) so we can use offset:
+        # ((char *)ARG0)
+        ptr = self.ctxt.new_cast(ptr, self.t_char_ptr)
+
+        # ((char *)ARG0)[offset]
+        ptr = self.ctxt.new_array_access(
+            ptr,
+            self.ctxt.new_rvalue_from_int(self.t_Signed,
+                                          r_int(fielddescr.offset)))
+
+        # (char **)(((char *)ARG0)[offset])
+        field_ptr_address = ptr.get_address ()
+
+        # ...and cast back to the correct type:
+        if fielddescr.is_pointer_field():
+            t_field = self.t_void_ptr
+        elif fielddescr.is_float_field():
+            # FIXME: do we need to handle C float vs C double?
+            t_field = self.t_float
+        else:
+            t_field = self.ctxt.get_int_type(r_int(fielddescr.field_size),
+                                             r_int(fielddescr.is_field_signed()))
+
+        # (T *)(char **)(((char *)ARG0)[offset])
+        field_ptr = self.ctxt.new_cast(field_ptr_address,
+                                       t_field.get_pointer())
+
+        # and dereference:
+        # *(T *)(char **)(((char *)ARG0)[offset])
+        field_lvalue = field_ptr.dereference()
+
+        return field_lvalue, t_field
+
+    def emit_getfield_gc(self, resop):
+        #print(repr(resop))
+        assert isinstance(resop._arg0, (BoxPtr, ConstPtr))
+        lvalres = self.expr_to_lvalue(resop.result)
+        field_lvalue, t_field = self.impl_get_lvalue_for_field(
+            resop._arg0,
+            resop.getdescr())
+        self.b_current.add_assignment(
+            lvalres,
+            self.ctxt.new_cast(field_lvalue.as_rvalue(),
+                               self.get_type_for_box(resop.result)))
+
+    def emit_setfield_gc(self, resop):
+        #print(repr(resop))
+        assert isinstance(resop._arg0, (BoxPtr, ConstPtr))
+        #print(resop._arg1)
+
+        field_lvalue, t_field = self.impl_get_lvalue_for_field(
+            resop._arg0,
+            resop.getdescr())
+
+        self.b_current.add_assignment(
+            field_lvalue,
+            
+            # ... = ARG1,
+            self.ctxt.new_cast(self.expr_to_rvalue(resop._arg1),
+                               t_field))
diff --git a/rpython/jit/backend/libgccjit/rffi_bindings.py b/rpython/jit/backend/libgccjit/rffi_bindings.py
--- a/rpython/jit/backend/libgccjit/rffi_bindings.py
+++ b/rpython/jit/backend/libgccjit/rffi_bindings.py
@@ -308,6 +308,12 @@
                                               self.GCC_JIT_TYPE_P]),
 
                 (self.GCC_JIT_LVALUE_P,
+                 'gcc_jit_context_new_array_access', [self.GCC_JIT_CONTEXT_P,
+                                                      self.GCC_JIT_LOCATION_P,
+                                                      self.GCC_JIT_RVALUE_P,
+                                                      self.GCC_JIT_RVALUE_P]),
+
+                (self.GCC_JIT_LVALUE_P,
                  'gcc_jit_lvalue_access_field', [self.GCC_JIT_LVALUE_P,
                                                  self.GCC_JIT_LOCATION_P,
                                                  self.GCC_JIT_FIELD_P]),
@@ -317,6 +323,14 @@
                                                       self.GCC_JIT_LOCATION_P,
                                                       self.GCC_JIT_FIELD_P]),
 
+                (self.GCC_JIT_LVALUE_P,
+                 'gcc_jit_rvalue_dereference', [self.GCC_JIT_RVALUE_P,
+                                                self.GCC_JIT_LOCATION_P]),
+
+                (self.GCC_JIT_RVALUE_P,
+                 'gcc_jit_lvalue_get_address', [self.GCC_JIT_LVALUE_P,
+                                                self.GCC_JIT_LOCATION_P]),
+
                 ############################################################
                 # Statement-creation.
                 ############################################################
@@ -698,6 +712,15 @@
                                                         rvalue.inner_rvalue,
                                                         type_.inner_type))
 
+    def new_array_access(self, ptr, index):
+        return LValue(self.lib,
+                      self,
+                      self.lib.gcc_jit_context_new_array_access(
+                          self.inner_ctxt,
+                          self.lib.null_location_ptr,
+                          ptr.inner_rvalue,
+                          index.inner_rvalue))
+
 class LibgccjitError(Exception):
     def __init__(self, ctxt):
         self.msg = charp2str(ctxt.lib.gcc_jit_context_get_last_error (ctxt.inner_ctxt))
@@ -763,6 +786,13 @@
                                                                 self.lib.null_location_ptr,
                                                                 field.inner_field))
 
+    def dereference(self):
+        return LValue(self.lib,
+                      self,
+                      self.lib.gcc_jit_rvalue_dereference(
+                          self.inner_rvalue,
+                          self.lib.null_location_ptr))
+
 class LValue(Object):
     def __init__(self, lib, ctxt, inner_lvalue):
         Object.__init__(self, lib, ctxt, inner_lvalue)
@@ -780,6 +810,13 @@
                                                             self.lib.null_location_ptr,
                                                             field.inner_field))
 
+    def get_address(self):
+        return RValue(self.lib,
+                      self,
+                      self.lib.gcc_jit_lvalue_get_address(
+                          self.inner_lvalue,
+                          self.lib.null_location_ptr))
+
 class Param(Object):
     def __init__(self, lib, ctxt, inner_param):
         Object.__init__(self, lib, ctxt, inner_param)


More information about the pypy-commit mailing list