view python/codegen.py @ 294:e89cca5779b0

Merge
author Windel Bouwman
date Thu, 28 Nov 2013 20:39:56 +0100
parents 534b94b40aa8
children
line wrap: on
line source

import ir
from target import Target
from ppci import CompilerError
import transform
import canon
import registerallocator


class CodeGenerator:
    """ Generic code generator """
    def __init__(self, target):
        # TODO: schedule traces in better order.
        # This is optional!
        assert isinstance(target, Target), target
        self.target = target
        self.ins_sel = target.ins_sel
        self.ra = registerallocator.RegisterAllocator()

    def generateFunc(self, irfunc, outs):
        """ Generate code for one function into a frame """
        # Cleanup function:
        transform.removeEmptyBlocks(irfunc)

        # Create a frame for this function:
        frame = self.target.FrameClass(irfunc.name)

        # Canonicalize the intermediate language:
        canon.make(irfunc, frame)
        self.ins_sel.munchFunction(irfunc, frame)
        
        # Do register allocation:
        self.ra.allocFrame(frame)
        # TODO: Peep-hole here?

        # Add label and return and stack adjustment:
        frame.EntryExitGlue3()

        # Materialize assembly
        # Materialize the register allocated instructions into a stream of
        # real instructions.
        frame.lower_to(outs)
        return frame

    def generate(self, ircode, outs):
        assert isinstance(ircode, ir.Module)
        outs.selectSection('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(func, outs) for func in ircode.Functions]
        return self.frames