Working on using InternalFunction instances from ast_translate. Fixed bug in AST modulo implementation.

This commit is contained in:
Jon Riehl 2012-10-18 16:01:32 -05:00
commit 9b1b444000
2 changed files with 38 additions and 13 deletions

View file

@ -139,7 +139,8 @@ class LLVMTranslator (BytecodeFlowVisitor):
self.control_flow_builder = ControlFlowBuilder() self.control_flow_builder = ControlFlowBuilder()
self.phi_injector = PhiInjector() self.phi_injector = PhiInjector()
def translate (self, function, llvm_type = None, env = None): def translate (self, function, llvm_type = None, llvm_function = None,
env = None):
'''Translate a function to the given LLVM function type. '''Translate a function to the given LLVM function type.
If no type is given, then assume the function is of LLVM type If no type is given, then assume the function is of LLVM type
@ -148,7 +149,10 @@ class LLVMTranslator (BytecodeFlowVisitor):
The optional env parameter allows extension of the global The optional env parameter allows extension of the global
environment.''' environment.'''
if llvm_type is None: if llvm_type is None:
llvm_type = lc.Type.function(lvoid, ()) if llvm_function is None:
llvm_type = lc.Type.function(lvoid, ())
else:
llvm_type = llvm_function.type.pointee
if env is None: if env is None:
env = {} env = {}
else: else:
@ -172,6 +176,7 @@ class LLVMTranslator (BytecodeFlowVisitor):
nargs = self.code_obj.co_argcount nargs = self.code_obj.co_argcount
self.cfg = self.control_flow_builder.visit( self.cfg = self.control_flow_builder.visit(
self.bytecode_flow_builder.visit(self.code_obj), nargs) self.bytecode_flow_builder.visit(self.code_obj), nargs)
self.llvm_function = llvm_function
flow = self.phi_injector.visit_cfg(self.cfg, nargs) flow = self.phi_injector.visit_cfg(self.cfg, nargs)
ret_val = self.visit(flow) ret_val = self.visit(flow)
del self.cfg del self.cfg
@ -185,8 +190,9 @@ class LLVMTranslator (BytecodeFlowVisitor):
def enter_flow_object (self, flow): def enter_flow_object (self, flow):
super(LLVMTranslator, self).enter_flow_object(flow) super(LLVMTranslator, self).enter_flow_object(flow)
self.llvm_function = self.llvm_module.add_function( if self.llvm_function is None:
self.llvm_type, self.target_function_name) self.llvm_function = self.llvm_module.add_function(
self.llvm_type, self.target_function_name)
self.llvm_blocks = {} self.llvm_blocks = {}
self.llvm_definitions = {} self.llvm_definitions = {}
self.pending_phis = {} self.pending_phis = {}
@ -202,7 +208,6 @@ class LLVMTranslator (BytecodeFlowVisitor):
del self.pending_phis del self.pending_phis
del self.llvm_definitions del self.llvm_definitions
del self.llvm_blocks del self.llvm_blocks
del self.llvm_function
if __debug__: print(ret_val) if __debug__: print(ret_val)
return ret_val return ret_val
@ -468,15 +473,17 @@ class LLVMTranslator (BytecodeFlowVisitor):
return ret_val return ret_val
def op_LOAD_DEREF (self, i, op, arg, *args, **kws): def op_LOAD_DEREF (self, i, op, arg, *args, **kws):
ret_val = self.globals[self.code_obj.co_freevars[arg]] name = self.code_obj.co_freevars[arg]
ret_val = self.globals[name]
if isinstance(ret_val, lc.Type) and not hasattr(ret_val, '__name__'): if isinstance(ret_val, lc.Type) and not hasattr(ret_val, '__name__'):
ret_val.__name__ = self.code_obj.co_names[arg] ret_val.__name__ = name
return [ret_val] return [ret_val]
def op_LOAD_GLOBAL (self, i, op, arg, *args, **kws): def op_LOAD_GLOBAL (self, i, op, arg, *args, **kws):
ret_val = self.globals[self.code_obj.co_names[arg]] name = self.code_obj.co_names[arg]
ret_val = self.globals[name]
if isinstance(ret_val, lc.Type) and not hasattr(ret_val, '__name__'): if isinstance(ret_val, lc.Type) and not hasattr(ret_val, '__name__'):
ret_val.__name__ = self.code_obj.co_names[arg] ret_val.__name__ = name
return [ret_val] return [ret_val]
def op_POP_BLOCK (self, i, op, arg, *args, **kws): def op_POP_BLOCK (self, i, op, arg, *args, **kws):
@ -539,7 +546,15 @@ def translate_function (func, lltype, llvm_module = None, **kws):
'''Given a function and an LLVM function type, emit LLVM code for '''Given a function and an LLVM function type, emit LLVM code for
that function using a new LLVMTranslator instance.''' that function using a new LLVMTranslator instance.'''
translator = LLVMTranslator(llvm_module) translator = LLVMTranslator(llvm_module)
ret_val = translator.translate(func, lltype, kws) ret_val = translator.translate(func, lltype, env = kws)
return ret_val
# ______________________________________________________________________
def translate_into_function (py_function, llvm_function, **kws):
translator = LLVMTranslator(llvm_function.module)
ret_val = translator.translate(py_function, llvm_function = llvm_function,
env = kws)
return ret_val return ret_val
# ______________________________________________________________________ # ______________________________________________________________________
@ -550,6 +565,13 @@ def llnumba (lltype, llvm_module = None, **kws):
return translate_function(func, lltype, llvm_module, **kws) return translate_function(func, lltype, llvm_module, **kws)
return _llnumba return _llnumba
# ______________________________________________________________________
def llnumba_into (llvm_function, **kws):
def _llnumba_into (func):
return translate_into_function(llvm_function, func, **kws)
return _llnumba_into
# ______________________________________________________________________ # ______________________________________________________________________
# Main (self-test) routine # Main (self-test) routine

View file

@ -84,8 +84,6 @@ class PhiInjector (BenignBytecodeVisitorMixin, BytecodeFlowVisitor):
def enter_block (self, block): def enter_block (self, block):
ret_val = False ret_val = False
if self.prev_blocks:
prev_block = self.prev_blocks[-1]
self.block = block self.block = block
if block == 0: if block == 0:
if self.nargs > 0: if self.nargs > 0:
@ -97,7 +95,12 @@ class PhiInjector (BenignBytecodeVisitorMixin, BytecodeFlowVisitor):
ret_val = True ret_val = True
elif 0 in self.cfg.blocks_reaching[block]: elif 0 in self.cfg.blocks_reaching[block]:
ret_val = True ret_val = True
prev_block_locals = self.blocks_locals[prev_block] prev_block_locals = None
for pred_block in self.cfg.blocks_in[block]:
if pred_block in self.prev_blocks:
prev_block_locals = self.blocks_locals[pred_block]
break
assert prev_block_locals is not None, "Internal translation error"
self.blocks_locals[block] = prev_block_locals.copy() self.blocks_locals[block] = prev_block_locals.copy()
phis_needed = self.cfg.phi_needed(block) phis_needed = self.cfg.phi_needed(block)
if phis_needed: if phis_needed: