Mercurial > lcfOS
view python/ppci/codegen/codegen.py @ 394:988f3fb861e4
c3 code generator rewrite
author | Windel Bouwman |
---|---|
date | Thu, 22 May 2014 08:14:12 +0200 |
parents | 39bf68bf1891 |
children |
line wrap: on
line source
from .. import ir from ..irutils import Verifier from ..transform import RemoveAddZero from ..target import Target from .. import CompilerError from .canon import make as canonicalize from .registerallocator import RegisterAllocator import logging class CodeGenerator: """ Generic code generator """ def __init__(self, target): # TODO: schedule traces in better order. # This is optional! assert isinstance(target, Target), target self.logger = logging.getLogger('codegen') self.target = target self.ins_sel = target.ins_sel self.ra = RegisterAllocator() self.verifier = Verifier() def generateFunc(self, irfunc, outs): """ Generate code for one function into a frame """ self.logger.debug('Generating code for {}'.format(irfunc.name)) # Create a frame for this function: frame = self.target.FrameClass(ir.label_name(irfunc)) # Canonicalize the intermediate language: canonicalize(irfunc, frame) RemoveAddZero().run(irfunc) self.logger.debug('after canonicalize', extra={'irfunc': irfunc}) self.verifier.verify_function(irfunc) self.ins_sel.munchFunction(irfunc, frame) self.logger.debug('Selected instructions', extra={'ppci_frame': frame}) # Do register allocation: self.ra.allocFrame(frame) self.logger.debug('Registers allocated, now adding final glue') # TODO: Peep-hole here? # Add label and return and stack adjustment: frame.EntryExitGlue3() # Materialize the register allocated instructions into a stream of # real instructions. self.target.lower_frame_to_stream(frame, outs) self.logger.debug('Instructions materialized') return frame def generate(self, ircode, outs): """ Generate code into output stream """ assert isinstance(ircode, ir.Module) outs.select_section('data') for global_variable in ircode.Variables: self.target.emit_global(outs, ir.label_name(global_variable)) outs.select_section('code') # Munch program into a bunch of frames. One frame per function. # Each frame has a flat list of abstract instructions. # Generate code for all functions: self.frames = [self.generateFunc(f, outs) for f in ircode.Functions] return self.frames