Пример #1
0
 def translate(self, func, sig):
     t = TranslationContext()
     t.buildannotator().build_types(func, sig)
     t.buildrtyper(type_system=self.type_system).specialize()
     if option.view:
         t.view()
     return t, RaiseAnalyzer(t)
Пример #2
0
def simple_inline_function(translator, inline_func, graph):
    inliner = Inliner(translator,
                      graph,
                      inline_func,
                      translator.rtyper.lltype_to_classdef_mapping(),
                      raise_analyzer=RaiseAnalyzer(translator))
    return inliner.inline_all()
Пример #3
0
 def inline_helpers(self, graph):
     if not self.prepared:
         raise Exception("Need to call prepare_inline_helpers first")
     if self.inline:
         raise_analyzer = RaiseAnalyzer(self.translator)
         to_enum = self.graph_dependencies.get(graph, self.graphs_to_inline)
         for inline_graph in to_enum:
             try:
                 inline.inline_function(self.translator, inline_graph, graph,
                                        self.lltype_to_classdef,
                                        raise_analyzer,
                                        cleanup=False)
             except inline.CannotInline, e:
                 print 'CANNOT INLINE:', e
                 print '\t%s into %s' % (inline_graph, graph)
         cleanup_graph(graph)
Пример #4
0
Файл: call.py Проект: njues/Sypy
 def __init__(self, cpu=None, jitdrivers_sd=[]):
     assert isinstance(jitdrivers_sd, list)   # debugging
     self.cpu = cpu
     self.jitdrivers_sd = jitdrivers_sd
     self.jitcodes = {}             # map {graph: jitcode}
     self.unfinished_graphs = []    # list of graphs with pending jitcodes
     self.callinfocollection = CallInfoCollection()
     if hasattr(cpu, 'rtyper'):     # for tests
         self.rtyper = cpu.rtyper
         translator = self.rtyper.annotator.translator
         self.raise_analyzer = RaiseAnalyzer(translator)
         self.readwrite_analyzer = ReadWriteAnalyzer(translator)
         self.virtualizable_analyzer = VirtualizableAnalyzer(translator)
         self.quasiimmut_analyzer = QuasiImmutAnalyzer(translator)
         self.randomeffects_analyzer = RandomEffectsAnalyzer(translator)
     #
     for index, jd in enumerate(jitdrivers_sd):
         jd.index = index
Пример #5
0
def auto_inlining(translator,
                  threshold=None,
                  callgraph=None,
                  call_count_pred=None,
                  heuristic=inlining_heuristic):

    assert threshold is not None and threshold != 1
    to_cleanup = {}
    from heapq import heappush, heappop, heapreplace, heapify
    callers = {}  # {graph: {graphs-that-call-it}}
    callees = {}  # {graph: {graphs-that-it-calls}}
    if callgraph is None:
        callgraph = inlinable_static_callers(translator.graphs)
    for graph1, graph2 in callgraph:
        callers.setdefault(graph2, {})[graph1] = True
        callees.setdefault(graph1, {})[graph2] = True
    # the -len(callers) change is OK
    heap = [(0.0, -len(callers[graph]), graph) for graph in callers]
    valid_weight = {}
    try_again = {}
    lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping()
    raise_analyzer = RaiseAnalyzer(translator)
    count = 0
    while heap:
        weight, _, graph = heap[0]
        if not valid_weight.get(graph):
            if hasattr(graph, 'func') and \
                   getattr(graph.func, '_always_inline_', None):
                weight, fixed = 0.0, True
            else:
                weight, fixed = heuristic(graph)
            #print '  + cost %7.2f %50s' % (weight, graph.name)
            heapreplace(heap, (weight, -len(callers[graph]), graph))
            valid_weight[graph] = True
            if not fixed:
                try_again[graph] = True
            continue

        if weight >= threshold:
            # finished... unless some graphs not in valid_weight would now
            # have a weight below the threshold.  Re-insert such graphs
            # at the start of the heap
            finished = True
            for i in range(len(heap)):
                graph = heap[i][2]
                if not valid_weight.get(graph):
                    heap[i] = (0.0, heap[i][1], graph)
                    finished = False
            if finished:
                break
            else:
                heapify(heap)
                continue

        heappop(heap)
        if callers[graph]:
            if translator.config.translation.verbose:
                log.inlining('%7.2f %50s' % (weight, graph.name))
            else:
                log.dot()
        for parentgraph in callers[graph]:
            if parentgraph == graph:
                continue
            subcount = 0
            try:
                subcount = inline_function(translator,
                                           graph,
                                           parentgraph,
                                           lltype_to_classdef,
                                           raise_analyzer,
                                           call_count_pred,
                                           cleanup=False)
                to_cleanup[parentgraph] = True
                res = bool(subcount)
            except CannotInline:
                try_again[graph] = True
                res = CannotInline
            if res is True:
                count += subcount
                # the parentgraph should now contain all calls that were
                # done by 'graph'
                for graph2 in callees.get(graph, {}):
                    callees[parentgraph][graph2] = True
                    callers[graph2][parentgraph] = True
                if parentgraph in try_again:
                    # the parentgraph was previously uninlinable, but it has
                    # been modified.  Maybe now we can inline it into further
                    # parents?
                    del try_again[parentgraph]
                    heappush(heap,
                             (0.0, -len(callers[parentgraph]), parentgraph))
                valid_weight[parentgraph] = False
    for graph in to_cleanup:
        cleanup_graph(graph)
    return count