<commit_before>"""
Generate legalizer transformations.

The transformations defined in the `cretonne.legalize` module are all of the
macro-expansion form where the input pattern is a single instruction. We
generate a Rust function for each `XFormGroup` which takes a `Cursor` pointing
at the instruction to be legalized. The expanded destination pattern replaces
the input instruction.
"""
from __future__ import absolute_import
from srcgen import Formatter
from base import legalize
from cdsl.ast import Var

try:
    from typing import Sequence  # noqa
    from cdsl.ast import Def  # noqa
    from cdsl.xform import XForm, XFormGroup  # noqa
except ImportError:
    pass


def unwrap_inst(iref, node, fmt):
    # type: (str, Def, Formatter) -> None
    """
    Given a `Def` node, emit code that extracts all the instruction fields from
    `dfg[iref]`.

    Create local variables named after the `Var` instances in `node`.

    :param iref: Name of the `Inst` reference to unwrap.
    :param node: `Def` node providing variable names.

    """
    fmt.comment('Unwrap {}'.format(node))
    expr = node.expr
    iform = expr.inst.format
    nvops = len(iform.value_operands)

    # The tuple of locals we're extracting is `expr.args`.
    with fmt.indented(
            'let ({}) = if let InstructionData::{} {{'
            .format(', '.join(map(str, expr.args)), iform.name), '};'):
        if iform.boxed_storage:
            # This format indirects to a largish `data` struct.
            fmt.line('ref data,')
        else:
            # Fields are encoded directly.
            for m in iform.imm_members:
                fmt.line('{},'.format(m))
            if nvops == 1:
                fmt.line('arg,')
            elif nvops > 1:
                fmt.line('args,')
        fmt.line('..')
        fmt.outdented_line('} = dfg[inst] {')
        # Generate the values for the tuple.
        outs = list()
        prefix = 'data.' if iform.boxed_storage else ''
        for i, m in enumerate(iform.members):
            if m:
                outs.append(prefix + m)
            else:
                # This is a value operand.
                if nvops == 1:
                    arg = prefix + 'arg'
                else:
                    arg = '{}args[{}]'.format(
                            prefix, iform.value_operands.index(i))
                outs.append('dfg.resolve_aliases({})'.format(arg))
        fmt.line('({})'.format(', '.join(outs)))
        fmt.outdented_line('} else {')
        fmt.line('unreachable!("bad instruction format")')

    # Get the types of any variables where it is needed.
    for i in iform.value_operands:
        v = expr.args[i]
        if isinstance(v, Var) and v.has_free_typevar():
            fmt.line('let typeof_{0} = dfg.value_type({0});'.format(v))

    # If the node has multiple results, detach the values.
    # Place the secondary values in 'src_{}' locals.
    if len(node.defs) > 1:
        if node.defs == node.defs[0].dst_def.defs:
            # Special case: The instruction replacing node defines the exact
            # same values.
            fmt.comment(
                    'Multiple results handled by {}.'
                    .format(node.defs[0].dst_def))
        else:<commit_msg>Avoid using 'members' and 'value_operands' in the legalizer.<commit_after>"""
Generate legalizer transformations.

The transformations defined in the `cretonne.legalize` module are all of the
macro-expansion form where the input pattern is a single instruction. We
generate a Rust function for each `XFormGroup` which takes a `Cursor` pointing
at the instruction to be legalized. The expanded destination pattern replaces
the input instruction.
"""
from __future__ import absolute_import
from srcgen import Formatter
from base import legalize
from cdsl.ast import Var

try:
    from typing import Sequence  # noqa
    from cdsl.ast import Def  # noqa
    from cdsl.xform import XForm, XFormGroup  # noqa
except ImportError:
    pass


def unwrap_inst(iref, node, fmt):
    # type: (str, Def, Formatter) -> None
    """
    Given a `Def` node, emit code that extracts all the instruction fields from
    `dfg[iref]`.

    Create local variables named after the `Var` instances in `node`.

    :param iref: Name of the `Inst` reference to unwrap.
    :param node: `Def` node providing variable names.

    """
    fmt.comment('Unwrap {}'.format(node))
    expr = node.expr
    iform = expr.inst.format
    nvops = iform.num_value_operands

    # The tuple of locals we're extracting is `expr.args`.
    with fmt.indented(
            'let ({}) = if let InstructionData::{} {{'
            .format(', '.join(map(str, expr.args)), iform.name), '};'):
        if iform.boxed_storage:
            # This format indirects to a largish `data` struct.
            fmt.line('ref data,')
        else:
            # Fields are encoded directly.
            for m in iform.imm_members:
                fmt.line('{},'.format(m))
            if nvops == 1:
                fmt.line('arg,')
            elif nvops != 0:
                fmt.line('args,')
        fmt.line('..')
        fmt.outdented_line('} = dfg[inst] {')
        # Generate the values for the tuple.
        outs = list()
        prefix = 'data.' if iform.boxed_storage else ''
        for opnum, op in enumerate(expr.inst.ins):
            if op.is_immediate():
                n = expr.inst.imm_opnums.index(opnum)
                outs.append(prefix + iform.imm_members[n])
            elif op.is_value():
                if nvops == 1:
                    arg = prefix + 'arg'
                else:
                    n = expr.inst.value_opnums.index(opnum)
                    arg = '{}args[{}]'.format(prefix, n)
                outs.append('dfg.resolve_aliases({})'.format(arg))
        fmt.line('({})'.format(', '.join(outs)))
        fmt.outdented_line('} else {')
        fmt.line('unreachable!("bad instruction format")')

    # Get the types of any variables where it is needed.
    for opnum in expr.inst.value_opnums:
        v = expr.args[opnum]
        if isinstance(v, Var) and v.has_free_typevar():
            fmt.line('let typeof_{0} = dfg.value_type({0});'.format(v))

    # If the node has multiple results, detach the values.
    # Place the secondary values in 'src_{}' locals.
    if len(node.defs) > 1:
        if node.defs == node.defs[0].dst_def.defs:
            # Special case: The instruction replacing node defines the exact
            # same values.
            fmt.comment(
                    'Multiple results handled by {}.'
                    .format(node.defs[0].dst_def))
        else:
{'fraction_non_alphanumeric': 0.11439336850037679, 'fraction_numerical': 0.0024114544084400903, 'mean_word_length': 2.1316658801321378, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6795753', 'n_tokens_mistral': 1972, 'n_tokens_neox': 1903, 'n_words': 619}