Beispiel #1
0
def check_scoping(func, env):
    for op in func.ops:
        if op.opcode == 'phi':
            continue

        for arg in flatten(op.args):
            if isinstance(arg, Undef):
                raise NameError("Variable referenced before assignment")
Beispiel #2
0
def check_scoping(func, env):
    for op in func.ops:
        if op.opcode == 'phi':
            continue

        for arg in flatten(op.args):
            if isinstance(arg, Undef):
                raise NameError("Variable referenced before assignment")
Beispiel #3
0
 def _process(self, ty, args=None, result=None, **metadata):
     if args is None:
         args = []
     assert ty is not None
     assert isinstance(args, list), args
     assert not any(arg is None for arg in flatten(args)), args
     result = Op(op, ty, args, result)
     if metadata:
         result.add_metadata(metadata)
     self._insert_op(result)
     return result
Beispiel #4
0
 def _process(self, ty, args=None, result=None, **metadata):
     if args is None:
         args = []
     assert ty is not None
     assert isinstance(args, list), args
     assert not any(arg is None for arg in flatten(args)), args
     result = Op(op, ty, args, result)
     if metadata:
         result.add_metadata(metadata)
     self._insert_op(result)
     return result
Beispiel #5
0
    def op_call(self, op):
        """
        Γ ⊢ f : (α -> β)        Γ ⊢ x : α
        ----------------------------------
                   Γ ⊢ f(a) : β
        """
        for arg in flatten(op.args):
            self.G.add_edge(arg, op)
        self.constraints[op] = 'call'

        func, args = op.args
        self.metadata[op] = { 'func': func, 'args': args, 'call': op }
Beispiel #6
0
    def op_call(self, op):
        """
        Γ ⊢ f : (α -> β)        Γ ⊢ x : α
        ----------------------------------
                   Γ ⊢ f(a) : β
        """
        for arg in flatten(op.args):
            self.G.add_edge(arg, op)
        self.constraints[op] = 'call'

        func, args = op.args
        self.metadata[op] = { 'func': func, 'args': args}
Beispiel #7
0
def vmap(f, func):
    """
    Apply `f` over all the values in `func`, that is, all Op, Const, FuncArg
    and GlobalValue.
    """
    from . import GlobalValue, Const, Function

    for arg in func.args:
        yield f(arg)
    for op in func.ops:
        yield f(op)
        for arg in flatten(op.args):
            if isinstance(arg, (GlobalValue, Const, Function)):
                yield f(arg)
Beispiel #8
0
def defuse(func):
    """
    Map definitions to uses, e.g.

        %0 = add %a %b
        %1 = mul %0 %b

            => { '%a': {'%0'}, '%b': {'%0', '%1'}, '%0': {'%1'}}
    """
    defuse = defaultdict(set) # { def : { use } }
    for block in func.blocks:
        for op in block:
            for arg in flatten(op.operands):
                defuse[arg].add(op.result)

    return defuse
Beispiel #9
0
def defuse(func):
    """
    Map definitions to uses, e.g.

        %0 = add %a %b
        %1 = mul %0 %b

            => { '%a': {'%0'}, '%b': {'%0', '%1'}, '%0': {'%1'}}
    """
    defuse = defaultdict(set)  # { def : { use } }
    for block in func.blocks:
        for op in block:
            for arg in flatten(op.operands):
                defuse[arg].add(op.result)

    return defuse
Beispiel #10
0
def build_graph(func):
    """
    Build a constraint network and initial context. This is a generic
    templates share-able between input types.
    """
    G = networkx.DiGraph()
    context = initial_context(func)

    for op in func.ops:
        G.add_node(op)
        for arg in flatten(op.args):
            if isinstance(arg, (ir.Const, ir.GlobalValue, ir.FuncArg)):
                G.add_node(arg)

    constraints, metadata = generate_constraints(func, G)
    return Context(func, context, constraints, G, metadata)
Beispiel #11
0
def build_graph(func):
    """
    Build a constraint network and initial context. This is a generic
    templates share-able between input types.
    """
    G = networkx.DiGraph()
    context = initial_context(func)

    for op in func.ops:
        G.add_node(op)
        for arg in flatten(op.args):
            if isinstance(arg, (ir.Const, ir.GlobalValue, ir.FuncArg)):
                G.add_node(arg)

    constraints, metadata = generate_constraints(func, G)
    return Context(func, context, constraints, G, metadata)
Beispiel #12
0
def defuse(func):
    """
    Map definitions to uses, e.g.

        %0 = add %a %b
        %1 = mul %0 %b

            => { Op('%a'): {Op('%0')}, ... }
    """
    defuse = defaultdict(set)  # { def : { use } }
    for block in func.blocks:
        for op in block:
            for arg in flatten(op.args):
                if isinstance(arg, (Op, FuncArg, Block)):
                    defuse[arg].add(op)

    return defuse
Beispiel #13
0
def defuse(func):
    """
    Map definitions to uses, e.g.

        %0 = add %a %b
        %1 = mul %0 %b

            => { Op('%a'): {Op('%0')}, ... }
    """
    defuse = defaultdict(set) # { def : { use } }
    for block in func.blocks:
        for op in block:
            for arg in flatten(op.args):
                if isinstance(arg, (Op, FuncArg, Block)):
                    defuse[arg].add(op)

    return defuse
Beispiel #14
0
def initial_context(func):
    """Initialize context with argtypes"""
    context = { 'return': set(), void: void, bool_: bool_}
    context['return'] = set()
    count = 0

    for op in func.ops:
        context[op] = set()
        if op.opcode == 'alloca':
            context['alloca%d' % count] = set()
            count += 1
        for arg in flatten(op.args):
            if (isinstance(arg, ir.Const) and
                    isinstance(arg.const, FunctionWrapper)):
                context[arg] = set([None])
            elif isinstance(arg, ir.Const):
                context[arg] = set([typeof(arg.const)])
            elif isinstance(arg, ir.GlobalValue):
                raise NotImplementedError("Globals")

    return context
Beispiel #15
0
def initial_context(func):
    """Initialize context with argtypes"""
    context = { 'return': set(), 'generator': set(), void: void, bool_: bool_ }
    context['return'] = set()
    count = 0

    for op in func.ops:
        context[op] = set()
        if op.opcode == 'alloca':
            context['alloca%d' % count] = set()
            count += 1
        for arg in flatten(op.args):
            if (isinstance(arg, ir.Const) and
                    isinstance(arg.const, FunctionWrapper)):
                context[arg] = set([None])
            elif isinstance(arg, ir.Const):
                context[arg] = set([typeof(arg.const)])
            elif isinstance(arg, ir.Undef):
                context[arg] = set()
            elif isinstance(arg, ir.GlobalValue):
                raise NotImplementedError("Globals")

    return context
Beispiel #16
0
 def symbols(self):
     """Set of symbolic register operands"""
     return [x for x in flatten(self.args)]
Beispiel #17
0
 def symbols(self):
     """Set of symbolic register operands"""
     return [x for x in flatten(self.args)]