[pypy-svn] r6267 - pypy/branch/pypy-genc/translator

arigo at codespeak.net arigo at codespeak.net
Thu Sep 2 15:32:48 CEST 2004


Author: arigo
Date: Thu Sep  2 15:32:47 2004
New Revision: 6267

Modified:
   pypy/branch/pypy-genc/translator/genc.py
   pypy/branch/pypy-genc/translator/typer.py
Log:
In-line constants by allowing convertion operations to provide a known answer.


Modified: pypy/branch/pypy-genc/translator/genc.py
==============================================================================
--- pypy/branch/pypy-genc/translator/genc.py	(original)
+++ pypy/branch/pypy-genc/translator/genc.py	Thu Sep  2 15:32:47 2004
@@ -5,7 +5,7 @@
 import autopath, os, re
 from pypy.objspace.flow.model import Variable, Constant, UndefinedConstant
 from pypy.objspace.flow.model import Block, Link, traverse
-from pypy.translator.typer import LLFunction, LLOp
+from pypy.translator.typer import LLFunction, LLOp, LLConst
 from pypy.annotation import model as annmodel
 
 
@@ -45,6 +45,7 @@
         self.genc = genc
         self.bindings = bindings
         self.r_constants = {}
+        self.globaldefs = []
         self.lloperations = {'convert': {}, 'release': {}}
         self.parse_operation_templates()
 
@@ -88,6 +89,15 @@
             return   # retry
         raise TypingError((opname,) + hltypes)
 
+    def knownanswer(self, llname):
+        if hasattr(llname, 'known_answer'):
+            if hasattr(llname, 'globaldef'):  # global definition required
+                self.consts_used.append(llname.globaldef)
+                del llname.globaldef
+            return llname.known_answer
+        else:
+            return None
+
     # ____________________________________________________________
 
     def constant_representation(self, value):
@@ -114,6 +124,7 @@
                 # can convert the constant to a C int
                 def writer(z):
                     return '%s = %d;' % (z, value)
+                writer.known_answer = [LLConst(self.R_INT, '%d' % value)]
                 conv[r, self.R_INT] = writer, False
                 # can convert the constant to a PyObject*
                 def writer(z, err):
@@ -310,7 +321,8 @@
             seen[a] = True
         for a in lllocals:
             if a not in seen:
-                print >> f, '\t%s %s;' % (a.type, a.name)
+                if not isinstance(a, LLConst):
+                    print >> f, '\t%s %s;' % (a.type, a.name)
                 seen[a] = True
         print >> f
 

Modified: pypy/branch/pypy-genc/translator/typer.py
==============================================================================
--- pypy/branch/pypy-genc/translator/typer.py	(original)
+++ pypy/branch/pypy-genc/translator/typer.py	Thu Sep  2 15:32:47 2004
@@ -13,6 +13,9 @@
         self.type = type   # low-level type in any format, e.g. a C type name
         self.name = name
 
+class LLConst(LLVar):
+    "An LLVar whose name is abused to be a constant expression."
+
 class LLOp:
     "A low-level operation."
     def __init__(self, name, args, errtarget=None):
@@ -53,6 +56,10 @@
 #       Called when no match is found in lloperations.  This function must
 #       either extend lloperations and return (to retry), or raise an
 #       exception (to stop).
+#
+#   def knownanswer(self, llname):
+#       Optionally returns a list of LLVars that give the well-known, constant
+#       answer to the low-level operation name 'llname'; else return None.
 # ____________________________________________________________
 
 
@@ -67,6 +74,7 @@
         self.represent    = typeset.represent
         self.lloperations = typeset.lloperations
         self.typingerror  = typeset.typingerror
+        self.knownanswer  = typeset.knownanswer
         self.hltypes = {}
         self.llreprs = {}
 
@@ -207,7 +215,8 @@
             if to == hltype:
                 yield frm
 
-    def operation(self, opname, args, result=None, errlabel=None):
+    def operation(self, opname, args, result=None, errlabel=None,
+                  resulttype=None):
         "Helper to build the LLOps for a single high-level operation."
         # get the hltypes of the input arguments
         for v in args:
@@ -216,7 +225,7 @@
         directions = [self.convert_from] * len(args)
         # append the hltype of the result
         if result:
-            self.makevar(result)
+            self.makevar(result, resulttype)
             args_t.append(self.hltypes[result])
             directions.append(self.convert_to)
         # enumerate possible signatures until we get a match
@@ -230,15 +239,21 @@
             # if 'typingerror' did not raise an exception, try again.
             # infinite recursion here means that 'typingerror' did not
             # correctly extend 'lloperations'.
-            self.operation(opname, args, result, errlabel)
+            self.operation(opname, args, result, errlabel, resulttype)
             return
+        # check if the answer has an existing well-known answer
+        if resulttype is not None:  # if we are allowed to patch self.llreprs
+            llrepr = self.knownanswer(llname)
+            if llrepr is not None:
+                # patch self.llreprs and we're done
+                self.llreprs[result] = llrepr
+                return
         # convert input args to temporary variables
         llargs = []
         for v, v_t, s_t in zip(args, args_t, sig):
             if v_t != s_t:
                 tmp = Variable()
-                self.makevar(tmp, hltype=s_t)
-                self.operation('convert', [v], tmp)
+                self.operation('convert', [v], tmp, resulttype=s_t)
                 v = tmp
             llargs += self.llreprs[v]
         # generate an error label if the operation can fail



More information about the Pypy-commit mailing list