[pypy-svn] r17395 - in pypy/dist/pypy/translator/llvm: . module

ericvrp at codespeak.net ericvrp at codespeak.net
Thu Sep 8 22:01:52 CEST 2005


Author: ericvrp
Date: Thu Sep  8 22:01:46 2005
New Revision: 17395

Added:
   pypy/dist/pypy/translator/llvm/exception.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/llvm/build_llvm_module.py
   pypy/dist/pypy/translator/llvm/codewriter.py
   pypy/dist/pypy/translator/llvm/gc.py
   pypy/dist/pypy/translator/llvm/genllvm.py
   pypy/dist/pypy/translator/llvm/module/extfunction.py
Log:
* refactored more code into gc.py

  The goal of this refactoring is to make it easier to use llvm's optimization
  capabilities. In this case it would be good to let llvm know that our GC_malloc
  is basically just some allocation on the heap that can be moved to the stack
  if this helps speeding up the code.
  These kind of optimization will in future probably also be handled by pypy
  transformations. But it makes sence to allow llvm to show it's tricks,
  if only so we know what can be achived.

* started to refactor exception handling into a policy.

  The goal here is again to keep related code in one place so experimentation is easier.
  To test this I would like to write a 'fast' exception policy 
  (as opposed to the CPython one) that does not use issubclass(..) but does only direct
  exception class comparison.



Modified: pypy/dist/pypy/translator/llvm/build_llvm_module.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/build_llvm_module.py	(original)
+++ pypy/dist/pypy/translator/llvm/build_llvm_module.py	Thu Sep  8 22:01:46 2005
@@ -12,7 +12,6 @@
 from pypy.translator.tool import stdoutcapture
 from pypy.translator.llvm.log import log
 
-EXCEPTIONS_SWITCHES   = "-enable-correct-eh-support"
 SIMPLE_OPTIMIZATION_SWITCHES = (" ".join([
     # kill code - hopefully to speed things up
     "-globaldce -adce -deadtypeelim -simplifycfg",
@@ -84,15 +83,16 @@
 
     cmds = ["llvm-as < %s.ll | opt %s -f -o %s.bc" % (b, OPTIMIZATION_SWITCHES, b)]
 
-    if False and sys.maxint == 2147483647:        #32 bit platform
-        cmds.append("llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b))
+    generate_s_file = False
+    if generate_s_file and sys.maxint == 2147483647:        #32 bit platform
+        cmds.append("llc %s %s.bc -f -o %s.s" % (genllvm.exceptionpolicy.llc_options(), b, b))
         cmds.append("as %s.s -o %s.o" % (b, b))
         if exe_name:
             cmds.append("gcc %s.o %s -lm -ldl -pipe -o %s" % (b, gc_libs, exe_name))
         object_files.append("%s.o" % b)
     else:       #assume 64 bit platform (x86-64?)
         #this special case for x86-64 (called ia64 in llvm) can go as soon as llc supports ia64 assembly output!
-        cmds.append("llc %s %s.bc -march=c -f -o %s.c" % (EXCEPTIONS_SWITCHES, b, b))
+        cmds.append("llc %s %s.bc -march=c -f -o %s.c" % (genllvm.exceptionpolicy.llc_options(), b, b))
         if exe_name:
             #XXX TODO: use CFLAGS when available
             cmds.append("gcc %s.c -c -O3 -pipe" % (b,))

Modified: pypy/dist/pypy/translator/llvm/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/codewriter.py	(original)
+++ pypy/dist/pypy/translator/llvm/codewriter.py	Thu Sep  8 22:01:46 2005
@@ -8,12 +8,13 @@
 DEFAULT_CCONV    = 'fastcc'    #ccc/fastcc
 
 class CodeWriter(object): 
-    def __init__(self, f, word, uword, show_line_number=False): 
+    def __init__(self, f, genllvm, show_line_number=False): 
         self.f = f
+        self.genllvm = genllvm
+        self.word  = genllvm.db.get_machine_word()
+        self.uword = genllvm.db.get_machine_uword()
         self.show_line_numbers = show_line_number
         self.n_lines = 0
-        self.word = word
-        self.uword = uword
 
     def append(self, line): 
         self.n_lines += 1
@@ -74,7 +75,6 @@
                     % (intty, cond, defaultdest, labels))
 
     def openfunc(self, decl, is_entrynode=False, cconv=DEFAULT_CCONV): 
-        self.malloc_count = count(0).next
         self.newline()
         if is_entrynode:
             linkage_type = ''
@@ -141,18 +141,8 @@
                         "%(fromvar)s to %(targettype)s" % locals())
 
     def malloc(self, targetvar, type_, size=1, atomic=False, cconv=DEFAULT_CCONV):
-        n = self.malloc_count()
-        if n:
-            cnt = ".%d" % n
-        else:
-            cnt = ""
-        postfix = ('', '_atomic')[atomic]
-        word  = self.word
-        uword = self.uword
-        self.indent("%%malloc.Size%(cnt)s = getelementptr %(type_)s* null, %(uword)s %(size)s" % locals())
-        self.indent("%%malloc.SizeU%(cnt)s = cast %(type_)s* %%malloc.Size%(cnt)s to %(uword)s" % locals())
-        self.indent("%%malloc.Ptr%(cnt)s = call %(cconv)s sbyte* %%gc_malloc%(postfix)s(%(uword)s %%malloc.SizeU%(cnt)s)" % locals())
-        self.indent("%(targetvar)s = cast sbyte* %%malloc.Ptr%(cnt)s to %(type_)s*" % locals())
+        for s in self.genllvm.gcpolicy.malloc(targetvar, type_, size, atomic, self.word, self.uword).split('\n'):
+            self.indent(s)
 
     def getelementptr(self, targetvar, type, typevar, *indices):
         word = self.word

Added: pypy/dist/pypy/translator/llvm/exception.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/llvm/exception.py	Thu Sep  8 22:01:46 2005
@@ -0,0 +1,42 @@
+class ExceptionPolicy:
+    def __init__(self):
+        raise Exception, 'ExceptionPolicy should not be used directly'
+
+    def llc_options(self):
+        return ''
+
+    def new(exceptionpolicy=None):  #factory
+        if exceptionpolicy is None or exceptionpolicy == 'cpython':
+            from pypy.translator.llvm.exception import CPythonExceptionPolicy
+            exceptionpolicy = CPythonExceptionPolicy()
+        elif exceptionpolicy == 'fast':
+            from pypy.translator.llvm.exception import FastExceptionPolicy
+            exceptionpolicy = FastExceptionPolicy()
+        elif exceptionpolicy == 'none':
+            from pypy.translator.llvm.exception import NoneExceptionPolicy
+            exceptionpolicy = NoneExceptionPolicy()
+        else:
+            raise Exception, 'unknown exceptionpolicy: ' + str(exceptionpolicy)
+        return exceptionpolicy
+    new = staticmethod(new)
+
+
+class NoneExceptionPolicy(ExceptionPolicy):
+    def __init__(self):
+        pass
+
+
+class CPythonExceptionPolicy(ExceptionPolicy):  #uses issubclass()
+    def __init__(self):
+        pass
+
+    def llc_options(self):
+        return '-enable-correct-eh-support'
+
+
+class FastExceptionPolicy(ExceptionPolicy):    #uses only 'direct' exception class comparision
+    def __init__(self):
+        pass
+
+    def llc_options(self):
+        return '-enable-correct-eh-support'

Modified: pypy/dist/pypy/translator/llvm/gc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/gc.py	(original)
+++ pypy/dist/pypy/translator/llvm/gc.py	Thu Sep  8 22:01:46 2005
@@ -5,20 +5,14 @@
     def gc_libraries(self):
         return []
 
-    def llvm_code(self):
-        return '''
-internal fastcc sbyte* %gc_malloc(uint %n) {
-    %nn  = cast uint %n to uint
-    %ptr = malloc sbyte, uint %nn
-    ret sbyte* %ptr
-}
-
-internal fastcc sbyte* %gc_malloc_atomic(uint %n) {
-    %nn  = cast uint %n to uint
-    %ptr = malloc sbyte, uint %nn
-    ret sbyte* %ptr
-}
-'''
+    def declarations(self):
+        return ''
+
+    def malloc(self, targetvar, type_, size, is_atomic, word, uword):
+        s = str(size)
+        if s == '0':
+            return '%(targetvar)s = cast %(type_)s* null to %(type_)s* ;was malloc 0 bytes' % locals()
+        return '%(targetvar)s = malloc %(type_)s, uint %(s)s' % locals()
 
     def pyrex_code(self):
         return ''
@@ -50,27 +44,31 @@
 
 class BoehmGcPolicy(GcPolicy):
     def __init__(self):
-        pass
+        self.n_malloced = 0
 
     def gc_libraries(self):
         return ['gc'] # xxx on windows?
 
-    def llvm_code(self):
+    def declarations(self):
         return '''
 declare ccc sbyte* %GC_malloc(uint)
 declare ccc sbyte* %GC_malloc_atomic(uint)
-
-internal fastcc sbyte* %gc_malloc(uint %n) {
-    %ptr = call ccc sbyte* %GC_malloc(uint %n)
-    ret sbyte* %ptr
-}
-
-internal fastcc sbyte* %gc_malloc_atomic(uint %n) {
-    %ptr = call ccc sbyte* %GC_malloc_atomic(uint %n)
-    ret sbyte* %ptr
-}
 '''
 
+    def malloc(self, targetvar, type_, size, is_atomic, word, uword):
+        s = str(size)
+        if s == '0':
+            return '%(targetvar)s = cast %(type_)s* null to %(type_)s* ;was malloc 0 bytes' % locals()
+        self.n_malloced += 1
+        cnt = '.%d' % self.n_malloced
+        atomic = is_atomic and '_atomic' or ''
+        return '''
+%%malloc.Size%(cnt)s  = getelementptr %(type_)s* null, %(uword)s %(s)s
+%%malloc.SizeU%(cnt)s = cast %(type_)s* %%malloc.Size%(cnt)s to %(uword)s
+%%malloc.Ptr%(cnt)s   = call ccc sbyte* %%GC_malloc%(atomic)s(%(uword)s %%malloc.SizeU%(cnt)s)
+%(targetvar)s = cast sbyte* %%malloc.Ptr%(cnt)s to %(type_)s*
+        ''' % locals()
+
     def pyrex_code(self):
         return '''
 cdef extern int GC_get_heap_size()

Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py	Thu Sep  8 22:01:46 2005
@@ -21,6 +21,7 @@
 from pypy.translator.llvm.structnode import StructNode
 from pypy.translator.llvm.externs2ll import post_setup_externs, generate_llfile
 from pypy.translator.llvm.gc import GcPolicy
+from pypy.translator.llvm.exception import ExceptionPolicy
 
 from pypy.translator.translator import Translator
 
@@ -31,13 +32,14 @@
 
 class GenLLVM(object):
 
-    def __init__(self, translator, gcpolicy=None, debug=True):
+    def __init__(self, translator, gcpolicy=None, exceptionpolicy=None, debug=True):
     
         # reset counters
         LLVMNode.nodename_count = {}    
         self.db = Database(translator)
         self.translator = translator
         self.gcpolicy = gcpolicy
+        self.exceptionpolicy = exceptionpolicy
         translator.checkgraphs()
         extfuncnode.ExternalFuncNode.used_external_functions = {}
 
@@ -146,7 +148,7 @@
             function_count[func.func_name] = 1
         filename = udir.join(func.func_name + postfix).new(ext='.ll')
         f = open(str(filename),'w')
-        codewriter = CodeWriter(f, self.db.get_machine_word(), self.db.get_machine_uword())
+        codewriter = CodeWriter(f, self)
         comment = codewriter.comment
         nl = codewriter.newline
 
@@ -174,7 +176,7 @@
         self._checkpoint('write global constants')
 
         nl(); comment("Function Prototypes") ; nl()
-        for extdecl in extdeclarations.split('\n'):
+        for extdecl in (extdeclarations+self.gcpolicy.declarations()).split('\n'):
             codewriter.append(extdecl)
         self._checkpoint('write function prototypes')
 
@@ -185,8 +187,6 @@
         nl(); comment("Function Implementation") 
         codewriter.startimpl()
         
-        codewriter.append(self.gcpolicy.llvm_code())
-
         for typ_decl in self.db.getnodes():
             typ_decl.writeimpl(codewriter)
         self._checkpoint('write implementations')
@@ -277,8 +277,8 @@
     def _debug_prototype(self, codewriter):
         codewriter.append("declare int %printf(sbyte*, ...)")
 
-def genllvm(translator, gcpolicy=None, log_source=False, **kwds):
-    gen = GenLLVM(translator, GcPolicy.new(gcpolicy))
+def genllvm(translator, gcpolicy=None, exceptionpolicy=None, log_source=False, **kwds):
+    gen = GenLLVM(translator, GcPolicy.new(gcpolicy), ExceptionPolicy.new(exceptionpolicy))
     filename = gen.gen_llvm_source()
     if log_source:
         log.genllvm(open(filename).read())

Modified: pypy/dist/pypy/translator/llvm/module/extfunction.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/module/extfunction.py	(original)
+++ pypy/dist/pypy/translator/llvm/module/extfunction.py	Thu Sep  8 22:01:46 2005
@@ -1,13 +1,7 @@
-extdeclarations =  """;rpython stuff
-
-;gc-type dependent mallocs
-declare fastcc sbyte* %gc_malloc(uint)
-declare fastcc sbyte* %gc_malloc_atomic(uint)
-
-;exception handling globals
+extdeclarations =  '''
 %last_exception_type  = global %RPYTHON_EXCEPTION_VTABLE* null
 %last_exception_value = global %RPYTHON_EXCEPTION* null
-"""
+'''
 
 extfunctions = {}   #dependencies, llvm-code
 



More information about the Pypy-commit mailing list