def _phase_1(code):
    instructions = code.instructions

    ''' Generate flow graph '''
    flow_graph = cfg.generate(instructions)

    ''' Get usability information '''
    use_ins, use_outs = fu.analyse(flow_graph, code.argument_fields, [])

    ''' Cherry-pick dead instructions '''
    instruction_list = []
    for _, node in flow_graph.iteritems():
        for instruction in node.basic_block:
            if isinstance(instruction, I.RMV):
                if is_reserved_or_argument_field(instruction.field.field, code.argument_fields):
                    pass
                else:
                    if get_rmv_instruction_count(code.instructions, instruction.field.field) < 2:
                        pass
                    elif not (instruction.field.field in use_outs[instruction]):
                        instruction_list.append(instruction)

    ''' Remove dead instructions from the code '''
    for instruction in instruction_list:
        instructions.remove(instruction)
def _phase_1(code):
    instructions = code.instructions
    ''' Generate flow graph '''
    flow_graph = cfg.generate(instructions)
    ''' Get usability information '''
    use_ins, use_outs = fu.analyse(flow_graph, code.argument_fields, [I.RMV])
    ''' Cherry-pick dead instructions '''
    instruction_list = []
    for _, node in flow_graph.iteritems():
        for instruction in node.basic_block:
            if isinstance(instruction, I.ADD):
                if is_reserved_or_argument_field(instruction.field.field,
                                                 code.argument_fields):
                    pass
                elif not (instruction.field.field in use_outs[instruction]):
                    instruction_list.append(instruction)
    ''' Remove dead instructions from the code '''
    for instruction in instruction_list:
        instructions.remove(instruction)
def _phase_2(code):
    instructions = code.instructions

    """ Generate flow graph """
    flow_graph = cfg.generate(instructions)

    """ Get reachability information """
    reach_ins, reach_outs = fr.analyse(flow_graph, code.argument_fields, [I.ADD])

    """ Cherry-pick dead instructions """
    instruction_list = []
    for _, node in flow_graph.iteritems():
        for instruction in node.basic_block:
            if isinstance(instruction, I.RMV):
                if is_reserved_or_argument_field(instruction.field.field, code.argument_fields):
                    pass
                elif not (instruction.field.field in reach_ins[instruction]):
                    instruction_list.append(instruction)

    """ Remove dead instructions from the code """
    for instruction in instruction_list:
        instructions.remove(instruction)
def _phase_0(code):
    instructions = code.instructions
    ''' Generate flow graph '''
    flow_graph = cfg.generate(instructions)
    ''' Get reachability information '''
    reach_ins, reach_outs = fr.analyse(flow_graph, code.argument_fields, [])
    ''' Cherry-pick dead instructions '''
    instruction_list = []
    for _, node in flow_graph.iteritems():
        for instruction in node.basic_block:
            if isinstance(instruction, I.ADD):
                if is_reserved_or_argument_field(instruction.field.field,
                                                 code.argument_fields):
                    pass
                else:
                    if get_add_instruction_count(code.instructions,
                                                 instruction.field.field) < 2:
                        pass
                    elif not (instruction.field.field
                              in reach_ins[instruction]):
                        instruction_list.append(instruction)
    ''' Remove dead instructions from the code '''
    for instruction in instruction_list:
        instructions.remove(instruction)
Exemple #5
0
def cost_Code(code, state):
    argument_fields = code.argument_fields
    instructions = code.instructions
    ''' Generate control flow graph '''
    flow_graph = cfg.generate(instructions)
    ''' Get reaching definitions information (for I.ADD only) '''
    reach_def_ins, reach_def_outs = rd.analyse(
        flow_graph, [],
        [I.LD, I.OP, I.LDt, I.LKt, I.CRC, I.HSH, I.CNC, I.ATM, I.SEQ])
    ''' Get field reachability information '''
    reach_ins, reach_outs = fr.analyse(
        flow_graph, [],
        [I.LD, I.OP, I.LDt, I.LKt, I.CRC, I.HSH, I.CNC, I.ATM, I.SEQ])

    instruction_dict = {}
    for _, node in flow_graph.iteritems():
        for instruction in node.basic_block:
            if isinstance(instruction, I.ID):
                state.area += get_header_size(reach_ins[instruction],
                                              reach_def_ins[instruction],
                                              argument_fields)
                state.latency += 1
            elif isinstance(instruction, I.DRP):
                state.area += get_header_size(reach_ins[instruction],
                                              reach_def_ins[instruction],
                                              argument_fields)
                state.latency += 1
            elif isinstance(instruction, I.CTR):
                state.area += get_header_size(reach_ins[instruction],
                                              reach_def_ins[instruction],
                                              argument_fields)
                state.latency += 1
            elif isinstance(instruction, I.ADD):
                pass
            elif isinstance(instruction, I.RMV):
                pass
            elif isinstance(instruction, I.LD):
                if isinstance(instruction.source, O.Value) or isinstance(
                        instruction.source, O.Field):
                    state.area += get_header_size(reach_ins[instruction],
                                                  reach_def_ins[instruction],
                                                  argument_fields)
                    state.latency += 1
                elif isinstance(instruction.source, O.Location):
                    state.area += get_header_size(reach_ins[instruction],
                                                  reach_def_ins[instruction],
                                                  argument_fields) * 2
                    state.latency += 2
            elif isinstance(instruction, I.ST):
                state.area += get_header_size(reach_ins[instruction],
                                              reach_def_ins[instruction],
                                              argument_fields)
                state.latency += 1
            elif isinstance(instruction, I.OP):
                if not (instruction.operator == Op.Mul
                        or instruction.operator == Op.Div):
                    state.area += get_header_size(reach_ins[instruction],
                                                  reach_def_ins[instruction],
                                                  argument_fields)
                    state.latency += 1
                else:
                    state.area += get_header_size(reach_ins[instruction],
                                                  reach_def_ins[instruction],
                                                  argument_fields) * 2
                    state.latency += 2
            elif isinstance(instruction, I.PUSH):
                state.area += get_header_size(reach_ins[instruction],
                                              reach_def_ins[instruction],
                                              argument_fields)
                state.latency += 1
            elif isinstance(instruction, I.POP):
                state.area += get_header_size(reach_ins[instruction],
                                              reach_def_ins[instruction],
                                              argument_fields)
                state.latency += 1
            elif isinstance(instruction, I.BR):
                state.area += get_header_size(reach_ins[instruction],
                                              reach_def_ins[instruction],
                                              argument_fields)
                state.latency += 1
            elif isinstance(instruction, I.JMP):
                state.area += get_header_size(reach_ins[instruction],
                                              reach_def_ins[instruction],
                                              argument_fields)
                state.latency += 1
            elif isinstance(instruction, I.LBL):
                pass
            elif isinstance(instruction, I.LDt):
                _, _, table_type = state.tables[instruction.table_id]

                if table_type == syntax.TableTypeCollection.RAM:
                    state.area += get_header_size(reach_ins[instruction],
                                                  reach_def_ins[instruction],
                                                  argument_fields) * 3
                    state.latency += 3
                else:
                    raise RuntimeError("invalid table type (%s)." % table_type)
                    # Note:
                    # 1) tables are not added in the "area" cost as they will incur a one time cost for the
                    # whole program
                    # 2) it only operates on RAM type
            elif isinstance(instruction, I.STt):
                _, _, table_type = state.tables[instruction.table_id]

                if table_type == syntax.TableTypeCollection.RAM:
                    state.area += get_header_size(reach_ins[instruction],
                                                  reach_def_ins[instruction],
                                                  argument_fields) * 3
                    state.latency += 3
                # elif table_type == syntax.TableTypeCollection.HSH:
                # latency += 2
                elif table_type == syntax.TableTypeCollection.CAM:
                    state.area += get_header_size(reach_ins[instruction],
                                                  reach_def_ins[instruction],
                                                  argument_fields) * 4
                    state.latency += 4
                else:
                    raise RuntimeError("invalid table type (%s)." % table_type)
            elif isinstance(instruction, I.INCt):
                _, _, table_type = state.tables[instruction.table_id]
                state.area += get_header_size(reach_ins[instruction],
                                              reach_def_ins[instruction],
                                              argument_fields)

                if table_type == syntax.TableTypeCollection.RAM:
                    state.area += get_header_size(reach_ins[instruction],
                                                  reach_def_ins[instruction],
                                                  argument_fields) * 3
                    state.latency += 3
                else:
                    raise RuntimeError("invalid table type (%s)." % table_type)
            elif isinstance(instruction, I.LKt):
                _, _, table_type = state.tables[instruction.table_id]

                if table_type == syntax.TableTypeCollection.RAM:
                    state.area += get_header_size(reach_ins[instruction],
                                                  reach_def_ins[instruction],
                                                  argument_fields) * 3
                    state.latency += 3
                # elif table_type == syntax.TableTypeCollection.HSH:
                # latency += 2
                elif table_type == syntax.TableTypeCollection.CAM:
                    state.area += get_header_size(reach_ins[instruction],
                                                  reach_def_ins[instruction],
                                                  argument_fields) * 4
                    state.latency += 4
                else:
                    raise RuntimeError("invalid table type (%s)." % table_type)
            elif isinstance(instruction, I.CRC):
                state.area += get_header_size(reach_ins[instruction],
                                              reach_def_ins[instruction],
                                              argument_fields)
                state.latency += 1
            elif isinstance(instruction, I.HSH):
                state.area += get_header_size(reach_ins[instruction],
                                              reach_def_ins[instruction],
                                              argument_fields)
                state.latency += 1
            elif isinstance(instruction, I.CNC):
                for code in instruction.codes:
                    cost_Code(code, state)
            elif isinstance(instruction, I.ATM):
                cost_Code(instruction.code, state)
            elif isinstance(instruction, I.SEQ):
                cost_Code(instruction.code, state)
Exemple #6
0
def _transform(code, exclude_list):
    instructions = code.instructions

    ''' Generate flow graph '''
    flow_graph = cfg.generate(instructions)

    ''' Get reaching definitions information (for I.ADD only) '''
    reach_def_ins, reach_def_outs = rd.analyse(flow_graph, code.argument_fields,
                                               [I.LD, I.OP, I.LDt, I.LKt, I.CRC, I.HSH, I.CNC, I.ATM, I.SEQ])

    ''' Get field reachability information '''
    reach_ins, reach_outs = fr.analyse(flow_graph, code.argument_fields, exclude_list)

    ''' Cherry-pick dead instructions '''
    instruction_dict = {}
    for _, node in flow_graph.iteritems():
        for instruction in node.basic_block:
            if isinstance(instruction, I.LD):
                instruction_dict[instruction] = []
                if isinstance(instruction.source, O.Field):
                    if is_reserved_or_argument_field(instruction.source.field, code.argument_fields):
                        pass
                    elif not (instruction.source.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(
                            I.ADD(O.Field(instruction.source.field),
                                  get_field_size(reach_def_ins[instruction], instruction.source.field)))
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields):
                        pass
                    elif not (instruction.destination.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(
                            I.ADD(O.Field(instruction.destination.field),
                                  get_field_size(reach_def_ins[instruction], instruction.destination.field)))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.ST):
                instruction_dict[instruction] = []
                if isinstance(instruction.source, O.Field):
                    if is_reserved_or_argument_field(instruction.source.field, code.argument_fields):
                        pass
                    elif not (instruction.source.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(
                            I.ADD(O.Field(instruction.source.field),
                                  get_field_size(reach_def_ins[instruction], instruction.source.field)))
                if isinstance(instruction.location, O.Location):
                    if isinstance(instruction.location.location.offset, O.Field):
                        if is_reserved_or_argument_field(instruction.location.location.offset.field,
                                                         code.argument_fields):
                            pass
                        elif not (instruction.location.location.offset.field in reach_ins[instruction]):
                            instruction_dict[instruction].append(I.ADD(
                                O.Field(instruction.location.location.offset.field),
                                get_field_size(reach_def_ins[instruction], instruction.location.location.offset.field)))
                    if isinstance(instruction.location.location.length, O.Field):
                        if is_reserved_or_argument_field(instruction.location.location.length.field,
                                                         code.argument_fields):
                            pass
                        elif not (instruction.location.location.length.field in reach_ins[instruction]):
                            instruction_dict[instruction].append(I.ADD(
                                O.Field(instruction.location.location.length.field),
                                get_field_size(reach_def_ins[instruction], instruction.location.location.length.field)))
                else:
                    raise RuntimeError("invalid %s of location (%s). Should be %s."
                                       % (type(instruction.location), instruction.location, O.Location))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.OP):
                instruction_dict[instruction] = []
                if isinstance(instruction.left_source, O.Field):
                    if is_reserved_or_argument_field(instruction.left_source.field, code.argument_fields):
                        pass
                    elif not (instruction.left_source.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(I.ADD(
                            O.Field(instruction.left_source.field),
                            get_field_size(reach_def_ins[instruction], instruction.left_source.field)))
                if isinstance(instruction.right_source, O.Field):
                    if is_reserved_or_argument_field(instruction.right_source.field, code.argument_fields):
                        pass
                    elif not (instruction.right_source.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(I.ADD(
                            O.Field(instruction.right_source.field),
                            get_field_size(reach_def_ins[instruction], instruction.right_source.field)))
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields):
                        pass
                    elif not (instruction.destination.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(I.ADD(
                            O.Field(instruction.destination.field),
                            get_field_size(reach_def_ins[instruction], instruction.destination.field)))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.PUSH):
                instruction_dict[instruction] = []
                if isinstance(instruction.location, O.Location):
                    if isinstance(instruction.location.location.offset, O.Field):
                        if is_reserved_or_argument_field(instruction.location.location.offset.field,
                                                         code.argument_fields):
                            pass
                        elif not (instruction.location.location.offset.field in reach_ins[instruction]):
                            instruction_dict[instruction].append(I.ADD(
                                O.Field(instruction.location.location.offset.field),
                                get_field_size(reach_def_ins[instruction], instruction.location.location.offset.field)))
                    if isinstance(instruction.location.location.length, O.Field):
                        if is_reserved_or_argument_field(instruction.location.location.length.field,
                                                         code.argument_fields):
                            pass
                        elif not (instruction.location.location.length.field in reach_ins[instruction]):
                            instruction_dict[instruction].append(I.ADD(
                                O.Field(instruction.location.location.length.field),
                                get_field_size(reach_def_ins[instruction], instruction.location.location.length.field)))
                else:
                    raise RuntimeError("invalid %s of location (%s). Should be %s."
                                       % (type(instruction.location), instruction.location, O.Location))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.POP):
                instruction_dict[instruction] = []
                if isinstance(instruction.location, O.Location):
                    if isinstance(instruction.location.location.offset, O.Field):
                        if is_reserved_or_argument_field(instruction.location.location.offset.field,
                                                         code.argument_fields):
                            pass
                        elif not (instruction.location.location.offset.field in reach_ins[instruction]):
                            instruction_dict[instruction].append(I.ADD(
                                O.Field(instruction.location.location.offset.field),
                                get_field_size(reach_def_ins[instruction], instruction.location.location.offset.field)))
                    if isinstance(instruction.location.location.length, O.Field):
                        if is_reserved_or_argument_field(instruction.location.location.length.field,
                                                         code.argument_fields):
                            pass
                        elif not (instruction.location.location.length.field in reach_ins[instruction]):
                            instruction_dict[instruction].append(I.ADD(
                                O.Field(instruction.location.location.length.field),
                                get_field_size(reach_def_ins[instruction], instruction.location.location.length.field)))
                else:
                    raise RuntimeError("invalid %s of location (%s). Should be %s."
                                       % (type(instruction.location), instruction.location, O.Location))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.BR):
                instruction_dict[instruction] = []
                if isinstance(instruction.left_source, O.Field):
                    if is_reserved_or_argument_field(instruction.left_source.field, code.argument_fields):
                        pass
                    elif not (instruction.left_source.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(I.ADD(
                            O.Field(instruction.left_source.field),
                            get_field_size(reach_def_ins[instruction], instruction.left_source.field)))
                if isinstance(instruction.right_source, O.Field):
                    if is_reserved_or_argument_field(instruction.right_source.field, code.argument_fields):
                        pass
                    elif not (instruction.right_source.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(I.ADD(
                            O.Field(instruction.right_source.field),
                            get_field_size(reach_def_ins[instruction], instruction.right_source.field)))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.LDt):
                instruction_dict[instruction] = []
                if isinstance(instruction.index, O.Field):
                    if is_reserved_or_argument_field(instruction.index.field, code.argument_fields):
                        pass
                    elif not (instruction.index.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(I.ADD(
                            O.Field(instruction.index.field),
                            get_field_size(reach_def_ins[instruction], instruction.index.field)))
                if isinstance(instruction.destinations, O.Operands__):
                    for operand in instruction.destinations:
                        if isinstance(operand, O.Field):
                            if is_reserved_or_argument_field(operand.field, code.argument_fields):
                                pass
                            elif not (operand.field in reach_ins[instruction]):
                                instruction_dict[instruction].append(I.ADD(
                                    O.Field(operand.field),
                                    get_field_size(reach_def_ins[instruction], operand.field)))
                else:
                    raise RuntimeError("invalid %s of destinations (%s). Should be %s."
                                       % (type(instruction.destinations), instruction.destinations, O.Operands__))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.STt):
                instruction_dict[instruction] = []
                if isinstance(instruction.index, O.Field):
                    if is_reserved_or_argument_field(instruction.index.field, code.argument_fields):
                        pass
                    elif not (instruction.index.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(I.ADD(
                            O.Field(instruction.index.field),
                            get_field_size(reach_def_ins[instruction], instruction.index.field)))
                if isinstance(instruction.sources, O.Operands_):
                    for operand in instruction.sources:
                        if isinstance(operand, O.Field):
                            if is_reserved_or_argument_field(operand.field, code.argument_fields):
                                pass
                            elif not (operand.field in reach_ins[instruction]):
                                instruction_dict[instruction].append(I.ADD(
                                    O.Field(operand.field),
                                    get_field_size(reach_def_ins[instruction], operand.field)))
                elif isinstance(instruction.sources, O.OperandsMasks_):
                    for operand, _ in instruction.sources:
                        if isinstance(operand, O.Field):
                            if is_reserved_or_argument_field(operand.field, code.argument_fields):
                                pass
                            elif not (operand.field in reach_ins[instruction]):
                                instruction_dict[instruction].append(I.ADD(
                                    O.Field(operand.field),
                                    get_field_size(reach_def_ins[instruction], operand.field)))
                else:
                    raise RuntimeError("invalid %s of sources (%s). Should be %s or %s."
                                       % (type(instruction.sources), instruction.sources,
                                          O.Operands_, O.OperandsMasks_))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.INCt):
                instruction_dict[instruction] = []
                if isinstance(instruction.index, O.Field):
                    if is_reserved_or_argument_field(instruction.index.field, code.argument_fields):
                        pass
                    elif not (instruction.index.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(I.ADD(
                            O.Field(instruction.index.field),
                            get_field_size(reach_def_ins[instruction], instruction.index.field)))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.LKt):
                instruction_dict[instruction] = []
                if isinstance(instruction.sources, O.Operands_):
                    for operand in instruction.sources:
                        if isinstance(operand, O.Field):
                            if is_reserved_or_argument_field(operand.field, code.argument_fields):
                                pass
                            elif not (operand.field in reach_ins[instruction]):
                                instruction_dict[instruction].append(I.ADD(
                                    O.Field(operand.field),
                                    get_field_size(reach_def_ins[instruction], operand.field)))
                else:
                    raise RuntimeError("invalid %s of sources (%s). Should be %s."
                                       % (type(instruction.sources), instruction.sources, O.Operands_))
                if isinstance(instruction.index, O.Field):
                    if is_reserved_or_argument_field(instruction.index.field, code.argument_fields):
                        pass
                    elif not (instruction.index.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(I.ADD(
                            O.Field(instruction.index.field),
                            get_field_size(reach_def_ins[instruction], instruction.index.field)))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.CRC):
                instruction_dict[instruction] = []
                if isinstance(instruction.sources, O.Operands_):
                    for operand in instruction.sources:
                        if isinstance(operand, O.Field):
                            if is_reserved_or_argument_field(operand.field, code.argument_fields):
                                pass
                            elif not (operand.field in reach_ins[instruction]):
                                instruction_dict[instruction].append(I.ADD(
                                    O.Field(operand.field),
                                    get_field_size(reach_def_ins[instruction], operand.field)))
                else:
                    raise RuntimeError("invalid %s of sources (%s). Should be %s."
                                       % (type(instruction.sources), instruction.sources, O.Operands_))
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields):
                        pass
                    elif not (instruction.destination.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(I.ADD(
                            O.Field(instruction.destination.field),
                            get_field_size(reach_def_ins[instruction], instruction.destination.field)))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.HSH):
                instruction_dict[instruction] = []
                if isinstance(instruction.sources, O.Operands_):
                    for operand in instruction.sources:
                        if isinstance(operand, O.Field):
                            if is_reserved_or_argument_field(operand.field, code.argument_fields):
                                pass
                            elif not (operand.field in reach_ins[instruction]):
                                instruction_dict[instruction].append(I.ADD(
                                    O.Field(operand.field),
                                    get_field_size(reach_def_ins[instruction], operand.field)))
                else:
                    raise RuntimeError("invalid %s of sources (%s). Should be %s."
                                       % (type(instruction.sources), instruction.sources, O.Operands_))
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields):
                        pass
                    elif not (instruction.destination.field in reach_ins[instruction]):
                        instruction_dict[instruction].append(I.ADD(
                            O.Field(instruction.destination.field),
                            get_field_size(reach_def_ins[instruction], instruction.destination.field)))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.CNC):
                instruction_dict[instruction] = []
                if isinstance(instruction.codes, I.Codes):
                    for _code in instruction.codes:
                        for field in _code.argument_fields:
                            if is_reserved_or_argument_field(field, code.argument_fields):
                                pass
                            elif not (field in reach_ins[instruction]):
                                instruction_dict[instruction].append(I.ADD(
                                    O.Field(field),
                                    get_field_size(reach_def_ins[instruction], field)))
                else:
                    raise RuntimeError("invalid %s of codes (%s). Should be %s."
                                       % (type(instruction.codes), instruction.codes, I.Codes))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.ATM):
                instruction_dict[instruction] = []
                if isinstance(instruction.code, I.Code):
                    for field in instruction.code.argument_fields:
                        if is_reserved_or_argument_field(field, code.argument_fields):
                            pass
                        elif not (field in reach_ins[instruction]):
                            instruction_dict[instruction].append(I.ADD(
                                O.Field(field),
                                get_field_size(reach_def_ins[instruction], field)))
                else:
                    raise RuntimeError("invalid %s of code (%s). Should be %s."
                                       % (type(instruction.code), instruction.code, I.Code))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]
            elif isinstance(instruction, I.SEQ):
                instruction_dict[instruction] = []
                if isinstance(instruction.code, I.Code):
                    for field in instruction.code.argument_fields:
                        if is_reserved_or_argument_field(field, code.argument_fields):
                            pass
                        elif not (field in reach_ins[instruction]):
                            instruction_dict[instruction].append(I.ADD(
                                O.Field(field),
                                get_field_size(reach_def_ins[instruction], field)))
                else:
                    raise RuntimeError("invalid %s of sources (%s). Should be %s."
                                       % (type(instruction.code), instruction.code, I.Code))
                if not instruction_dict[instruction]:
                    del instruction_dict[instruction]

    ''' Add new add instructions in the code '''
    for instruction, _instructions in instruction_dict.iteritems():
        index = instructions.index(instruction)
        for i in range(0, len(_instructions)):
            instructions.insert(index + i, _instructions[i])
    def _setup(self):
        flow_graph = cfg.generate(self.instructions)

        ''' Setting connections with in basic blocks '''
        for label, node in flow_graph.iteritems():
            if label == syntax.Label('$entry') or label == syntax.Label('$exit'):
                continue
            next_instruction = None
            for instruction in node.basic_block[::-1]:
                if (isinstance(instruction, I.ATM) or isinstance(instruction, I.SEQ) or
                        isinstance(instruction, I.CNC)):
                    self._instructions[instruction] = GroupProcess(instruction, self.tables)
                else:
                    self._instructions[instruction] = PrimitiveProcess(instruction)

                if next_instruction:
                    self._instructions[instruction].output_interfaces[syntax.Label('')] = \
                        self._instructions[next_instruction].input_interface

                next_instruction = instruction

        ''' Setting up connections across basic blocks '''
        for label, node in flow_graph.iteritems():
            last_instruction = node.basic_block[-1]
            for successor_label in node.successors:
                first_instruction = flow_graph[successor_label].basic_block[0]

                if label == syntax.Label('$entry'):
                    # if successor_label == Label('$exit'):
                    # self.input_interface = self.output_interface
                    # else:
                    self._input_interface = self._instructions[first_instruction].input_interface
                    # Note: this should always be no more than one
                else:
                    if successor_label == syntax.Label('$exit'):
                        self._instructions[last_instruction].output_interfaces[
                            syntax.Label('')] = self._output_interface
                    else:
                        if isinstance(last_instruction, I.BR) or isinstance(last_instruction, I.JMP):
                            if last_instruction.label == successor_label:
                                self._instructions[last_instruction].output_interfaces[last_instruction.label] = \
                                    self._instructions[first_instruction].input_interface
                            else:
                                self._instructions[last_instruction].output_interfaces[syntax.Label('')] = \
                                    self._instructions[first_instruction].input_interface
                        else:
                            self._instructions[last_instruction].output_interfaces[syntax.Label('')] = \
                                self._instructions[first_instruction].input_interface

        ''' Connect tables with instructions '''
        for instruction in self._instructions:
            if isinstance(instruction, I.LDt):
                table = self.tables[instruction.table_id]
                self._instructions[instruction].table_interface.output_interface = table.input_interface
                table.output_interfaces[id(instruction)] = \
                    self._instructions[instruction].table_interface.input_interface
            elif isinstance(instruction, I.STt):
                table = self.tables[instruction.table_id]
                self._instructions[instruction].table_interface.output_interface = table.input_interface
                table.output_interfaces[id(instruction)] = \
                    self._instructions[instruction].table_interface.input_interface
            elif isinstance(instruction, I.INCt):
                table = self.tables[instruction.table_id]
                self._instructions[instruction].table_interface.output_interface = table.input_interface
                table.output_interfaces[id(instruction)] = \
                    self._instructions[instruction].table_interface.input_interface
            elif isinstance(instruction, I.LKt):
                table = self.tables[instruction.table_id]
                self._instructions[instruction].table_interface.output_interface = table.input_interface
                table.output_interfaces[id(instruction)] = \
                    self._instructions[instruction].table_interface.input_interface

        self._is_setup = True
def _phase_0(code):
    instructions = code.instructions
    ''' Generate flow graph '''
    flow_graph = cfg.generate(instructions)
    ''' Get liveness information '''
    live_ins, live_outs = li.analyse(flow_graph, code.argument_fields,
                                     [I.ADD, I.RMV])
    ''' Cherry-pick dead instructions '''
    instruction_list = []
    for _, node in flow_graph.iteritems():
        for instruction in node.basic_block:
            # I.ID
            # I.DRP
            # I.CTR
            # I.ADD
            # I.RMV
            if isinstance(instruction, I.LD):
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(
                            instruction.destination.field,
                            code.argument_fields):
                        pass
                    elif not (instruction.destination.field
                              in live_outs[instruction]):
                        instruction_list.append(instruction)
            # I.ST
            elif isinstance(instruction, I.OP):
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(
                            instruction.destination.field,
                            code.argument_fields):
                        pass
                    elif not (instruction.destination.field
                              in live_outs[instruction]):
                        instruction_list.append(instruction)
            # I.PUSH
            # I.POP
            # I.BR
            # I.JMP
            # I.LBL
            elif isinstance(instruction, I.LDt):
                check_list = []
                for destination in instruction.destinations:
                    if isinstance(destination, O.Field):
                        if is_reserved_or_argument_field(
                                destination.field, code.argument_fields):
                            check_list.append(False)
                        else:
                            check_list.append(True if not (
                                destination.field in live_outs[instruction]
                            ) else False)
                if check_list and all(check_list):
                    instruction_list.append(instruction)
            # I.STt
            # I.INCt
            elif isinstance(instruction, I.LKt):
                if isinstance(instruction.index, O.Field):
                    if is_reserved_or_argument_field(instruction.index.field,
                                                     code.argument_fields):
                        pass
                    elif not (instruction.index.field
                              in live_outs[instruction]):
                        instruction_list.append(instruction)
            elif isinstance(instruction, I.CRC):
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(
                            instruction.destination.field,
                            code.argument_fields):
                        pass
                    elif not (instruction.destination.field
                              in live_outs[instruction]):
                        instruction_list.append(instruction)
            elif isinstance(instruction, I.HSH):
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(
                            instruction.destination.field,
                            code.argument_fields):
                        pass
                    elif not (instruction.destination.field
                              in live_outs[instruction]):
                        instruction_list.append(instruction)
            # I.HLT
            # I.CNC
            # I.ATM
            # I.SEQ

            # TODO: add support for group instructions, above.
    ''' Remove dead instructions from the code '''
    for instruction in instruction_list:
        instructions.remove(instruction)
                O.Value(Value(1, Size(16))),
            ), I.JMP(Label('LBL_0')), I.LBL(Label('LBL_HLT')),
            I.LD(O.Field(Field('outport_bitmap')), O.Field(Field('reg0'))),
            I.HLT()))

    return Policy(decls, code)


# Testing
if __name__ == "__main__":
    policy = main()

    # CFG
    if False:
        import netasm.netasm.core.graphs.control_flow_graph as cfg
        graph = cfg.generate(policy.code.instructions)
        print graph

    # Cost
    if False:
        from netasm.netasm import cost
        area, latency = cost.cost_Policy(policy)
        print area, latency

    # Execute
    if True:
        from netasm.netasm import execute

        policy = execute.Execute(policy)

        state = execute.State(execute.Header(), execute.Packet(1000))
def _phase_0(code):
    instructions = code.instructions

    """ Generate flow graph """
    flow_graph = cfg.generate(instructions)

    """ Get liveness information """
    live_ins, live_outs = li.analyse(flow_graph, code.argument_fields, [I.ADD, I.RMV])

    """ Cherry-pick dead instructions """
    instruction_list = []
    for _, node in flow_graph.iteritems():
        for instruction in node.basic_block:
            # I.ID
            # I.DRP
            # I.CTR
            # I.ADD
            # I.RMV
            if isinstance(instruction, I.LD):
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields):
                        pass
                    elif not (instruction.destination.field in live_outs[instruction]):
                        instruction_list.append(instruction)
            # I.ST
            elif isinstance(instruction, I.OP):
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields):
                        pass
                    elif not (instruction.destination.field in live_outs[instruction]):
                        instruction_list.append(instruction)
            # I.PUSH
            # I.POP
            # I.BR
            # I.JMP
            # I.LBL
            elif isinstance(instruction, I.LDt):
                check_list = []
                for destination in instruction.destinations:
                    if isinstance(destination, O.Field):
                        if is_reserved_or_argument_field(destination.field, code.argument_fields):
                            check_list.append(False)
                        else:
                            check_list.append(True if not (destination.field in live_outs[instruction]) else False)
                if check_list and all(check_list):
                    instruction_list.append(instruction)
            # I.STt
            # I.INCt
            elif isinstance(instruction, I.LKt):
                if isinstance(instruction.index, O.Field):
                    if is_reserved_or_argument_field(instruction.index.field, code.argument_fields):
                        pass
                    elif not (instruction.index.field in live_outs[instruction]):
                        instruction_list.append(instruction)
            elif isinstance(instruction, I.CRC):
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields):
                        pass
                    elif not (instruction.destination.field in live_outs[instruction]):
                        instruction_list.append(instruction)
            elif isinstance(instruction, I.HSH):
                if isinstance(instruction.destination, O.Field):
                    if is_reserved_or_argument_field(instruction.destination.field, code.argument_fields):
                        pass
                    elif not (instruction.destination.field in live_outs[instruction]):
                        instruction_list.append(instruction)
            # I.HLT
            # I.CNC
            # I.ATM
            # I.SEQ

            # TODO: add support for group instructions, above.

    """ Remove dead instructions from the code """
    for instruction in instruction_list:
        instructions.remove(instruction)