import copy import itertools import re import textwrap import unittest from . import TestCase from llvmlite import ir from llvmlite import binding as llvm from llvmlite import six int1 = ir.IntType(1) int8 = ir.IntType(8) int32 = ir.IntType(32) int64 = ir.IntType(64) flt = ir.FloatType() dbl = ir.DoubleType() class TestBase(TestCase): """ Utilities for IR tests. """ def assertInText(self, pattern, text): """Replaces whitespace sequence in `pattern` with "\s+". """ def escape(c): if not c.isalnum() and not c.isspace(): return '\\' + c return c
int main(){ int a = 1; float b = 1.0; a = a + b; b = b + a; return 0; } ''' # Cria o módulo. modulo = ir.Module('meu_modulo.bc') FLOAT = ir.FloatType() INT = ir.IntType(32) # int main() tipo_funcao = ir.FunctionType(INT, []) main = ir.Function(modulo, tipo_funcao, name="main") bloco_entrada = main.append_basic_block("entry") bloco_saida = main.append_basic_block("exit") # ==================================================================== # Trabalhando sobre o corpo da funcao builder = ir.IRBuilder(bloco_entrada) # int retorno
def resolve_expressao(self, filho, modulo): if len(filho.child) == 1: if filho.child[0].type == "var": valor_da_atribuicao = filho.child[0].value i = 0 while i < len(self.lista_ponteiros_variaveis): if str(self.lista_ponteiros_variaveis[i].name) == str( valor_da_atribuicao): valor_da_atribuicao = self.lista_ponteiros_variaveis[i] i = i + 1 varTemp = self.builder.load(valor_da_atribuicao, name='varTemp') return varTemp elif filho.child[0].type == "numero_int": varTemp = ir.Constant(ir.IntType(32), filho.child[0].value) return varTemp elif filho.child[0].type == "numero_float": varTemp = ir.Constant(ir.FloatType(), filho.child[0].value) return varTemp elif len(filho.child) == 3: filho_esquerda = filho.child[0] operador = filho.child[1] filho_direita = filho.child[2] valor_filho_esquerda = str(filho_esquerda.value) valor_filho_direita = str(filho_direita.value) if filho_direita.type == "var": i = 0 while i < len(self.lista_ponteiros_variaveis): if str(self.lista_ponteiros_variaveis[i].name ) == valor_filho_direita: filho_direita = self.lista_ponteiros_variaveis[i] i = i + 1 varTempRight = self.builder.load(filho_direita, name='varTempRight') elif filho_direita.type == "numero_int": varTempRight = ir.Constant(ir.IntType(32), int(filho_direita.value)) elif filho_direita.type == "numero_float": varTempRight = ir.Constant(ir.FloatType(), float(filho_direita.value)) if filho_esquerda.type == "var": i = 0 while i < len(self.lista_ponteiros_variaveis): if str(self.lista_ponteiros_variaveis[i].name ) == valor_filho_esquerda: filho_esquerda = self.lista_ponteiros_variaveis[i] i = i + 1 varTempLeft = self.builder.load(filho_esquerda, name='varTempLeft') elif filho_esquerda.type == "numero_int": varTempLeft = ir.Constant(ir.IntType(32), int(filho_esquerda.value)) elif filho_esquerda.type == "numero_float": varTempLeft = ir.Constant(ir.FloatType(), float(filho_esquerda.value)) if operador.type == "operador_soma": if operador.value == "+": varTempAdd = self.builder.add(varTempLeft, varTempRight, name="varTempAdd") return varTempAdd elif operador.value == "-": varTempSub = self.builder.sub(varTempLeft, varTempRight, name="varTempSub") return varTempSub else: return ir.Constant(ir.IntType(32), 0)
def type() -> ir.Type: return ir.FloatType()
from llvmlite import ir from llvmlite import binding as llvm from dumbc.ast.ast import BuiltinTypes NBITS = {ty:int(ty.name[1:]) for ty in BuiltinTypes.NUMERICAL} _BUILTIN_TY_TO_LLVM_TY = { BuiltinTypes.I8: ir.IntType(8), BuiltinTypes.U8: ir.IntType(8), BuiltinTypes.I32: ir.IntType(32), BuiltinTypes.U32: ir.IntType(32), BuiltinTypes.I64: ir.IntType(64), BuiltinTypes.I64: ir.IntType(64), BuiltinTypes.F32: ir.FloatType(), BuiltinTypes.F64: ir.DoubleType(), BuiltinTypes.BOOL: ir.IntType(1), BuiltinTypes.STR: ir.IntType(8).as_pointer(), BuiltinTypes.VOID: ir.VoidType() } def convert_to_llvm_ty(ty): # pragma: nocover """Convert internal type class to LLVM representation. Args: ty (ast.Type): Type to be converted. Returns: ir.Type: converted builtin type.
def declare_atomic_add_float32(lmod): fname = 'llvm.numba_nvvm.atomic.load.add.f32.p0f32' fnty = ir.FunctionType(ir.FloatType(), (ir.PointerType(ir.FloatType(), 0), ir.FloatType())) return cgutils.get_or_insert_function(lmod, fnty, fname)
from ctypes import CFUNCTYPE, c_int, c_float, POINTER, c_double, py_object, byref, pointer, cast from typing import List from llvmlite.ir import builder class DType(Enum): Int = 1 Float = 2 Double = 3 Complx = 4 DComplx = 5 type_map_llvm = { DType.Int: ir.IntType(32), DType.Float: ir.FloatType(), DType.Double: ir.DoubleType(), DType.Complx: ir.FloatType(), DType.DComplx: ir.DoubleType() } int_type = ir.IntType(32) float_type = ir.FloatType() double_type = ir.DoubleType() void_type = ir.VoidType() ll_ptr_float = ir.PointerType(float_type) ll_ptr_double = ir.PointerType(double_type) ll_ptr_int = ir.PointerType(int_type) map_kk_ct = { DType.Int: (c_int, ll_ptr_int),
def retorna(self, root, modulo, builder): r = self.searchVar("return") #ret = builder.load(r, name="retorna", align=4) name = self.ponteirosFunc[-1].name start = self.ponteirosFunc[-1].append_basic_block("start" + name) builder.branch(start) builder.position_at_end(start) #stop = self.ponteirosFunc[-1].append_basic_block("end"+name) express = root.child[0].child[0] if len(express.child) == 1: aux = leaf(express.child[0]) if str(aux) != "num_inteiro" and str(aux) != "num_flutuante": rightVar = self.searchVar(str(leaf(aux))) TempVarRight = builder.load(rightVar, name="rightvar") elif str(aux) == "num_inteiro": TempVarRight = ir.Constant(ir.IntType(32), int(aux.value)) elif str(aux) == "num_flutuante": TempVarRight = ir.Constant(ir.FloatType(), int(aux.value)) rets = self.searchVar("return") builder.store(TempVarRight, rets) builder.ret(builder.load(rets, name="reeet")) else: if str(express.child[0]) != "num_inteiro" and str( express.child[0]) != "num_flutuante": sideRight = self.searchVar(str(express.child[0])) tempRight = builder.load(sideRight, name='tempRight') elif str(express.child[0]) == "num_inteiro": tempRight = ir.Constant(ir.IntType(32), int(express.child[0].value)) elif str(express.child[0]) == "num_float": tempRight = ir.Constant(ir.FloatType(), float(express.child[0].value)) if str(express.child[2]) != "num_inteiro" and str( express.child[2]) != "num_flutuante": sideLeft = self.searchVar(str(express.child[2])) tempLeft = builder.load(sideLeft, name='tempLeft') elif str(express.child[2]) == "num_inteiro": tempLeft = ir.Constant(ir.IntType(32), int(express.child[2].value)) elif str(express.child[2]) == "num_float": tempLeft = ir.Constant(ir.FloatType(), float(express.child[2].value)) if str(express.child[1]) == "+": tempPlus = builder.add(tempLeft, tempRight, name="tempPlus") if str(express.child[1]) == "-": tempPlus = builder.sub(tempLeft, tempRight, name="tempPlus") rets = self.searchVar("return") builder.store(tempPlus, rets) builder.ret(builder.load(rets, name="reeet")) builder.branch(stop) builder.position_at_end(stop)
def atrib(self, root, modulo, builder, escopo): left = self.searchVar(str(root.child[0])) auxright = root.child[1].child[0] if len(auxright.child) == 1: right = leaf(auxright) if str(auxright.child[0].child[0]) == "chamada_funcao": self.expressSolution(auxright, modulo, builder, escopo, root) return if str(right) == "num_inteiro": varRight = ir.Constant(ir.IntType(32), int(right.value)) builder.store(varRight, left) elif str(right) == "num_flutuante": varRight = ir.Constant(ir.FloatType(), float(right.value)) builder.store(varRight, left) else: varRight = self.searchVar(str(right)) varTemp = builder.load(varRight, "varTemp") builder.store(varTemp, left) if len(auxright.child) == 3: if str(auxright.child[0]) != "num_inteiro" and str( auxright.child[0]) != "num_flutuante": sideRight = self.searchVar(str(auxright.child[0])) tempRight = builder.load(sideRight, name='tempRight') elif str(auxright.child[0]) == "num_inteiro": tempRight = ir.Constant(ir.IntType(32), int(auxright.child[0].value)) elif str(auxright.child[0]) == "num_float": tempRight = ir.Constant(ir.FloatType(), float(auxright.child[0].value)) if str(auxright.child[2]) != "num_inteiro" and str( auxright.child[2]) != "num_flutuante": sideLeft = self.searchVar(str(auxright.child[2])) tempLeft = builder.load(sideLeft, name='tempLeft') elif str(auxright.child[2]) == "num_inteiro": tempLeft = ir.Constant(ir.IntType(32), int(auxright.child[2].value)) elif str(auxright.child[2]) == "num_float": tempLeft = ir.Constant(ir.FloatType(), float(auxright.child[2].value)) if str(auxright.child[1]) == "+": tempPlus = builder.add(tempLeft, tempRight, name="tempPlus") builder.store(tempPlus, left) elif str(auxright.child[1]) == "-": tempPlus = builder.sub(tempRight, tempLeft, name="tempSub") builder.store(tempPlus, left) elif str(auxright.child[1]) == "*": tempPlus = builder.mul(tempRight, tempLeft, name="tempMult") builder.store(tempPlus, left) elif str(auxright.child[1]) == "/": tempPlus = builder.mul(tempRight, tempLeft, name="tempDiv") builder.store(tempPlus, left)
def _add_basic_types(self): self.env.scope.add_type("int", MetaType("int", ir.IntType(64))) self.env.scope.add_type("float", MetaType("float", ir.FloatType())) self.env.scope.add_type("void", MetaType("void", ir.VoidType())) self.env.scope.add_type("bool", MetaType("bool", ir.IntType(8)))
def ifs(self, root, modulo, builder, escopo, ret): bodytrue = root.child[1] bodyfalse = root.child[2] express = self.expressAux(root.child[0]) leftSide = express[0].child[0] leftVar = self.searchVar(str(leftSide)) TempVar = builder.load(leftVar, name="leftvar") if str(express[0].child[2]) != "num_inteiro" and str( express[0].child[2]) != "num_flutuante": rightVar = self.searchVar(str(express[0].child[2])) TempVarRight = builder.load(rightVar, name="rightvar") elif str(express[0].child[2]) == "num_inteiro": TempVarRight = ir.Constant(ir.IntType(32), int(express[0].child[2].value)) elif str(express[0].child[2]) == "num_flutuante": TempVarRight = ir.Constant(ir.FloatType(), float(express[0].child[2].value)) op = str(express[0].child[1]) if op == "=": op = "==" c = str(bodytrue.child[0]) c = c.split(" ") if c[0] == "vazio": ifs = self.ponteirosFunc[-1].append_basic_block('if') #els = self.ponteirosFunc[-1].append_basic_block('else') end = self.ponteirosFunc[-1].append_basic_block('end') ifx = builder.icmp_signed(op, TempVar, TempVarRight, name='testecond') builder.cbranch(ifx, ifs, end) builder.position_at_end(ifs) self.walkFunc(bodytrue, modulo, builder, ret, escopo) #builder.branch(end) #builder.position_at_end(els) #self.walkFunc(bodyfalse, modulo, builder, ret, escopo) builder.branch(end) builder.position_at_end(end) else: #cond = self.ponteirosFunc[-1].append_basic_block('condif') ifs = self.ponteirosFunc[-1].append_basic_block('if') els = self.ponteirosFunc[-1].append_basic_block('else') notifs = self.ponteirosFunc[-1].append_basic_block('ifend') ifx = builder.icmp_signed(op, TempVar, TempVarRight, name='testecond') builder.cbranch(ifx, ifs, els) builder.position_at_end(ifs) self.walkFunc(bodytrue.child[0], modulo, builder, ret, escopo) builder.branch(notifs) # builder.position_at_end(els) self.walkFunc(bodytrue.child[0], modulo, builder, ret, escopo) builder.branch(notifs) builder.position_at_end(notifs)
def visit_float(self, float_t): value = ir.Constant(ir.FloatType(), float(float_t.valtok.value[:-1])) var_addr = self.env.builder.alloca(value.type) self.env.builder.store(value, var_addr) type_name = self.env.scope.get_type_name(ir.FloatType()) return MetaVariable(var_addr, type_name)
class F32Type(BaseType): base_llvm_type = ll.FloatType() size_in_bits = 32 is_floating_point = True str_repr = "f32"
def type(): return ir.FloatType()
def eval(self): if type == ir.IntType(32): i = ir.Constant(ir.IntType(32), int(self.value)) else: i = ir.Constant(ir.FloatType(), float(self.value)) return i
def addArgs(self, tipo): if str(tipo) == "inteiro": return ir.IntType(32) else: return ir.FloatType()
from llvmlite import ir import llvmlite.binding as llvm from symTable import * import sys import clang #defines the types for llvmlite integerType = ir.IntType(32) booleanType = ir.IntType(1) floatType = ir.FloatType() voidType = ir.VoidType() typeMap = { 'int': integerType, 'cint': integerType, 'float': floatType, 'void': voidType, 'bool': booleanType, 'ref int': ir.PointerType(integerType), 'ref float': ir.PointerType(floatType), 'ref bool': ir.PointerType(booleanType), 'ref cint': ir.PointerType(integerType), 'noalias ref int': ir.PointerType(integerType), 'noalias ref float': ir.PointerType(floatType), 'noalias ref bool': ir.PointerType(booleanType), 'noalias ref cint': ir.PointerType(integerType) } module = ir.Module( name='module') funcTable = SymTable() symtable = SymTable()
return to_llvm_type(data_type.base_type).as_pointer() else: return to_llvm_type.map[data_type.numpy_dtype] if ir: to_llvm_type.map = { np.dtype(np.int8): ir.IntType(8), np.dtype(np.int16): ir.IntType(16), np.dtype(np.int32): ir.IntType(32), np.dtype(np.int64): ir.IntType(64), np.dtype(np.uint8): ir.IntType(8), np.dtype(np.uint16): ir.IntType(16), np.dtype(np.uint32): ir.IntType(32), np.dtype(np.uint64): ir.IntType(64), np.dtype(np.float32): ir.FloatType(), np.dtype(np.float64): ir.DoubleType(), } def peel_off_type(dtype, type_to_peel_off): while type(dtype) is type_to_peel_off: dtype = dtype.base_type return dtype def collate_types(types): """ Takes a sequence of types and returns their "common type" e.g. (float, double, float) -> double Uses the collation rules from numpy. """
def declare_atomic_max_float32(lmod): fname = '___numba_atomic_float_max' fnty = ir.FunctionType(ir.FloatType(), (ir.PointerType(ir.FloatType()), ir.FloatType())) return cgutils.get_or_insert_function(lmod, fnty, fname)
def gen_float(self, number: float): return ir.Constant(ir.FloatType(), number)
def visit_expression(self, branch): op = branch[1]['op'] lhs, lhs_type = self.visit_value(branch[1]['lhs']) rhs, rhs_type = self.visit_value(branch[1]['rhs']) if isinstance(rhs_type, ir.FloatType) and isinstance( lhs_type, ir.FloatType): Type = ir.FloatType() if op == '+': value = self.builder.fadd(lhs, rhs) elif op == '*': value = self.builder.fmul(lhs, rhs) elif op == '/': value = self.builder.fdiv(lhs, rhs) elif op == '%': value = self.builder.frem(lhs, rhs) elif op == '-': value = self.builder.fsub(lhs, rhs) elif op == '<': value = self.builder.fcmp_ordered('<', lhs, rhs) Type = ir.IntType(1) elif op == '<=': value = self.builder.fcmp_ordered('<=', lhs, rhs) Type = ir.IntType(1) elif op == '>': value = self.builder.fcmp_ordered('>', lhs, rhs) Type = ir.IntType(1) elif op == '>=': value = self.builder.fcmp_ordered('>=', lhs, rhs) Type = ir.IntType(1) elif op == '!=': value = self.builder.fcmp_ordered('!=', lhs, rhs) Type = ir.IntType(1) elif op == '==': value = self.builder.fcmp_ordered('==', lhs, rhs) Type = ir.IntType(1) elif isinstance(rhs_type, ir.IntType) and isinstance( lhs_type, ir.IntType): Type = ir.IntType(32) if op == '+': value = self.builder.add(lhs, rhs) elif op == '*': value = self.builder.mul(lhs, rhs) elif op == '/': value = self.builder.sdiv(lhs, rhs) elif op == '%': value = self.builder.srem(lhs, rhs) elif op == '-': value = self.builder.sub(lhs, rhs) elif op == '<': value = self.builder.icmp_signed('<', lhs, rhs) Type = ir.IntType(1) elif op == '<=': value = self.builder.icmp_signed('<=', lhs, rhs) Type = ir.IntType(1) elif op == '>': value = self.builder.icmp_signed('>', lhs, rhs) Type = ir.IntType(1) elif op == '>=': value = self.builder.icmp_signed('>=', lhs, rhs) Type = ir.IntType(1) elif op == '!=': value = self.builder.icmp_signed('!=', lhs, rhs) Type = ir.IntType(1) elif op == '==': value = self.builder.icmp_signed('==', lhs, rhs) Type = ir.IntType(1) elif op == 'and': value = self.builder.and_(lhs, rhs) Type = ir.IntType(1) elif op == 'or': value = self.builder.or_(lhs, rhs) Type = ir.IntType(1) return value, Type
import ast from llvmlite import ir try: import numpy as np except ImportError: np = None # # Basic IR types # void = ir.VoidType() float32 = ir.FloatType() float64 = ir.DoubleType() int8 = ir.IntType(8) int16 = ir.IntType(16) int32 = ir.IntType(32) int64 = ir.IntType(64) # Pointers int8p = int8.as_pointer() int64p = int64.as_pointer() # Constants zero = ir.Constant(int64, 0) one = ir.Constant(int64, 1) zero32 = ir.Constant(int32, 0)
def float(): return ir.FloatType()
scanf("%d", &a); printf("%d", a); return 0; } ''' if __name__ == '__main__': modulo = ir.Module('meu_modulo.bc') # Declaração das funções que serão 'adicionadas' em tempo de vinculação. _escrevaI = ir.FunctionType(ir.VoidType(), [ir.IntType(32)]) escrevaI = ir.Function(modulo, _escrevaI, "escrevaInteiro") _escrevaF = ir.FunctionType(ir.VoidType(), [ir.FloatType()]) escrevaF = ir.Function(modulo, _escrevaF, "escrevaFlutuante") _leiaI = ir.FunctionType(ir.IntType(32), []) leiaI = ir.Function(modulo, _leiaI, "leiaInteiro") _leiaF = ir.FunctionType(ir.FloatType(), []) leiaF = ir.Function(modulo, _leiaF, "leiaFlutuante") # Declaração da função 'principal', que DEVE ser usada com o nome 'main'. main_type = ir.FunctionType(ir.IntType(32), []) main = ir.Function(modulo, main_type, "main") # Cria blocos de entrada e saída bloco_entrada = main.append_basic_block("bloco_entrada") bloco_saida = main.append_basic_block("bloco_saida")
def visit_Call(self, instr): # Add to any call that has float/double return type if instr.type in (ir.FloatType(), ir.DoubleType()): for flag in self.flags: instr.fastmath.add(flag)
def int_to_float(self, num): return self.builder.sitofp(num, ir.FloatType())
def ptx_min_f4(context, builder, sig, args): fn = cgutils.get_or_insert_function( builder.module, ir.FunctionType(ir.FloatType(), (ir.FloatType(), ir.FloatType())), '__nv_fminf') return builder.call(fn, args)
def numero_decl(self, node): return ir.Constant(ir.FloatType(), node.value)
import struct # indices into a box TYPE = 0 SIZE = 1 DATA = 2 ENV = 3 # sizes of things HASH_SIZE = 128 # all sorts of type aliases i8 = ir.IntType(8) i32 = ir.IntType(32) i64 = ir.IntType(64) f32 = ir.FloatType() f64 = ir.DoubleType() void = ir.VoidType() func = ir.FunctionType ptr = ir.PointerType arr = ir.ArrayType box = ir.context.global_context.get_identified_type('box') item = ir.context.global_context.get_identified_type('item') lpt = ir.context.global_context.get_identified_type('table') arg = ptr(box) lp = ir.LiteralStructType([ptr(i8), i32]) def vfunc(*args, var_arg=False): return func(void, args, var_arg=var_arg)
def gen_code(tree, symbol_table, sema_success): # symbol = { # "symbol_type": None, # "name": None, # "value_type": None, # "scope": None, # "parameters": [], # "dimensions": [], # "declared": True, # "inicialized": False, # "used": False # } global module global info # Define Global Variables and Functions for symbol in symbol_table: if (symbol["symbol_type"] == "variable" and symbol["scope"] == "global"): var_type = symbol["value_type"] if (var_type == "inteiro"): if (len(symbol["dimensions"]) == 0): g = ir.GlobalVariable(module, ir.IntType(32), symbol["name"]) if (len(symbol["dimensions"]) == 1): g_type = ir.ArrayType(ir.IntType(32), int(symbol["dimensions"][0])) g = ir.GlobalVariable(module, g_type, symbol["name"]) info["global_variables"].append(g) elif (var_type == "flutuante"): if (len(symbol["dimensions"]) == 0): g = ir.GlobalVariable(module, ir.FloatType(), symbol["name"]) if (len(symbol["dimensions"]) == 1): g_type = ir.ArrayType(ir.FloatType(), int(symbol["dimensions"][0])) g = ir.GlobalVariable(module, g_type, symbol["name"]) g.linkage = "common" g.align = 4 info["global_variables"].append(g) elif (symbol["symbol_type"] == "function"): if (symbol["name"] == "principal"): symbol["name"] = "main" arguments_list = [] if (len(symbol["parameters"]) > 0): for a in symbol["parameters"]: if (a["par_type"] == "inteiro"): arguments_list.append(ir.IntType(32)) else: arguments_list.append(ir.FloatType()) if (len(symbol["return"]) > 0): if (symbol["return"][0]["ret_type"] == "inteiro"): f_ret = ir.IntType(32) else: f_ret = ir.FloatType() f_func = ir.FunctionType(f_ret, arguments_list) f = ir.Function(module, f_func, name=symbol["name"]) entryBlock = f.append_basic_block('entry') builder = ir.IRBuilder(entryBlock) else: f_func = ir.FunctionType(ir.VoidType(), arguments_list) f = ir.Function(module, f_func, name=symbol["name"]) entryBlock = f.append_basic_block('entry') builder = ir.IRBuilder(entryBlock) for i in range(len(f.args)): f.args[i].name = symbol["parameters"][i]["par_name"] functions.append({ "function": f, "builder": builder, "arguments": f.args }) go_through_tree(tree, functions) file = open('module.ll', 'w') file.write(str(module)) file.close() print(module)