def codegen_proto(proto): name, args = proto[1], proto[2] double_types = [double_type] * len(args) func_type = Type.function(double_type, double_types) try: func = Function.get(the_module, name) if func.basic_block_count: raise CodegenError("redefinition of function") if len(func.args) != len(args): raise CodegenError("redefinition of function with different # args") except LLVMException: func = Function.new(the_module, func_type, name) for arg, name in zip(func.args, args): arg.name = name named_values[name] = arg return func
def codegen_proto(proto): name, args = proto[1], proto[2] double_types = [double_type] * len(args) func_type = Type.function(double_type, double_types) try: func = Function.get(the_module, name) if func.basic_block_count: raise CodegenError("redefinition of function") if len(func.args) != len(args): raise CodegenError( "redefinition of function with different # args") except LLVMException: func = Function.new(the_module, func_type, name) for arg, name in zip(func.args, args): arg.name = name named_values[name] = arg return func
def codegen_expr(builder, expr): kind = expr[0] if kind == "number": number = expr[1] return Constant.real(double_type, number) elif kind == "variable": name = expr[1] try: return named_values[name] except KeyError: raise CodegenError("unknown variable name") elif kind == "binary": op, lhs, rhs = expr[1], expr[2], expr[3] lhs_val = codegen_expr(builder, lhs) rhs_val = codegen_expr(builder, rhs) if op == "+": return builder.add(lhs_val, rhs_val, "addtmp") elif op == "-": return builder.sub(lhs_val, rhs_val, "subtmp") elif op == "*": return builder.mul(lhs_val, rhs_val, "multmp") elif op == "<": i = builder.fcmp(FCMP_ULT, lhs_val, rhs_val, "cmptmp") return builder.uitofp(i, "booltmp") else: raise CodegenError("invalid binary operator") elif kind == "call": name, args = expr[1], expr[2] try: callee = Function.get(the_module, name) except LLVMException: raise CodegenError("unknown function referenced") if len(callee.args) != len(args): raise CodegenError("incorrect # arguments passed") arg_vals = [] for arg in args: arg_val = codegen_expr(builder, arg) arg_vals.append(arg_val) return builder.call(callee, arg_vals, "calltmp")
def codegen_expr(builder, expr): kind = expr[0] if kind == 'number': number = expr[1] return Constant.real(double_type, number) elif kind == 'variable': name = expr[1] try: return named_values[name] except KeyError: raise CodegenError("unknown variable name") elif kind == 'binary': op, lhs, rhs = expr[1], expr[2], expr[3] lhs_val = codegen_expr(builder, lhs) rhs_val = codegen_expr(builder, rhs) if op == '+': return builder.add(lhs_val, rhs_val, 'addtmp') elif op == '-': return builder.sub(lhs_val, rhs_val, 'subtmp') elif op == '*': return builder.mul(lhs_val, rhs_val, 'multmp') elif op == '<': i = builder.fcmp(FCMP_ULT, lhs_val, rhs_val, 'cmptmp') return builder.uitofp(i, 'booltmp') else: raise CodegenError("invalid binary operator") elif kind == 'call': name, args = expr[1], expr[2] try: callee = Function.get(the_module, name) except LLVMException: raise CodegenError("unknown function referenced") if len(callee.args) != len(args): raise CodegenError("incorrect # arguments passed") arg_vals = [] for arg in args: arg_val = codegen_expr(builder, arg) arg_vals.append(arg_val) return builder.call(callee, arg_vals, 'calltmp')
def test_objcache(self): # Testing module aliasing m1 = Module.new('a') t = Type.int() ft = Type.function(t, [t]) f1 = m1.add_function(ft, "func") m2 = f1.module self.assert_(m1 is m2) # Testing global vairable aliasing 1 gv1 = GlobalVariable.new(m1, t, "gv") gv2 = GlobalVariable.get(m1, "gv") self.assert_(gv1 is gv2) # Testing global vairable aliasing 2 gv3 = m1.global_variables[0] self.assert_(gv1 is gv3) # Testing global vairable aliasing 3 gv2 = None gv3 = None gv1.delete() gv4 = GlobalVariable.new(m1, t, "gv") self.assert_(gv1 is not gv4) # Testing function aliasing 1 b1 = f1.append_basic_block('entry') f2 = b1.function self.assert_(f1 is f2) # Testing function aliasing 2 f3 = m1.get_function_named("func") self.assert_(f1 is f3) # Testing function aliasing 3 f4 = Function.get_or_insert(m1, ft, "func") self.assert_(f1 is f4) # Testing function aliasing 4 f5 = Function.get(m1, "func") self.assert_(f1 is f5) # Testing function aliasing 5 f6 = m1.get_or_insert_function(ft, "func") self.assert_(f1 is f6) # Testing function aliasing 6 f7 = m1.functions[0] self.assert_(f1 is f7) # Testing argument aliasing a1 = f1.args[0] a2 = f1.args[0] self.assert_(a1 is a2) # Testing basic block aliasing 1 b2 = f1.basic_blocks[0] self.assert_(b1 is b2) # Testing basic block aliasing 2 b3 = f1.get_entry_basic_block() self.assert_(b1 is b3) # Testing basic block aliasing 3 b31 = f1.entry_basic_block self.assert_(b1 is b31) # Testing basic block aliasing 4 bldr = Builder.new(b1) b4 = bldr.basic_block self.assert_(b1 is b4) # Testing basic block aliasing 5 i1 = bldr.ret_void() b5 = i1.basic_block self.assert_(b1 is b5) # Testing instruction aliasing 1 i2 = b5.instructions[0] self.assert_(i1 is i2) # phi node phi = bldr.phi(t) phi.add_incoming(f1.args[0], b1) v2 = phi.get_incoming_value(0) b6 = phi.get_incoming_block(0) # Testing PHI / basic block aliasing 5 self.assert_(b1 is b6) # Testing PHI / value aliasing self.assert_(f1.args[0] is v2)
def test_objcache(self): # Testing module aliasing m1 = Module.new("a") t = Type.int() ft = Type.function(t, [t]) f1 = m1.add_function(ft, "func") m2 = f1.module self.assert_(m1 is m2) # Testing global vairable aliasing 1 gv1 = GlobalVariable.new(m1, t, "gv") gv2 = GlobalVariable.get(m1, "gv") self.assert_(gv1 is gv2) # Testing global vairable aliasing 2 gv3 = m1.global_variables[0] self.assert_(gv1 is gv3) # Testing global vairable aliasing 3 gv2 = None gv3 = None gv1.delete() gv4 = GlobalVariable.new(m1, t, "gv") self.assert_(gv1 is not gv4) # Testing function aliasing 1 b1 = f1.append_basic_block("entry") f2 = b1.function self.assert_(f1 is f2) # Testing function aliasing 2 f3 = m1.get_function_named("func") self.assert_(f1 is f3) # Testing function aliasing 3 f4 = Function.get_or_insert(m1, ft, "func") self.assert_(f1 is f4) # Testing function aliasing 4 f5 = Function.get(m1, "func") self.assert_(f1 is f5) # Testing function aliasing 5 f6 = m1.get_or_insert_function(ft, "func") self.assert_(f1 is f6) # Testing function aliasing 6 f7 = m1.functions[0] self.assert_(f1 is f7) # Testing argument aliasing a1 = f1.args[0] a2 = f1.args[0] self.assert_(a1 is a2) # Testing basic block aliasing 1 b2 = f1.basic_blocks[0] self.assert_(b1 is b2) # Testing basic block aliasing 2 b3 = f1.entry_basic_block self.assert_(b1 is b3) # Testing basic block aliasing 3 b31 = f1.entry_basic_block self.assert_(b1 is b31) # Testing basic block aliasing 4 bldr = Builder.new(b1) b4 = bldr.basic_block self.assert_(b1 is b4) # Testing basic block aliasing 5 i1 = bldr.ret_void() b5 = i1.basic_block self.assert_(b1 is b5) # Testing instruction aliasing 1 i2 = b5.instructions[0] self.assert_(i1 is i2) # phi node phi = bldr.phi(t) phi.add_incoming(f1.args[0], b1) v2 = phi.get_incoming_value(0) b6 = phi.get_incoming_block(0) # Testing PHI / basic block aliasing 5 self.assert_(b1 is b6) # Testing PHI / value aliasing self.assert_(f1.args[0] is v2)