Exemple #1
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
Exemple #2
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()
Exemple #3
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)
Exemple #4
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 = {}
Exemple #5
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()
Exemple #6
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()
Exemple #7
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 = {}
Exemple #8
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)
Exemple #9
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)
Exemple #10
0
 def __init__(self):
     self.module = Module('module')
     self.globals = {}
     self.blocks = {}
     self.declare_runtime_library()