Example #1
0
 def generate_call_code(self, result_arg_list):
     return "call {output_precision} @{function_name}({arg_list})".format(
         output_precision=llvm_ir_format(self.output_precision),
         function_name=self.function_name,
         arg_list=", ".join([
             "%s %s" % (llvm_ir_format(var_arg.precision), var_arg.get())
             for var_arg in result_arg_list
         ]))
 def get_function_common(self, fct_type, common_keyword, final=True, language=LLVM_IR_Code, arg_list=None):
     """ :param common_keyword: llvm-ir specialization function declaration or definition """
     if arg_list:
         arg_format_list = ", ".join("%s %s" % (llvm_ir_format(inp.get_precision()), self.get_llvm_varname(inp.get_tag())) for inp in arg_list)
     else:
         arg_format_list = ", ".join(input_format.get_name(language=language) for input_format in fct_type.arg_list_precision)
     function_name = fct_type.name
     output_format = fct_type.output_format
     return "{keyword} {out_format} @{name}({arg_list})\n".format(
         keyword=common_keyword,
         out_format=llvm_ir_format(output_format),
         name=function_name,
         arg_list=arg_format_list)
Example #3
0
 def get_function_declaration(self,
                              function_name,
                              output_format,
                              arg_list,
                              final=True,
                              language=C_Code):
     """ generate function declaration code """
     arg_format_list = ", ".join("%s %s" %
                                 (llvm_ir_format(inp.get_precision()),
                                  self.get_llvm_varname(inp.get_tag()))
                                 for inp in arg_list)
     return "define %s @%s(%s)\n" % (llvm_ir_format(output_format),
                                     function_name, arg_format_list)
Example #4
0
def llvm_not_function(precision):
    """ build a code generation operator for LogicalNot operation (unary)
        from the binary operations supported in LLVM-IR """
    op = "xor"
    one = 1
    return LLVMIrTemplateOperator("{op} {precision} {one}, {{}}".format(
        op=op, one=one, precision=llvm_ir_format(precision)),
                                  arity=1)
 def generate_assignation(self, result_var, expression_code, final=True, precision=None):
     """ generate code for assignation of value <expression_code> to 
         variable <result_var> """
     final_symbol = ";\n" if final else ""
     format_symbol = llvm_ir_format(precision) if precision else ""
     return "{result} = {format_str} {expr}{final}".format(
         result=result_var,
         expr=expression_code,
         format_str=format_symbol,
         final=final_symbol
     )
Example #6
0
def llvm_negation_function(precision):
    """ build code generation operator for Negation operation.
        As LLVM-IR does not have neg we must build a subtraction from 0 """
    op = "fsub" if ML_FP_Format.is_fp_format(precision) else "sub"
    zero = "0.0" if ML_FP_Format.is_fp_format(precision) else "0"
    return LLVMIrTemplateOperator("{op} {precision} {zero}, {{}}".format(
        zero=zero,
        op=op,
        precision=llvm_ir_format(precision),
    ),
                                  arity=1)
    def generate_expr(self, code_object, optree, folded=True, result_var=None, initial=False, __exact=None, language=None, strip_outer_parenthesis=False, force_variable_storing=False, next_block=None):
        """ code generation function """

        # search if <optree> has already been processed
        if self.has_memoization(optree):
            return self.get_memoization(optree)

        result = None
        # implementation generation
        if isinstance(optree, CodeVariable):
            # adding LLVM variable "%" prefix
            if optree.name[0] != "%":
                optree.name = "%" + optree.name
            result = optree

        elif isinstance(optree, Variable):
            result = CodeVariable("%" + optree.get_tag(), optree.get_precision())

        elif isinstance(optree, Constant):
            precision = optree.get_precision()
            result = generate_Constant_expr(optree)
            #result = CodeExpression(precision.get_gappa_cst(optree.get_value()), precision)

        elif isinstance(optree, BasicBlock):
            bb_label = self.get_bb_label(code_object, optree)
            code_object << (bb_label + ":")
            code_object.open_level(header="")
            for op in optree.inputs:
                self.generate_expr(code_object, op, folded=folded,
                    initial=True, language=language)
            code_object.close_level(footer="", cr="")
            return None

        elif isinstance(optree, ConditionalBranch):
            cond = optree.get_input(0)
            if_bb = optree.get_input(1)
            else_bb = optree.get_input(2)
            if_label = self.get_bb_label(code_object, if_bb)
            else_label = self.get_bb_label(code_object, else_bb)

            cond_code = self.generate_expr(
                code_object, cond, folded=folded, language=language)

            code_object << "br i1 {cond} , label %{if_label}, label %{else_label}\n".format(
                cond=cond_code.get(),
                if_label=if_label,
                else_label=else_label
            )
            # generating destination bb
            # self.generate_expr(code_object, if_bb, folded=folded, language=language)
            # self.generate_expr(code_object, else_bb, folded=folded, language=language)
            return None

        elif isinstance(optree, UnconditionalBranch):
            dest_bb = optree.get_input(0)
            code_object << "br label %{}\n".format(self.get_bb_label(code_object, dest_bb))
            # generating destination bb
            # self.generate_expr(code_object, dest_bb, folded=folded, language=language)
            return None

        elif isinstance(optree, BasicBlockList):
            for bb in optree.inputs:
                self.generate_expr(code_object, bb, folded=folded, language=language)
            return None

        elif isinstance(optree, Statement):
            Log.report(Log.Error, "Statement are not supported in LLVM-IR codegen"
                "They must be translated to BB (e.g. through gen_basic_block pass)"
                "faulty node: {}", optree)

        elif isinstance(optree, ConditionBlock):
            Log.report(Log.Error, "ConditionBlock are not supported in LLVM-IR codegen"
                "They must be translated to BB (e.g. through gen_basic_block pass)"
                "faulty node: {}", optree)

        elif isinstance(optree, Loop):
            Log.report(Log.Error, "Loop are not supported in LLVM-IR codegen"
                "They must be translated to BB (e.g. through gen_basic_block pass)"
                "faulty node: {}", optree)

        elif isinstance(optree, PhiNode):
            output_var = optree.get_input(0)
            output_var_code = self.generate_expr(
                code_object, output_var, folded=folded, language=language)

            value_list = []
            for input_var, bb_var in zip(optree.get_inputs()[1::2], optree.get_inputs()[2::2]):
                assert isinstance(input_var, Variable)
                assert isinstance(bb_var, BasicBlock)
                input_var = self.generate_expr(
                    code_object, input_var, folded=folded, language=language
                )
                bb_label = self.get_bb_label(code_object, bb_var)
                value_list.append("[{var}, %{bb}]".format(var=input_var.get(), bb=bb_label))

            code_object << "{output_var} = phi {precision} {value_list}\n".format(
                output_var=output_var_code.get(),
                precision=llvm_ir_format(precision=output_var.get_precision()),
                value_list=(", ".join(value_list))
            )

            return None

        elif isinstance(optree, ReferenceAssign):
            output_var = optree.get_input(0)
            result_value = optree.get_input(1)

            # In LLVM it is illegal to assign a constant value, directly to a
            # variable so with insert a dummy add with 0
            if isinstance(result_value, Constant):
                cst_precision = result_value.get_precision()
                result_value = Addition(
                    result_value,
                    Constant(0, precision=cst_precision),
                    precision=cst_precision)

            # TODO/FIXME: fix single static assignation enforcement
            #output_var_code = self.generate_expr(
            #    code_object, output_var, folded=False, language=language
            #)

            result_value_code = self.generate_expr(
                code_object, result_value, folded=folded, result_var="%"+output_var.get_tag(), language=language
            )
            assert isinstance(result_value_code, CodeVariable)
            # code_object << self.generate_assignation(output_var_code.get(), result_value_code.get(), precision=output_var_code.precision)
            # debug msg generation is not supported in LLVM code genrator

            return None

        else:
            result = self.processor.generate_expr(self, code_object, optree, optree.inputs, folded = folded, result_var = result_var, language = self.language)
            # each operation is generated on a separate line

        # registering result into memoization table
        self.add_memoization(optree, result)

        # debug management
        if optree.get_debug() and not self.disable_debug:
            code_object << self.generate_debug_msg(optree, result)


        if strip_outer_parenthesis and isinstance(result, CodeExpression):
          result.strip_outer_parenthesis()
        return result
Example #8
0
 def generate_call_code(self, result_arg_list):
     return "{function_name} {output_precision} {arg_list}".format(
         output_precision=llvm_ir_format(self.output_precision),
         function_name=self.function_name,
         arg_list=", ".join([var_arg.get() for var_arg in result_arg_list]))
Example #9
0
def llvm_extract_element_function(src_precision, index_precision):
    return LLVMIrTemplateOperator(
        "extractelement {src_format} {{}},  {index_format} {{}}".format(
            src_format=llvm_ir_format(src_precision),
            index_format=llvm_ir_format(index_precision)),
        arity=1)
Example #10
0
def llvm_bitcast_function(dst_precision, src_precision):
    return LLVMIrTemplateOperator(
        "bitcast {src_format} {{}} to {dst_format}".format(
            src_format=llvm_ir_format(src_precision),
            dst_format=llvm_ir_format(dst_precision)),
        arity=1)