Jelajahi Sumber

Added comment').

Taddeus Kroes 14 tahun lalu
induk
melakukan
86b4d42889
3 mengubah file dengan 47 tambahan dan 16 penghapusan
  1. 12 2
      src/program.py
  2. 26 12
      src/statement.py
  3. 9 2
      src/writer.py

+ 12 - 2
src/program.py

@@ -1,13 +1,16 @@
 from statement import Statement as S, Block
 from statement import Statement as S, Block
 from dataflow import find_basic_blocks, generate_flow_graph
 from dataflow import find_basic_blocks, generate_flow_graph
+
 from optimize.redundancies import remove_redundant_jumps, remove_redundancies,\
 from optimize.redundancies import remove_redundant_jumps, remove_redundancies,\
         remove_redundant_branch_jumps
         remove_redundant_branch_jumps
 from optimize.advanced import eliminate_common_subexpressions, \
 from optimize.advanced import eliminate_common_subexpressions, \
         fold_constants, copy_propagation, eliminate_dead_code
         fold_constants, copy_propagation, eliminate_dead_code
-from writer import write_statements
+
 import liveness
 import liveness
 import reaching_definitions
 import reaching_definitions
 
 
+from writer import write_statements
+
 
 
 class Program(Block):
 class Program(Block):
     def __len__(self):
     def __len__(self):
@@ -30,6 +33,9 @@ class Program(Block):
                 message = ' Block %d (%d statements), edges from: %s' \
                 message = ' Block %d (%d statements), edges from: %s' \
                           % (b.bid, len(b), map(get_id, b.edges_from))
                           % (b.bid, len(b), map(get_id, b.edges_from))
 
 
+                if hasattr(b, 'copy_in'):
+                    message += ', COPY_in: %s' % list(b.copy_in)
+
                 if hasattr(b, 'live_in'):
                 if hasattr(b, 'live_in'):
                     message += ', LIVE_in: %s' % list(b.live_in)
                     message += ', LIVE_in: %s' % list(b.live_in)
 
 
@@ -43,6 +49,9 @@ class Program(Block):
                 message = ' End of block %d, edges to: %s' \
                 message = ' End of block %d, edges to: %s' \
                           % (b.bid, map(get_id, b.edges_to))
                           % (b.bid, map(get_id, b.edges_to))
 
 
+                if hasattr(b, 'copy_out'):
+                    message += ', COPY_out: %s' % list(b.copy_out)
+
                 if hasattr(b, 'live_out'):
                 if hasattr(b, 'live_out'):
                     message += ', LIVE_out: %s' % list(b.live_out)
                     message += ', LIVE_out: %s' % list(b.live_out)
 
 
@@ -108,5 +117,6 @@ class Program(Block):
     def save(self, filename):
     def save(self, filename):
         """Save the program in the specified file."""
         """Save the program in the specified file."""
         f = open(filename, 'w+')
         f = open(filename, 'w+')
-        f.write(write_statements(self.get_statements(True)))
+        f.write(write_statements(self.get_statements(True),
+                verbose=self.verbose))
         f.close()
         f.close()

+ 26 - 12
src/statement.py

@@ -38,6 +38,9 @@ class Statement:
     def __repr__(self):  # pragma: nocover
     def __repr__(self):  # pragma: nocover
         return str(self)
         return str(self)
 
 
+    def set_message(self, message):
+        self.options['message'] = message
+
     def set_inline_comment(self, comment):
     def set_inline_comment(self, comment):
         self.options['comment'] = comment
         self.options['comment'] = comment
 
 
@@ -169,15 +172,17 @@ class Statement:
 
 
         return defined
         return defined
 
 
-    def get_use(self):
+    def get_use(self, as_items=False):
         """Get the variables that this statement uses, if any."""
         """Get the variables that this statement uses, if any."""
         instr = ['addu', 'subu', 'mult', 'div', 'move', 'mov.d', \
         instr = ['addu', 'subu', 'mult', 'div', 'move', 'mov.d', \
             'dmfc1', 'div.s']
             'dmfc1', 'div.s']
         use = set()
         use = set()
+        indices = []
 
 
         # Jump to register addres uses register
         # Jump to register addres uses register
         if self.is_command('j') and re.match('^\$\d+$', self[0]):
         if self.is_command('j') and re.match('^\$\d+$', self[0]):
             use.add(self[0])
             use.add(self[0])
+            indices.append(0)
 
 
         # Case arg0
         # Case arg0
         if (self.is_branch() \
         if (self.is_branch() \
@@ -189,8 +194,10 @@ class Statement:
 
 
                 if m:
                 if m:
                     use.add(m.group(1))
                     use.add(m.group(1))
+                    indices.append(0)
             else:
             else:
                 use.add(self[0])
                 use.add(self[0])
+                indices.append(0)
 
 
         if (self.is_branch() and not self.is_branch_zero() \
         if (self.is_branch() and not self.is_branch_zero() \
                 and not self.is_command('bc1f', 'bc1t', 'bct', 'bcf')) \
                 and not self.is_command('bc1f', 'bc1t', 'bct', 'bcf')) \
@@ -201,23 +208,27 @@ class Statement:
                 or self.is_compare() or self.is_command(*instr):
                 or self.is_compare() or self.is_command(*instr):
             # Case arg1 direct adressing
             # Case arg1 direct adressing
             use.add(self[1])
             use.add(self[1])
+            indices.append(1)
         elif self.is_load_non_immediate() or self.is_store():
         elif self.is_load_non_immediate() or self.is_store():
             # Case arg1 relative adressing
             # Case arg1 relative adressing
             m = re.match('^[^(]+\(([^)]+)\)$', self[1])
             m = re.match('^[^(]+\(([^)]+)\)$', self[1])
 
 
             if m:
             if m:
                 use.add(m.group(1))
                 use.add(m.group(1))
+                indices.append(1)
             elif not re.match('^\$LC\d+$', self[1]):
             elif not re.match('^\$LC\d+$', self[1]):
                 use.add(self[1])
                 use.add(self[1])
+                indices.append(1)
 
 
         # Case arg2
         # Case arg2
-        if self.is_double_arithmetic() or self.is_set_if_less() \
+        if (self.is_double_arithmetic() or self.is_set_if_less() \
                 or self.is_logical() or self.is_truncate() \
                 or self.is_logical() or self.is_truncate() \
-                or self.is_command('addu', 'subu', 'div'):
-            if not isinstance(self[2], int):
-                    use.add(self[2])
+                or self.is_command('addu', 'subu', 'div')) \
+                and not isinstance(self[2], int):
+            use.add(self[2])
+            indices.append(2)
 
 
-        return use
+        return zip(indices, use) if as_items else use
 
 
     def defines(self, reg):
     def defines(self, reg):
         """Check if this statement defines the given register."""
         """Check if this statement defines the given register."""
@@ -227,6 +238,11 @@ class Statement:
         """Check if this statement uses the given register."""
         """Check if this statement uses the given register."""
         return reg in self.get_use()
         return reg in self.get_use()
 
 
+    def replace_usage(self, x, y):
+        """Replace the uses of register x by y."""
+        for i, arg in enumerate(self):
+            self[i] = re.sub('\\' + x + '(?!\d)', y, str(arg))
+
 
 
 class Block:
 class Block:
     bid = 1
     bid = 1
@@ -256,7 +272,7 @@ class Block:
     def __len__(self):
     def __len__(self):
         return len(self.statements)
         return len(self.statements)
 
 
-    def read(self, count=1):
+    def read(self):
         """Read the statement at the current pointer position and move the
         """Read the statement at the current pointer position and move the
         pointer one position to the right."""
         pointer one position to the right."""
         s = self.statements[self.pointer]
         s = self.statements[self.pointer]
@@ -293,10 +309,10 @@ class Block:
                 message = ' ' + message
                 message = ' ' + message
 
 
                 if len(replacement):
                 if len(replacement):
-                    replacement[0].set_inline_comment(message)
+                    replacement[0].set_message(message)
 
 
                     for s in replacement[1:]:
                     for s in replacement[1:]:
-                        s.set_inline_comment('|')
+                        s.set_message('|')
                 else:
                 else:
                     replacement = [Statement('comment', message)]
                     replacement = [Statement('comment', message)]
             elif not len(replacement):
             elif not len(replacement):
@@ -313,10 +329,8 @@ class Block:
         if index == None:
         if index == None:
             index = self.pointer
             index = self.pointer
 
 
-        if self.verbose and len(message):
-            statement.set_inline_comment(' ' + message)
-
         self.statements.insert(index, statement)
         self.statements.insert(index, statement)
+        statement.set_message(' ' + message)
 
 
     def apply_filter(self, callback):
     def apply_filter(self, callback):
         """Apply a filter to the statement list. If the callback returns True,
         """Apply a filter to the statement list. If the callback returns True,

+ 9 - 2
src/writer.py

@@ -11,7 +11,7 @@ ADD_ARGUMENT_SPACE = False  # Wether to add a space between command arguments
                             # and the previous comma
                             # and the previous comma
 
 
 
 
-def write_statements(statements):
+def write_statements(statements, verbose=0):
     """Write a list of statements to valid assembly code."""
     """Write a list of statements to valid assembly code."""
     out = ''
     out = ''
     indent_level = 0
     indent_level = 0
@@ -49,7 +49,14 @@ def write_statements(statements):
             raise Exception('Unsupported statement type "%s"' % s.stype)
             raise Exception('Unsupported statement type "%s"' % s.stype)
 
 
         # Add the inline comment, if there is any
         # Add the inline comment, if there is any
+        comment = ''
+
         if s.has_inline_comment():
         if s.has_inline_comment():
+            comment = s.options['comment']
+        elif verbose:
+            comment = s.options.get('message', '')
+
+        if len(comment):
             start = INLINE_COMMENT_LEVEL * TABSIZE
             start = INLINE_COMMENT_LEVEL * TABSIZE
             diff = start - len(line.expandtabs(TABSIZE))
             diff = start - len(line.expandtabs(TABSIZE))
 
 
@@ -59,7 +66,7 @@ def write_statements(statements):
             else:
             else:
                 tabs = '  '
                 tabs = '  '
 
 
-            line += tabs + '#' + s.options['comment']
+            line += tabs + '#' + comment
 
 
         # Add newline at end of command
         # Add newline at end of command
         line += '\n'
         line += '\n'