OpenCores
URL https://opencores.org/ocsvn/tcp_socket/tcp_socket/trunk

Subversion Repositories tcp_socket

[/] [tcp_socket/] [trunk/] [chips2/] [chips/] [compiler/] [optimizer.py] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jondawson
__author__ = "Jon Dawson"
2
__copyright__ = "Copyright (C) 2012, Jonathan P Dawson"
3
__version__ = "0.1"
4
 
5
def cleanup_functions(instructions):
6
 
7 4 jondawson
    """Remove functions that are not called"""
8 2 jondawson
 
9
 
10 4 jondawson
    #This is an iterative processr. Once a function is removed,
11
    #there may be more unused functions
12
    while 1:
13 2 jondawson
 
14 4 jondawson
        #find function calls
15
        live_functions = {}
16
        for instruction in instructions:
17
            if instruction["op"] == "jmp_and_link":
18
                if instruction["label"].startswith("function"):
19
                    live_functions[instruction["label"]] = None
20 2 jondawson
 
21 4 jondawson
        #remove instructions without function calls
22
        kept_instructions = []
23
        generate_on = True
24
        for instruction in instructions:
25
            if instruction["op"] == "label":
26
                if instruction["label"].startswith("function"):
27
                    if instruction["label"] in live_functions:
28
                        generate_on = True
29
                    else:
30
                        generate_on = False
31
            if generate_on:
32
                kept_instructions.append(instruction)
33 2 jondawson
 
34 4 jondawson
        if len(instructions) == len(kept_instructions):
35
            return kept_instructions
36
        instructions = kept_instructions
37 2 jondawson
 
38
def reallocate_registers(instructions, registers):
39
 
40
    register_map = {}
41
    new_registers = {}
42
    n = 0
43
    for register, definition in registers.iteritems():
44 4 jondawson
        register_map[register] = n
45
        new_registers[n] = definition
46
        n+=1
47 2 jondawson
 
48
    for instruction in instructions:
49
        if "dest" in instruction:
50
            instruction["dest"] = register_map[instruction["dest"]]
51
        if "src" in instruction:
52
            instruction["src"] = register_map[instruction["src"]]
53
        if "srcb" in instruction:
54
            instruction["srcb"] = register_map[instruction["srcb"]]
55
 
56
    return instructions, new_registers
57
 
58
def cleanup_registers(instructions, registers):
59
 
60
    #find all the registers that are read from.
61
    used_registers = {}
62
    for instruction in instructions:
63
        if "src" in instruction:
64
            used_registers[instruction["src"]] = None
65
        if "srcb" in instruction:
66
            used_registers[instruction["srcb"]] = None
67
 
68
    #remove them from the list of allocated registers
69
    kept_registers = {}
70
    for register, description in registers.iteritems():
71
        if register in used_registers:
72
            kept_registers[register] = description
73
 
74
    #remove all instructions that read from unused registers
75
    kept_instructions = []
76
    for instruction in instructions:
77
        if "dest" in instruction:
78
            if instruction["dest"] in kept_registers:
79
                kept_instructions.append(instruction)
80
        else:
81
            kept_instructions.append(instruction)
82
 
83
    return reallocate_registers(kept_instructions, kept_registers)
84
 
85
def parallelise(instructions):
86
 
87 4 jondawson
    def modifies_register(instruction):
88 2 jondawson
 
89 4 jondawson
        """Return the register modified by this instruction if any"""
90 2 jondawson
 
91 4 jondawson
        if "dest" in instruction:
92
            return instruction["dest"]
93
        return None
94 2 jondawson
 
95 4 jondawson
    def uses_registers(instruction):
96 2 jondawson
 
97 4 jondawson
        """Return the registers used by this instruction if any"""
98 2 jondawson
 
99 4 jondawson
        registers = []
100
        for field in ["src", "srcb"]:
101
            if field in instruction:
102
                registers.append(instruction[field])
103
        return registers
104 2 jondawson
 
105 4 jondawson
    def memory_clash(a, b):
106 2 jondawson
 
107 4 jondawson
        """do instructions result in a memory clash"""
108 2 jondawson
 
109 4 jondawson
        if a["op"] in ["memory_write", "memory_write_literal"]:
110
            return b["op"] in ["memory_write", "memory_write_literal", "memory_read", "memory_read_wait", "memory_read_request"]
111 2 jondawson
 
112 4 jondawson
        if b["op"] in ["memory_write", "memory_write_literal"]:
113
            return a["op"] in ["memory_write", "memory_write_literal", "memory_read", "memory_read_wait", "memory_read_request"]
114 2 jondawson
 
115 4 jondawson
        if a["op"] in ["memory_read", "memory_read_wait", "memory_read_request", "memory_write", "memory_write_literal"]:
116
            return b["op"] == a["op"]
117 2 jondawson
 
118 4 jondawson
        if b["op"] in ["memory_read", "memory_read_wait", "memory_read_request", "memory_write", "memory_write_literal"]:
119
            return b["op"] == a["op"]
120 2 jondawson
 
121 4 jondawson
    def is_part_of_read(a, b):
122 2 jondawson
 
123 4 jondawson
        """requests, waits and reads with the same sequence number must not be concurrent"""
124 2 jondawson
 
125 4 jondawson
        read_instructions = ["memory_read_request", "memory_read_wait", "memory_read"]
126
        if (a["op"] in read_instructions) and (b["op"] in read_instructions):
127
            return a["sequence"] == b["sequence"]
128
        return False
129 2 jondawson
 
130 4 jondawson
    def is_solitary(instruction):
131 2 jondawson
 
132 4 jondawson
        """Return True if an instruction cannot be executed in parallel with other instructions"""
133 2 jondawson
 
134 4 jondawson
        if "type" in instruction and instruction["type"] == "float":
135
            if instruction["op"] in ["+", "-", "/", "*"]:
136
                return True
137
        return instruction["op"] in ["read", "write", "ready", "label", "/", "%", "int_to_float", "float_to_int", "file_write", "file_read"]
138 2 jondawson
 
139 4 jondawson
    def is_jump(instruction):
140 2 jondawson
 
141 4 jondawson
        """Return True if an instruction contains a branch or jump"""
142 2 jondawson
 
143 4 jondawson
        return instruction["op"] in ["goto", "jmp_if_true", "jmp_if_false", "jmp_and_link",
144
                                     "jmp_to_reg"]
145 2 jondawson
 
146 4 jondawson
    def is_dependent(instruction, frame, preceding):
147 2 jondawson
 
148 4 jondawson
        """determine whether an instruction is dependent on the outcome of:
149
        - an instruction within the current frame
150
        - preceding instructions not within the frame """
151 2 jondawson
 
152 4 jondawson
        for i in frame + preceding:
153
            if modifies_register(i) is not None:
154
                if modifies_register(i) in uses_registers(instruction):
155
                    return True
156
                if modifies_register(i) == modifies_register(instruction):
157
                    return True
158
            if memory_clash(i, instruction):
159
                return True
160
            if is_part_of_read(i, instruction):
161
                return True
162
            if is_jump(i):
163
                return True
164
        for i in preceding:
165
            if modifies_register(instruction) is not None:
166
                if modifies_register(instruction) in uses_registers(i):
167
                    return True
168
            if memory_clash(i, instruction):
169
                return True
170
            if is_part_of_read(i, instruction):
171
                return True
172
        if is_jump(instruction) and preceding:
173
            return True
174
        return False
175 2 jondawson
 
176 4 jondawson
    def add_instructions(frame, instructions):
177 2 jondawson
 
178 4 jondawson
        """Add more instructions to the current frame if dependencies allow."""
179 2 jondawson
 
180 4 jondawson
        instructions_added = True
181
        while instructions_added:
182
            instructions_added = False
183
            for index, instruction in enumerate(instructions):
184
                if is_solitary(instruction):
185
                    return
186
                for i in frame:
187
                    if is_jump(i):
188
                        return
189
                    if is_solitary(i):
190
                        return
191
                if not is_dependent(instruction, frame, instructions[:index]):
192
                    frame.append(instructions.pop(index))
193
                    instructions_added = True
194
                    break
195 2 jondawson
 
196 4 jondawson
    frames = []
197
    while instructions:
198
        frame = [instructions.pop(0)]
199
        add_instructions(frame, instructions)
200
        frames.append(frame)
201 2 jondawson
 
202 4 jondawson
    return frames

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.