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 2

Go to most recent revision | 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
  """Remove functions that are not called"""
8
 
9
 
10
  #This is an iterative processr. Once a function is removed,
11
  #there may be more unused functions
12
  while 1:
13
 
14
      #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
 
21
      #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
 
34
      if len(instructions) == len(kept_instructions):
35
          return kept_instructions
36
      instructions = kept_instructions
37
 
38
def reallocate_registers(instructions, registers):
39
 
40
    register_map = {}
41
    new_registers = {}
42
    n = 0
43
    for register, definition in registers.iteritems():
44
      register_map[register] = n
45
      new_registers[n] = definition
46
      n+=1
47
 
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
  def modifies_register(instruction):
88
 
89
    """Return the register modified by this instruction if any"""
90
 
91
    if "dest" in instruction:
92
      return instruction["dest"]
93
    return None
94
 
95
  def uses_registers(instruction):
96
 
97
    """Return the registers used by this instruction if any"""
98
 
99
    registers = []
100
    for field in ["src", "srcb"]:
101
      if field in instruction:
102
        registers.append(instruction[field])
103
    return registers
104
 
105
  def memory_clash(a, b):
106
 
107
    """do instructions result in a memory clash"""
108
 
109
    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
 
112
    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
 
115
    if a["op"] in ["memory_read", "memory_read_wait", "memory_read_request", "memory_write", "memory_write_literal"]:
116
        return b["op"] == a["op"]
117
 
118
    if b["op"] in ["memory_read", "memory_read_wait", "memory_read_request", "memory_write", "memory_write_literal"]:
119
        return b["op"] == a["op"]
120
 
121
  def is_part_of_read(a, b):
122
 
123
    """requests, waits and reads with the same sequence number must not be concurrent"""
124
 
125
    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
 
130
  def is_solitary(instruction):
131
 
132
    """Return True if an instruction cannot be executed in parallel with other instructions"""
133
 
134
    return instruction["op"] in ["read", "write", "ready", "label", "/", "%"]
135
 
136
  def is_jump(instruction):
137
 
138
    """Return True if an instruction contains a branch or jump"""
139
 
140
    return instruction["op"] in ["goto", "jmp_if_true", "jmp_if_false", "jmp_and_link",
141
                                 "jmp_to_reg"]
142
 
143
  def is_dependent(instruction, frame, preceding):
144
 
145
    """determine whether an instruction is dependent on the outcome of:
146
    - an instruction within the current frame
147
    - preceding instructions not within the frame """
148
 
149
    for i in frame + preceding:
150
      if modifies_register(i) is not None:
151
        if modifies_register(i) in uses_registers(instruction):
152
          return True
153
        if modifies_register(i) == modifies_register(instruction):
154
          return True
155
      if memory_clash(i, instruction):
156
          return True
157
      if is_part_of_read(i, instruction):
158
          return True
159
      if is_jump(i):
160
        return True
161
    for i in preceding:
162
      if modifies_register(instruction) is not None:
163
        if modifies_register(instruction) in uses_registers(i):
164
          return True
165
      if memory_clash(i, instruction):
166
          return True
167
      if is_part_of_read(i, instruction):
168
          return True
169
    if is_jump(instruction) and preceding:
170
      return True
171
    return False
172
 
173
  def add_instructions(frame, instructions):
174
 
175
    """Add more instructions to the current frame if dependencies allow."""
176
 
177
    instructions_added = True
178
    while instructions_added:
179
      instructions_added = False
180
      for index, instruction in enumerate(instructions):
181
        if is_solitary(instruction):
182
          return
183
        for i in frame:
184
          if is_jump(i):
185
            return
186
          if is_solitary(i):
187
            return
188
        if not is_dependent(instruction, frame, instructions[:index]):
189
          frame.append(instructions.pop(index))
190
          instructions_added = True
191
          break
192
 
193
  frames = []
194
  while instructions:
195
    frame = [instructions.pop(0)]
196
    add_instructions(frame, instructions)
197
    frames.append(frame)
198
 
199
  return frames

powered by: WebSVN 2.1.0

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