示例#1
0
    # setting stage id if undefined or updating stage_id value
    stage_id = optree_set_undefined_stage(optree, stage_id)

    if isinstance(optree, ML_LeafNode):
        pass
    else:
        for op_input in optree.get_inputs():
            unify_stages_rec(op_input, stage_id, memoization_map)

    memoization_map[optree] = stage_id


class Pass_UnifyPipelineStages(OptreeOptimization):
    """ implementation of pipeline stage uniformisation """
    pass_tag = "unify_pipeline_stages"

    def __init__(self, target):
        """ pass initialization """
        OptreeOptimization.__init__(self, "unify_pipeline_stages", target)

    def execute(self, optree):
        """ pass execution """
        return unify_stages_rec(optree, {})


# register pass
Log.report(Log.Info,
           "Registering {}  pass".format(Pass_UnifyPipelineStages.pass_tag))
Pass.register(Pass_UnifyPipelineStages)
示例#2
0
## _m128 register promotion
class Pass_M128_Promotion(Pass_Vector_Promotion):
    pass_tag = "m128_promotion"
    ## Translation table between standard formats
    #  and __m128-based register formats
    trans_table = {
        ML_Binary32: ML_SSE_m128_v1float32,
        ML_Binary64: ML_SSE_m128_v1float64,
        v2float64: ML_SSE_m128_v2float64,
        v4float32: ML_SSE_m128_v4float32,
        v4bool: ML_SSE_m128_v4bool,
        v2int64: ML_SSE_m128_v2int64,
        v4int32: ML_SSE_m128_v4int32,
        v2uint64: ML_SSE_m128_v2uint64,
        v4uint32: ML_SSE_m128_v4uint32,
        ML_Int32: ML_SSE_m128_v1int32,
    }

    def get_translation_table(self):
        return self.trans_table

    def __init__(self, target):
        Pass_Vector_Promotion.__init__(self, target)
        self.set_descriptor("SSE promotion pass")


Log.report(LOG_PASS_INFO, "Registering m128_conversion pass")
# register pass
Pass.register(Pass_M128_Promotion)
                    self.promote_node(op) for op in optree.get_inputs()
                ]

                # register modified inputs
                new_optree.inputs = new_inputs

                if parent_converted and optree.get_precision(
                ) in self.get_translation_table():
                    new_optree = insert_conversion_when_required(
                        new_optree,
                        self.get_conv_format(optree.get_precision())
                    )  #Conversion(new_optree, precision = self.get_conv_format(optree.get_precision()))
                    return new_optree
                elif parent_converted:
                    print(optree.get_precision())
                    raise NotImplementedError
                return self.memoize(parent_converted, optree, new_optree)

    # standard Opt pass API
    def execute_on_optree(self,
                          optree,
                          fct=None,
                          fct_group=None,
                          memoization_map=None):
        return self.promote_node(optree)


Log.report(LOG_PASS_INFO, "Registering vector_conversion pass")
# register pass
Pass.register(Pass_Vector_Promotion)
示例#4
0
    def __init__(self,
                 target,
                 default_precision,
                 default_integer_format=ML_Int32,
                 default_boolean_precision=ML_Int32):
        FunctionPass.__init__(self, "instantiate_prec")
        self.default_integer_format = default_integer_format
        self.default_boolean_precision = default_boolean_precision
        self.default_precision = default_precision

    def execute_on_optree(self,
                          optree,
                          fct=None,
                          fct_group=None,
                          memoization_map=None):
        memoization_map = memoization_map if not memoization_map is None else {}
        optree_precision = instantiate_precision(
            optree,
            self.default_precision,
            memoization_map=memoization_map,
            backend=self)
        return optree


# register pass
Log.report(LOG_PASS_INFO, "Registering instantiate_abstract_prec pass")
Pass.register(PassInstantiateAbstractPrecision)

Log.report(LOG_PASS_INFO, "Registering instantiate_prec pass")
Pass.register(PassInstantiatePrecision)
示例#5
0
            check_result = self.check_function(optree)
            self.memoization_map[optree] = check_result
            if not check_result:
                Log.report(
                    Log.Info, "the following node check failed: {}".format(
                        optree.get_str(depth=2,
                                       display_precision=True,
                                       memoization_map={})))
            if not isinstance(optree, ML_LeafNode):
                for op_input in optree.get_inputs():
                    check_result &= self.execute(op_input)
            return check_result


## Generic vector promotion pass
class Pass_CheckPrecision(Pass_CheckGeneric):
    pass_tag = "check_precision"

    def __init__(self, target):
        Pass_CheckGeneric.__init__(self, target, check_precision_validity,
                                   "check_precision pass")
        self.memoization_map = {}


# register pass
Log.report(LOG_PASS_INFO, "Registering check_generic pass")
Pass.register(Pass_CheckGeneric)

Log.report(LOG_PASS_INFO, "Registering check_precision pass")
Pass.register(Pass_CheckPrecision)
示例#6
0
                                    target)
        ## memoization map for promoted optree
        self.memoization_map = {}
        self.expander = VectorMaskTestExpander(target)

    def can_be_transformed(self, node, *args):
        """ Returns True if @p can be expanded from a multi-precision
            node to a list of scalar-precision fields,
            returns False otherwise """
        return self.expander.is_expandable(node)

    def transform_node(self, node, transformed_inputs, *args):
        """ If node can be transformed returns the transformed node
            else returns None """
        return self.expander.expand_node(node)

    def reconstruct_from_transformed(self, node, transformed_node):
        """return a node at the root of a transformation chain,
            compatible with untransformed nodes """
        return transformed_node

    ## standard Opt pass API
    def execute(self, optree):
        """ Implémentation of the standard optimization pass API """
        return self.transform_graph(optree)


Log.report(LOG_PASS_INFO, "Registering vector_mask_test_legalization pass")
# register pass
Pass.register(Pass_VectorMaskTestLegalization)
示例#7
0
    def evaluate_set_range(self, optree, memoization_map=None):
        """ check if all precision-instantiated operation are supported by the processor """
        # memoization map is used to store node's range/interval
        memoization_map = {} if memoization_map is None else memoization_map
        if  optree in memoization_map:
            return optree
        else:
            if not is_leaf_node(optree):
                for op in optree.inputs:
                    _ = self.evaluate_set_range(op, memoization_map=memoization_map)

            if optree.get_interval() is None:
                op_range = evaluate_range(optree, update_interval=True)
            else:
                op_range = optree.get_interval()
            if not op_range is None:
                Log.report(LOG_VERBOSE_EVALUATE_RANGE, "range for {} has been evaluated to {}", optree, op_range)
            # memoization
            memoization_map[optree] = op_range
            return optree

    def execute_on_optree(self, optree, fct=None, fct_group=None, memoization_map=None):
        return self.evaluate_set_range(optree, memoization_map)



Log.report(LOG_PASS_INFO, "Registering evaluate_range pass")
# register pass
Pass.register(Pass_EvaluateRange)
        ## memoization map for promoted optree
        self.memoization_map = {}
        self.expander = MultiPrecisionExpander(target)

    def can_be_transformed(self, node, *args):
        """ Returns True if @p can be expanded from a multi-precision
            node to a list of scalar-precision fields,
            returns False otherwise """
        return self.expander.is_expandable(node)

    def transform_node(self, node, transformed_inputs, *args):
        """ If node can be transformed returns the transformed node
            else returns None """
        return self.expander.expand_node(node)

    def reconstruct_from_transformed(self, node, transformed_node):
        """return a node at the root of a transformation chain,
            compatible with untransformed nodes """
        return self.expander.reconstruct_from_transformed(
            node, transformed_node)

    ## standard Opt pass API
    def execute(self, optree):
        """ Implémentation of the standard optimization pass API """
        return self.transform_graph(optree)


Log.report(LOG_PASS_INFO, "Registering expand_multi_precision pass")
# register pass
Pass.register(Pass_ExpandMultiPrecision)
            if not result is None:
                Log.report(LOG_VERBOSE_NUMERICAL_SIMPLIFICATION, "{} has been simplified to {}", node, result)
            self.memoization_map[node] = result
            return result





class Pass_NumericalSimplification(FunctionPass):
    """ Pass to expand oepration on vector masks """
    pass_tag = "numerical_simplification"

    def __init__(self, target):
        FunctionPass.__init__(
            self, "virtual vector bool legalization pass", target)
        ## memoization map for promoted optree
        self.memoization_map = {}
        self.simplifier = NumericalSimplifier(target)

    def execute_on_optree(self, node, fct=None, fct_group=None, memoization_map=None):
        """ If node can be transformed returns the transformed node
            else returns None """
        return self.simplifier.simplify(node)



Log.report(LOG_PASS_INFO, "Registering numerical_simplification pass")
# register pass
Pass.register(Pass_NumericalSimplification)
示例#10
0
                cond_cp, if_value_cp, else_value_cp)
            return self.memoize_result(optree, select_cp)
        elif optree.__class__ in OPERATION_CLASS_TIMING_MODEL:
            return self.memoize_result(
                optree, OPERATION_CLASS_TIMING_MODEL[optree.__class__](self,
                                                                       optree))
        else:
            Log.report(Log.Error, "unkwown node in evaluate_critical_path: {}",
                       optree)

    def execute(self, optree):
        self.evaluate_critical_path(optree)
        ordered_list = [
            op for op in self.memoization_map.keys()
            if not self.memoization_map[op] is None
        ]
        ordered_list = sorted(ordered_list,
                              key=lambda v: self.memoization_map[v].value,
                              reverse=True)

        longest_path = self.memoization_map[ordered_list[0]]
        current = longest_path
        while current != None:
            print(current.node.get_tag(), current.value)
            current = current.previous


Log.report(LOG_PASS_INFO, "Registering critical_path_eval pass")
# register pass
Pass.register(Pass_CriticalPathEval)
示例#11
0
        OptreeOptimization.__init__(self, "rtl simplification pass", target)
        ## memoization map for promoted optree
        self.memoization_map = {}
        self.simplifier = BasicSimplifier(target)

    def can_be_transformed(self, node, *args):
        """ Returns True if @p can be expanded from a multi-precision
            node to a list of scalar-precision fields,
            returns False otherwise """
        return self.simplifier.is_simplifiable(node)

    def transform_node(self, node, transformed_inputs, *args):
        """ If node can be transformed returns the transformed node
            else returns None """
        return self.simplifier.simplify_node(node)

    def reconstruct_from_transformed(self, node, transformed_node):
        """return a node at the root of a transformation chain,
            compatible with untransformed nodes """
        return transformed_node

    ## standard Opt pass API
    def execute(self, optree):
        """ Implémentation of the standard optimization pass API """
        return self.transform_graph(optree)


Log.report(LOG_PASS_INFO, "Registering simplify_rtl pass")
# register pass
Pass.register(Pass_SimplifyRTL)
示例#12
0
                # no simplification
                result = node
            self.memoization_map[node] = result
            return result


class Pass_LogicalSimplification(FunctionPass):
    """ Pass to simplify logical operation """
    pass_tag = "logical_simplification"

    def __init__(self, target):
        FunctionPass.__init__(self, "logical operation simplification pass",
                              target)
        ## memoization map for promoted optree
        self.memoization_map = {}
        self.simplifier = LogicalSimplification(target)

    def execute_on_optree(self,
                          node,
                          fct=None,
                          fct_group=None,
                          memoization_map=None):
        """ If node can be transformed returns the transformed node
            else returns None """
        return self.simplifier.simplify(node)


Log.report(LOG_PASS_INFO, "Registering logical_simplification pass")
# register pass
Pass.register(Pass_LogicalSimplification)
示例#13
0
        OptreeOptimization.__init__(self, "basic legalization pass", target)
        ## memoization map for promoted optree
        self.memoization_map = {}
        self.expander = BasicExpander(target)

    def can_be_transformed(self, node, *args):
        """ Returns True if @p can be expanded from a multi-precision
            node to a list of scalar-precision fields,
            returns False otherwise """
        return self.expander.is_expandable(node)

    def transform_node(self, node, transformed_inputs, *args):
        """ If node can be transformed returns the transformed node
            else returns None """
        return self.expander.expand_node(node)

    def reconstruct_from_transformed(self, node, transformed_node):
        """return a node at the root of a transformation chain,
            compatible with untransformed nodes """
        return transformed_node

    ## standard Opt pass API
    def execute(self, optree):
        """ Implémentation of the standard optimization pass API """
        return self.transform_graph(optree)


Log.report(LOG_PASS_INFO, "Registering basic_legalization pass")
# register pass
Pass.register(Pass_BasicLegalization)
示例#14
0
            elif isinstance(optree, PlaceHolder):
                pass
            elif isinstance(optree, SwitchBlock):
                #self.check_processor_support(optree.get_pre_statement(), memoization_map)

                for op in optree.get_extra_inputs():
                    # TODO: assert case is integer constant
                    self.check_processor_support(op,
                                                 memoization_map,
                                                 debug=debug)
            elif not self.get_target().is_supported_operation(optree,
                                                              debug=debug):
                print(self.processor.get_operation_keys(optree))  # Error print
                print(
                    optree.get_str(display_precision=True,
                                   display_id=True,
                                   memoization_map={}))  # Error print
                Log.report(Log.Error, "unsupported operation\n")
        # memoization
        memoization_map[optree] = True
        return True

    def execute(self, optree):
        memoization_map = {}
        return self.check_processor_support(optree, memoization_map)


Log.report(LOG_PASS_INFO, "Registering check_target_support pass")
# register pass
Pass.register(Pass_CheckSupport)
示例#15
0
        """ """
        # looking into memoization map
        if optree in self.memoization_map:
            return False, 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 = legalize_single_operation(optree, self.format_solver)

        self.memoization_map[optree] = new_optree 
        return (local_changed or arg_changed), new_optree


    def execute(self, optree):
        """ pass execution """
        return self.legalize_operation_rec(optree)

Log.report(LOG_PASS_INFO, "Registering size_datapath pass")
# register pass
Pass.register(Pass_RTLLegalize)
示例#16
0
        if optree.__class__ in support_simplification:
            code_gen_key = optree.get_codegen_key()
            if code_gen_key in support_simplification[optree.__class__]:
                for cond in support_simplification[
                        optree.__class__][code_gen_key]:
                    if cond(optree): return True
        return False

    def get_support_simplification(self, optree):
        code_gen_key = optree.get_codegen_key()
        for cond in support_simplification[optree.__class__][code_gen_key]:
            if cond(optree):
                return support_simplification[
                    optree.__class__][code_gen_key][cond](optree,
                                                          self.processor)
        Log.report(Log.Error, "support simplification mapping not found")


# register pass
Log.report(LOG_PASS_INFO, "Registering silence_fp_operations pass")
Pass.register(PassSilenceFPOperation)

Log.report(LOG_PASS_INFO, "Registering fuse_fma pass")
Pass.register(PassFuseFMA)

Log.report(LOG_PASS_INFO, "Registering sub_expr_sharing pass")
Pass.register(PassSubExpressionSharing)

Log.report(LOG_PASS_INFO, "Registering check_processor_support pass")
Pass.register(PassCheckProcessorSupport)
示例#17
0
from metalibm_core.opt.p_vector_promotion import Pass_Vector_Promotion


## _m256 register promotion
class Pass_M256_Promotion(Pass_Vector_Promotion):
  pass_tag = "m256_promotion"
  ## Translation table between standard formats
  #  and __m256-based register formats
  trans_table = {
    v4float64:   ML_AVX_m256_v4float64,
    v8float32:   ML_AVX_m256_v8float32,
    v4int64:     ML_AVX_m256_v4int64,
    v8int32:     ML_AVX_m256_v8int32,
    v4uint64:    ML_AVX_m256_v4uint64,
    v8uint32:    ML_AVX_m256_v8uint32,
    v8bool:      ML_AVX_m256_v8bool,
  }

  def get_translation_table(self):
    return self.trans_table

  def __init__(self, target):
    Pass_Vector_Promotion.__init__(self, target)
    self.set_descriptor("AVX promotion pass")



Log.report(LOG_PASS_INFO, "Registering m256_conversion pass")
# register pass
Pass.register(Pass_M256_Promotion)
示例#18
0

## Legalize the precision of a datapath by finely tuning the size
#  of each operations (limiting width while preventing overflow)
class Pass_SizeDatapath(FunctionPass):
    """ implementation of datapath sizing pass """
    pass_tag = "size_datapath"

    def __init__(self, target):
        """ pass initialization """
        FunctionPass.__init__(self, "size_datapath", target)
        self.format_solver = FormatSolver()

    def execute(self, optree):
        """ pass execution,
            API required to be executed on an ML_Entity """
        return self.format_solver.solve_format_rec(optree)

    def execute_on_optree(self,
                          optree,
                          fct=None,
                          fct_group=None,
                          memoization_map=None):
        """ Trampoline required by FunctionPass API """
        return self.execute(optree)


Log.report(LOG_PASS_INFO, "Registering size_datapath pass")
# register pass
Pass.register(Pass_SizeDatapath)
示例#19
0
                                    target)
        ## memoization map for promoted optree
        self.memoization_map = {}
        self.expander = VirtualBoolVectorLegalizer(target)

    def can_be_transformed(self, node, *args):
        """ Returns True if @p can be expanded from a multi-precision
            node to a list of scalar-precision fields,
            returns False otherwise """
        return self.expander.is_legalizable(node)

    def transform_node(self, node, transformed_inputs, *args):
        """ If node can be transformed returns the transformed node
            else returns None """
        return self.expander.legalize_node(node)

    def reconstruct_from_transformed(self, node, transformed_node):
        """return a node at the root of a transformation chain,
            compatible with untransformed nodes """
        return transformed_node

    ## standard Opt pass API
    def execute(self, optree):
        """ Implémentation of the standard optimization pass API """
        return self.transform_graph(optree)


Log.report(LOG_PASS_INFO, "Registering virtual_vector_bool_legalization pass")
# register pass
Pass.register(Pass_VirtualVectorBoolLegalization)
示例#20
0
    def execute_on_function(self, fct, fct_group):
        """ Execute SSA translation pass on function @p fct from
            function-group @p fct_group """
        Log.report(LOG_LEVEL_GEN_BB_INFO, "executing pass {} on fct {}".format(
            self.pass_tag, fct.get_name()))
        optree = fct.get_scheme()
        assert isinstance(optree, BasicBlockList)
        bb_root = optree.get_input(0)
        bbg = BasicBlockGraph(bb_root, optree)
        phi_node_insertion(bbg)
        variable_renaming(bbg)

# registering basic-block generation pass
Log.report(LOG_PASS_INFO, "Registering generate Basic-Blocks pass")
Pass.register(Pass_GenerateBasicBlock)
# registering ssa translation pass
Log.report(LOG_PASS_INFO, "Registering ssa translation pass")
Pass.register(Pass_SSATranslate)
# registering basic-block simplification pass
Log.report(LOG_PASS_INFO, "Registering basic-block simplification pass")
Pass.register(Pass_BBSimplification)

if __name__ == "__main__":
    bb_root = BasicBlock(tag="bb_root")
    bb_1 = BasicBlock(tag="bb_1")
    bb_2 = BasicBlock(tag="bb_2")
    bb_3 = BasicBlock(tag="bb_3")

    var_x = Variable("x", precision=None)
    var_y = Variable("y", precision=None)
示例#21
0
            function-group @p fct_group """
        Log.report(
            LOG_LEVEL_GEN_BB_INFO,
            "executing pass {} on fct {}".format(self.pass_tag,
                                                 fct.get_name()))
        optree = fct.get_scheme()
        assert isinstance(optree, BasicBlockList)
        bb_root = optree.get_input(0)
        bbg = BasicBlockGraph(bb_root, optree)
        phi_node_insertion(bbg)
        variable_renaming(bbg)


# registering basic-block generation pass
Log.report(LOG_PASS_INFO, "Registering generate Basic-Blocks pass")
Pass.register(Pass_GenerateBasicBlock)
# registering ssa translation pass
Log.report(LOG_PASS_INFO, "Registering ssa translation pass")
Pass.register(Pass_SSATranslate)

if __name__ == "__main__":
    bb_root = BasicBlock(tag="bb_root")
    bb_1 = BasicBlock(tag="bb_1")
    bb_2 = BasicBlock(tag="bb_2")
    bb_3 = BasicBlock(tag="bb_3")

    var_x = Variable("x", precision=None)
    var_y = Variable("y", precision=None)

    bb_root.add(ReferenceAssign(var_x, 1))
    bb_root.add(ReferenceAssign(var_y, 2))