Пример #1
0
def legalize_fixed_point_subselection(optree,
                                      input_prec_solver=default_prec_solver):
    """ Legalize a SubSignalSelection on a fixed-point node """
    sub_input = optree.get_input(0)
    inf_index = evaluate_cst_graph(optree.get_inf_index(),
                                   input_prec_solver=input_prec_solver)
    sup_index = evaluate_cst_graph(optree.get_sup_index(),
                                   input_prec_solver=input_prec_solver)
    assert not inf_index is None and not sup_index is None
    input_format = ML_StdLogicVectorFormat(
        sub_input.get_precision().get_bit_size())
    output_format = ML_StdLogicVectorFormat(sup_index - inf_index + 1)
    subselect = SubSignalSelection(TypeCast(sub_input, precision=input_format),
                                   inf_index,
                                   sup_index,
                                   precision=output_format)
    result = TypeCast(
        subselect,
        precision=optree.get_precision(),
    )
    # TypeCast may be simplified during code generation so attributes
    # may also be forwarded to previous node
    forward_attributes(optree, subselect)
    forward_attributes(optree, result)
    return result
Пример #2
0
def legalize_multi_precision_vector_element_selection(optree):
    """ legalize a VectorElementSelection @p optree on a vector of
        multi-precision elements to a single element """
    assert isinstance(optree, VectorElementSelection)
    multi_precision_vector = optree.get_input(0)
    elt_index = optree.get_input(1)
    hi_vector = multi_precision_vector.hi
    lo_vector = multi_precision_vector.lo
    limb_num = multi_precision_vector.get_precision().get_scalar_format().limb_num 
    if limb_num == 2:
        component_vectors = [hi_vector, lo_vector]
    elif limb_num == 3:
        me_vector = multi_precision_vector.me
        component_vectors = [hi_vector, me_vector, lo_vector]
    else:
        Log.report(Log.Error, "unsupported number of limbs in legalize_multi_precision_vector_element_selection for {}", optree)
    result = BuildFromComponent(
        *tuple(VectorElementSelection(vector, elt_index) for vector in component_vectors)
    )
    forward_attributes(optree, result)
    result.set_precision(optree.precision)
    return result



        
Пример #3
0
def fixed_point_position_legalizer(optree,
                                   input_prec_solver=default_prec_solver):
    """ Legalize a FixedPointPosition node to a constant """
    assert isinstance(optree, FixedPointPosition)
    fixed_input = optree.get_input(0)
    fixed_precision = input_prec_solver(fixed_input)
    if not is_fixed_point(fixed_precision):
        Log.report(
            Log.Error,
            "in fixed_point_position_legalizer: precision of {} should be fixed-point but is {}"
            .format(fixed_input, fixed_precision))

    position = optree.get_input(1).get_value()

    align = optree.get_align()

    value_computation_map = {
        FixedPointPosition.FromLSBToLSB:
        position,
        FixedPointPosition.FromMSBToLSB:
        fixed_precision.get_bit_size() - 1 - position,
        FixedPointPosition.FromPointToLSB:
        fixed_precision.get_frac_size() + position,
        FixedPointPosition.FromPointToMSB:
        fixed_precision.get_integer_size() - position
    }
    cst_value = value_computation_map[align]
    # display value
    Log.report(
        Log.LogLevel("FixedPoint"),
        "fixed-point position {tag} has been resolved to {value}".format(
            tag=optree.get_tag(), value=cst_value))
    result = Constant(cst_value, precision=ML_Integer)
    forward_attributes(optree, result)
    return result
Пример #4
0
    def legalize_operation_rec(self, optree):
        """ """
        # looking into memoization map
        if optree in self.memoization_map:
            return self.memoization_map[optree]

        # has the npde been modified ?
        arg_changed = False

        if isinstance(optree, ML_LeafNode):
            pass
        else:
            for index, op_input in enumerate(optree.get_inputs()):
                is_modified, new_node = self.legalize_operation_rec(op_input)
                if is_modified:
                    optree.set_input(index, new_node)
                    arg_changed = True

        local_changed, new_optree = self.legalize_single_operation(
            optree, self.format_solver)
        if local_changed:
            forward_attributes(optree, new_optree)
            Log.report(LOG_LEVEL_LEGALIZE, "legalized {} to {}", optree,
                       new_optree)

        self.memoization_map[optree] = local_changed, new_optree
        return (local_changed or arg_changed), new_optree
Пример #5
0
def simplify_logical_tree(node,
                          op_predicate=lambda n: isinstance(n, LogicalAnd),
                          leaf_predicate=lambda n: isinstance(n, LogicalNot),
                          result_ctor=lambda node, input_list: None):
    """ simplify a tree of operation matching the following conditions:
        - each internal node verifies op_predicate(node)
        - each leaf verifies leaf_predicate(node)

        a list is built with the leaf node and the result is built
        by calling result_ctor(<input node>, <list>) """
    def get_input_list(op):
        if leaf_predicate(op):
            # extract input of input (decapsulating LogicalNot)
            return [op]
        elif op_predicate(op):
            return get_input_list(op.get_input(0)) + get_input_list(
                op.get_input(1))
        else:
            raise NotImplementedError

    input_list = get_input_list(node)
    result = result_ctor(node, input_list)
    #result = LogicalNot(logical_or_reduce(list(map(leaf_transform, input_list))))
    forward_attributes(node, result)
    return result
Пример #6
0
 def expand_sub(self, node):
     lhs = node.get_input(0)
     rhs = node.get_input(1)
     tag = node.get_tag()
     precision = node.get_precision()
     new_node = Addition(lhs,
                         Negation(rhs, precision=rhs.precision),
                         precision=precision)
     forward_attributes(node, new_node)
     return self.expand_node(new_node)
Пример #7
0
 def reconstruct_from_transformed(self, node, transformed_node):
     """return a node at the root of a transformation chain,
         compatible with untransformed nodes """
     if isinstance(node, Constant):
         return node
     else:
         result = BuildFromComponent(*tuple(transformed_node),
                                     precision=node.precision)
         forward_attributes(node, result)
         result.set_tag(node.get_tag())
         return result
    def simplify(self, node):
        def get_node_input(index):
            # look for input into simpifield list
            # and return directly node input if simplified input is None
            return node.get_input(index)

        result = None
        if node in self.memoization_map:
            return self.memoization_map[node]
        else:
            if not is_leaf_node(node):
                for index, op in enumerate(node.inputs):
                    new_op = self.simplify(op)
                    # replacing modified inputs
                    if not new_op is None:
                        node.set_input(index, new_op)
            if is_simplifiable_to_cst(node):
                new_node = Constant(
                    sollya.inf(node.get_interval()),
                    precision=node.get_precision()
                )
                forward_attributes(node, new_node)
                result = new_node
            elif isinstance(node, Multiplication) and is_simplifiable_multiplication(node, get_node_input(0), get_node_input(1)):
                result = simplify_multiplication(node)
            elif isinstance(node, Min):
                simplified_min = is_simplifiable_min(node, get_node_input(0), get_node_input(1))
                if simplified_min:
                    result = simplified_min
            elif isinstance(node, Max):
                simplified_max = is_simplifiable_max(node, get_node_input(0), get_node_input(1))
                if simplified_max:
                    result = simplified_max
            elif isinstance(node, Comparison):
                cmp_value = is_simplifiable_cmp(node, get_node_input(0), get_node_input(1))
                if cmp_value is BooleanValue.AlwaysTrue:
                    result = generate_uniform_cst(True, node.get_precision())
                elif cmp_value is BooleanValue.AlwaysFalse:
                    result = generate_uniform_cst(False, node.get_precision())
            elif isinstance(node, Test):
                test_value = is_simplifiable_test(node, node.inputs)
                if test_value is BooleanValue.AlwaysTrue:
                    result = generate_uniform_cst(True, node.get_precision())
                elif test_value is BooleanValue.AlwaysFalse:
                    result = generate_uniform_cst(False, node.get_precision())
            elif isinstance(node, ConditionBlock):
                result = simplify_condition_block(node)
            elif isinstance(node, LogicOperation):
                result = simplify_logical_op(node)
            if not result is None:
                Log.report(LOG_VERBOSE_NUMERICAL_SIMPLIFICATION, "{} has been simplified to {}", node, result)
            self.memoization_map[node] = result
            return result
Пример #9
0
 def minmax_legalizer(optree):
     op0 = optree.get_input(0)
     op1 = optree.get_input(1)
     bool_prec = get_compatible_bool_format(optree)
     comp = Comparison(op0,
                       op1,
                       specifier=predicate,
                       precision=bool_prec,
                       tag="minmax_pred")
     # forward_stage_attributes(optree, comp)
     result = Select(comp, op0, op1, precision=optree.get_precision())
     forward_attributes(optree, result)
     return result
Пример #10
0
 def reconstruct_from_transformed(self, node, transformed_node):
     Log.report(LOG_LEVEL_EXPAND_VERBOSE, "reconstructed : {}", node)
     Log.report(LOG_LEVEL_EXPAND_VERBOSE, "from transformed: {}",
                "\n".join([str(n) for n in transformed_node]))
     if isinstance(node, Constant):
         result = node
     else:
         if len(transformed_node) == 1:
             result = transformed_node[0]
         else:
             result = BuildFromComponent(*tuple(transformed_node),
                                         precision=node.precision)
         forward_attributes(node, result)
         result.set_tag(node.get_tag())
     Log.report(LOG_LEVEL_EXPAND_VERBOSE, "  result is : {}", result)
     return result
Пример #11
0
 def expand_sub(self, node):
     lhs = node.get_input(0)
     rhs = node.get_input(1)
     tag = node.get_tag()
     precision = node.get_precision()
     # Subtraction x - y is transformed into x + (-y)
     # WARNING: if y is not expandable (e.g. scalar precision)
     #          this could stop expansion
     new_node = Addition(lhs,
                         Negation(rhs, precision=rhs.precision),
                         precision=precision)
     forward_attributes(node, new_node)
     expanded_node = self.expand_node(new_node)
     Log.report(
         LOG_LEVEL_EXPAND_VERBOSE,
         "expanding Subtraction {} into {} with expanded form {}", node,
         new_node, ", ".join(
             (op.get_str(display_precision=True, depth=None))
             for op in expanded_node))
     return expanded_node
Пример #12
0
def simplify_logical_or_not(node, leaf_transform):
    """ Simplify a tree of LogicalOr nodes, whose
        leaf are LogicalNot nodes """

    # the leaf_function transforms a leaf by extracting
    # its single input (decapsulating LogicalNot) and
    # calling leaf_transform on this input
    def leaf_function(op):
        return leaf_transform(op.get_input(0))

    result = simplify_logical_tree(
        node,
        op_predicate=(lambda op: isinstance(op, LogicalOr)),
        leaf_predicate=(lambda op: isinstance(op, LogicalNot)),
        result_ctor=lambda op, op_list: LogicalNot(
            logical_reduce(list(map(leaf_transform, op_list)),
                           LogicalAnd,
                           precision=node.get_precision()),
            precision=node.get_precision()))
    forward_attributes(node, result)
    return result
Пример #13
0
    def expand_node(self, node):
        """ return the expansion of @p node when possible
            else None """
        def wrap_expansion(node, transformed_node):
            return node if transformed_node is None else transformed_node

        if node in self.memoization_map:
            return self.memoization_map[node]
        elif isinstance(node, ExponentExtraction):
            op = wrap_expansion(node.get_input(0),
                                self.expand_node(node.get_input(0)))
            result = generate_exp_extraction(op)
            forward_attributes(node, result)
        elif isinstance(node, ExponentInsertion):
            op = wrap_expansion(node.get_input(0),
                                self.expand_node(node.get_input(0)))
            result = generate_exp_insertion(op, node.precision)
            forward_attributes(node, result)
        elif is_expandable_test(node):
            op = wrap_expansion(node.get_input(0),
                                self.expand_node(node.get_input(0)))
            result = generate_test_expansion(node.specifier, op)
            forward_attributes(node, result)
        else:
            result = None

        self.memoization_map[node] = result
        return result
Пример #14
0
def mantissa_extraction_modifier(optree):
    """ Legalizing a MantissaExtraction node into a sub-graph
        of basic operation """
    init_stage = optree.attributes.get_dyn_attribute("init_stage")
    op = optree.get_input(0)
    tag = optree.get_tag() or "mant_extr"

    op_precision = op.get_precision().get_base_format()
    exp_prec = ML_StdLogicVectorFormat(op_precision.get_exponent_size())
    field_prec = ML_StdLogicVectorFormat(op_precision.get_field_size())

    exp_op = RawExponentExtraction(op,
                                   precision=exp_prec,
                                   init_stage=init_stage,
                                   tag=tag + "_exp_extr")
    field_op = SubSignalSelection(TypeCast(
        op,
        precision=op.get_precision().get_support_format(),
        init_stage=init_stage,
        tag=tag + "_field_cast"),
                                  0,
                                  op_precision.get_field_size() - 1,
                                  precision=field_prec,
                                  init_stage=init_stage,
                                  tag=tag + "_field")
    exp_is_zero = Comparison(exp_op,
                             Constant(op_precision.get_zero_exponent_value(),
                                      precision=exp_prec,
                                      init_stage=init_stage),
                             precision=ML_Bool,
                             specifier=Comparison.Equal,
                             init_stage=init_stage)

    result = mantissa_extraction_modifier_from_fields(op, field_op,
                                                      exp_is_zero)
    forward_attributes(optree, result)
    return result
Пример #15
0
    def simplify_node(self, node):
        """ return the simplified version of @p node when possible
            else the node itself """
        result = node

        if node in self.memoization_map:
            return self.memoization_map[node]
        elif isinstance(node, SubSignalSelection):
            op_input = self.simplify_node(node.get_input(0))
            lo_index = evaluate_cst_graph(node.get_input(1))
            hi_index = evaluate_cst_graph(node.get_input(2))
            if isinstance(op_input, SubSignalSelection):
                parent_input = self.simplify_node(op_input.get_input(0))
                parent_lo_index = evaluate_cst_graph(op_input.get_input(1))
                new_node = SubSignalSelection(parent_input,
                                              parent_lo_index + lo_index,
                                              parent_lo_index + hi_index)
                forward_attributes(node, new_node)
                result = new_node

        elif isinstance(node, VectorElementSelection):
            op_input = self.simplify_node(node.get_input(0))
            op_index = evaluate_cst_graph(node.get_input(1))
            if isinstance(op_input, SubSignalSelection):
                parent_input = op_input.get_input(0)
                base_index = evaluate_cst_graph(op_input.get_input(1))
                new_node = BitSelection(parent_input, base_index + op_index)
                forward_attributes(node, new_node)
                result = new_node
            elif isinstance(op_input, Constant):
                offset = 0
                if is_fixed_point(op_input.get_precision()):
                    offset = -op_input.get_precision().get_frac_size()
                bit_value = (op_input.get_value() >> (op_index + offset)) & 1
                new_node = Constant(bit_value, precision=node.get_precision())
                forward_attributes(node, new_node)
                result = new_node
        else:
            result = node

        Log.report(LOG_VERBOSE_SIMPLIFY_RTL, "Simplifying {} to {}", node,
                   result)

        self.memoization_map[node] = result
        return result