Ejemplo n.º 1
0
def insert_pointer(module: ir.Module,
                   scope_stack: list,
                   builder: ir.IRBuilder,
                   type_list: list,
                   val_name: tuple,
                   val_value=None):
    val_type = type_map[type_list[-1]]
    for pointer in val_name[1]:
        if pointer == '*':
            val_type = val_type.as_pointer()
    if builder is None:
        val = ir.GlobalVariable(module, val_type,
                                module.get_unique_name(val_name[2][1]))
        if val_value:
            val.initializer = val_value
    else:
        val = builder.alloca(val_type,
                             name=module.get_unique_name(val_name[2][1]))
        if val_value:
            opt_store(builder, val_value, val)
    scope_stack[-1][val_name[2][1]] = {
        'type':
        'struct_ptr' if isinstance(type_map[type_list[-1]],
                                   ir.IdentifiedStructType) else 'val_ptr',
        'val_type':
        type_list[-1],
        'value':
        val
    }
    return val
Ejemplo n.º 2
0
    def compile(self, module: ll.Module, builder: ll.IRBuilder):
        inputs = []

        for i in range(self.num_inputs):
            path = self.get_pin(f'in{i}')
            inputs.append(module.get_global(path))

        output = module.get_global(self.get_pin('out'))

        output_v = ll.Constant(INT_TYPE, 0)

        if self.kind == 'and':
            output_v = builder.not_(output_v)

        for inp in inputs:
            v = builder.load(inp)
            if self.kind == 'and':
                output_v = builder.and_(output_v, v)
            elif self.kind == 'or':
                output_v = builder.or_(output_v, v)
            elif self.kind == 'xor':
                output_v = builder.xor(output_v, v)

        if self.negated:
            output_v = builder.not_(output_v)

        builder.store(output_v, output)
Ejemplo n.º 3
0
    def compile(self, module: ll.Module, builder: ll.IRBuilder):
        pin_in = self.get_pin('in')
        pin_out = self.get_pin('out')

        pin_in = module.get_global(pin_in)
        pin_out = module.get_global(pin_out)

        v = builder.load(pin_in)
        v = builder.not_(v)
        builder.store(v, pin_out)
Ejemplo n.º 4
0
    def _get_ll_pointer_type(self, target_data, context=None):
        """
        Convert this type object to an LLVM type.
        """
        from llvmlite.ir import Module, GlobalVariable
        from llvmlite.binding import parse_assembly

        if context is None:
            m = Module()
        else:
            m = Module(context=context)
        foo = GlobalVariable(m, self, name="foo")
        with parse_assembly(str(m)) as llmod:
            return llmod.get_global_variable(foo.name).type
Ejemplo n.º 5
0
    def __init__(self):
        # Perform the basic LLVM initialization.  You need the following parts:
        #
        #    1.  A top-level Module object
        #    2.  A Function instance in which to insert code
        #    3.  A Builder instance to generate instructions
        #
        # Note: For project 5, we don't have any user-defined
        # functions so we're just going to emit all LLVM code into a top
        # level function void main() { ... }.   This will get changed later.

        self.module = Module('module')
        self.function = Function(self.module,
                                 FunctionType(void_type, []),
                                 name='main')

        self.block = self.function.append_basic_block('entry')
        self.builder = IRBuilder(self.block)

        # Dictionary that holds all of the global variable/function declarations.
        # Any declaration in the Gone source code is going to get an entry here
        self.vars = {}

        # Dictionary that holds all of the temporary registers created in
        # the intermediate code.
        self.temps = {}

        # Initialize the runtime library functions (see below)
        self.declare_runtime_library()
Ejemplo n.º 6
0
def Codegen(ast: ProgramNode, printIR: bool = True):
    """Genera l'LLVM IR dall'AST in input. 

    Args:
        ast: L'albero di sintassi astratto.
        printIR (bool): Un boolean che indica se fare un print dell'IR generato (default `False`)

    Returns:
        L'IR generato sotto forma di `str`

    Raises:
        StdlibNotFoundError: Se la standard lib non puo' essere trovata
    """

    llvm.initialize()
    llvm.initialize_native_target()
    llvm.initialize_native_asmprinter()

    # Decide l'estensione della stdlib
    ext = None
    if platform.system() == 'Windows':
        ext = 'dll'
    elif platform.system() == 'Darwin':
        ext = 'dylib'
    elif platform.system() == 'Linux':
        ext = 'so'

    path = pathlib.Path(__file__).parent.absolute()
    try:
        llvm.load_library_permanently(
            str(path) + "/../../bin/tiny_hi_core.{}".format(ext))
    except Exception:
        print("StdlibNotFoundError: Cannot find the standard library (tiny_hi_core.{})".format(ext))
        return (None, None)

    module = Module()
    builder = IRBuilder()
    context = Context(module)

    entry = None

    llmod = None

    try:
        entry = ast.entry_point()
        ast.codegen(builder, context)

        strmod = str(module)

        if printIR:
            print(strmod)

        llmod = llvm.parse_assembly(strmod)

    except Exception as e:
        print("Codegen Failed")
        print("{}: {}".format(type(e).__name__, e))
    finally:
        return (llmod, entry)
Ejemplo n.º 7
0
def insert_array(module: ir.Module,
                 scope_stack: list,
                 builder: ir.IRBuilder,
                 type: list,
                 num,
                 val_name: tuple,
                 val_value=None):
    array_type = ir.ArrayType(type_map[type[-1]], num.constant)
    if builder is None:
        val = ir.GlobalVariable(module, array_type,
                                module.get_unique_name(val_name[1]))
        if val_value:
            val.initializer = val_value
    else:
        val = builder.alloca(array_type,
                             name=module.get_unique_name(val_name[1]))
        # if val_value:
        #     opt_store(builder, val_value, val)
    scope_stack[-1][val_name[1]] = {'type': 'array', 'value': val}
    return val
Ejemplo n.º 8
0
 def compile(self, module: ll.Module, builder: ll.IRBuilder):
     for cname in self._toposort():
         cdesc = self.children[cname]
         cdesc.compile(module, builder)
         for pin1 in self._conns.get(cname, dict()):
             for desc2, pin2 in self._conns[cname][pin1]:
                 p1 = self.get_desc(cname).get_pin(pin1)
                 p2 = self.get_desc(desc2).get_pin(pin2)
                 p1 = module.get_global(p1)
                 p2 = module.get_global(p2)
                 v = builder.load(p1)
                 builder.store(v, p2)
Ejemplo n.º 9
0
    def __init__(self):
        self.module = Module('hello')
        self._print_int = Function(self.module,
                                   FunctionType(void_type, [int_type]),
                                   name='_print_int')

        self.function = Function(self.module,
                                 FunctionType(int_type, []),
                                 name='main')
        self.block = self.function.append_basic_block('entry')
        self.builder = IRBuilder(self.block)

        self.stack = []
        self.vars = {}
Ejemplo n.º 10
0
    def __init__(self):
        # Perform the basic LLVM initialization.  You need the following parts:
        #
        #    1.  A top-level Module object
        #    2.  A dictionary of global declarations
        #    3.  Initialization of runtime functions (for printing)
        #
        self.module = Module('module')

        # Dictionary that holds all of the global variable/function declarations.
        # Any declaration in the Wabbit source code is going to get an entry here
        self.globals = {}

        # Initialize the runtime library functions (see below)
        self.declare_runtime_library()
Ejemplo n.º 11
0
    def __init__(self):
        # Perform the basic LLVM initialization.  You need the following parts:
        #
        #    1.  A top-level Module object
        #    2.  A Function instance in which to insert code
        #    3.  A Builder instance to generate instructions
        #
        # Note: For project 5, we don't have any user-defined
        # functions so we're just going to emit all LLVM code into a top
        # level function void main() { ... }.   This will get changed later.

        self.module = Module('module')
        self.globals = {}

        # Initialize the runtime library functions (see below)
        self.declare_runtime_library()
Ejemplo n.º 12
0
    def __init__(self, symbol_table) -> None:
        # Module is an LLVM construct that contains functions and global variables.
        # In many ways, it is the top-level structure that the LLVM IR uses to contain
        # code. It will own the memory for all of the IR that we generate, which is why
        # the codegen() method returns a raw Value*, rather than a unique_ptr<Value>.
        self.module = Module()

        # The Builder object is a helper object that makes it easy to generate LLVM
        # instructions. Instances of the IRBuilder class template keep track of the
        # current place to insert instructions and has methods to create new instructions.
        self.builder = None
        self.symbol_table = symbol_table
        self.expr_counter = 0
        self.str_counter = 0
        self.bool_counter = 0
        self.printf_counter = 0
        self.func_name = ""
        self.GLOBAL_MEMORY = {}
Ejemplo n.º 13
0
def insert_string(module: ir.Module,
                  scope_stack: list,
                  builder: ir.IRBuilder,
                  raw_data: str,
                  prt=False):
    try:
        global_string = scope_stack[0][raw_data]
    except KeyError:
        data = eval('%s' % raw_data)
        data += '\00'
        data = data.encode()
        str_type = ir.ArrayType(char_type, len(data))
        const_string = ir.Constant(str_type, bytearray(data))
        global_string = ir.GlobalVariable(module, str_type,
                                          module.get_unique_name(raw_data))
        global_string.initializer = const_string
        scope_stack[0][raw_data] = global_string
    if prt:
        return builder.gep(global_string, [int_type(0), int_type(0)], True)
    else:
        return global_string
Ejemplo n.º 14
0
# hellollvm.py

from llvmlite.ir import (
    Module, Function, FunctionType, IntType,
    Constant, IRBuilder
    )

mod = Module('hello')
hello_func = Function(mod, 
                      FunctionType(IntType(32), []), 
                      name='hello')
block = hello_func.append_basic_block('entry')
builder = IRBuilder(block)
builder.ret(Constant(IntType(32), 37))

# A user-defined function
from llvmlite.ir import DoubleType

ty_double = DoubleType()
dsquared_func = Function(mod, 
                         FunctionType(ty_double, [ty_double, ty_double]), 
                         name='dsquared')
block = dsquared_func.append_basic_block('entry')
builder = IRBuilder(block)

# Get the function args
x, y = dsquared_func.args

# Compute temporary values for x*x and y*y
xsquared = builder.fmul(x, x)
ysquared = builder.fmul(y, y)
Ejemplo n.º 15
0
# cmp.py
#
# A sample of executing an integer < in LLVM

from llvmlite.ir import (Module, Function, FunctionType, IntType, IRBuilder)

mod = Module('example')

# Define a function:
#
#    func lessthan(x int, y int) bool {
#         return x < y;
#    }
#
# Note: The result of boolean operations is a 1-bit integer

func = Function(mod,
                FunctionType(IntType(1),
                             [IntType(32), IntType(32)]),
                name='lessthan')

block = func.append_basic_block("entry")
builder = IRBuilder(block)

# The icmp_signed() instruction is used for all comparisons on
# integers.  For floating point, use fcmp_ordered().  The compare operation
# takes an operator expressed as a string such as '<', '>', '==',
# etc.

result = builder.icmp_signed('<', func.args[0], func.args[1])
builder.ret(result)
Ejemplo n.º 16
0
 def __init__(self):
     self.module = Module('module')
     self.globals = {}
     self.blocks = {}
     self.declare_runtime_library()