Explorar o código

Debug messages are not concatenated instead of overwritten.

Taddeus Kroes %!s(int64=14) %!d(string=hai) anos
pai
achega
69a922ff52
Modificáronse 4 ficheiros con 100 adicións e 7 borrados
  1. 93 0
      src/copy_propagation.py
  2. 2 2
      src/optimize/advanced.py
  3. 4 4
      src/statement.py
  4. 1 1
      src/writer.py

+ 93 - 0
src/copy_propagation.py

@@ -0,0 +1,93 @@
+from dataflow import pred
+from liveness import RESERVED_REGISTERS
+
+
+def create_gen_kill(block):
+    block.c_gen = set()
+    block.c_kill = set()
+
+    for s in block:
+        if s.is_command('move'):
+            # An occurrence of a copy statement generates this statement
+            x, y = s
+
+            if x not in RESERVED_REGISTERS and y not in RESERVED_REGISTERS:
+                block.c_gen.add((x, y))
+        else:
+            # An assignment to x or y kills the copy statement x = y
+            block.c_kill |= set(s.get_def())
+            #for reg in s.get_def():
+            #    block.c_kill.add(reg)
+            #    print 'kill of %s' % reg
+
+
+def create_in_out(blocks):
+    """Generate the `in' and `out' sets of the given blocks using the iterative
+    algorithm from the lecture slides."""
+    # Create gen/kill sets
+    for b in blocks:
+        create_gen_kill(b)
+        b.copy_in = set()
+        b.copy_out = set()
+
+    # in[B1] = {} where B1 is the initial block
+    blocks[0].copy_in = set()
+
+    #def create_sets(b, first=False):
+    for i, b in enumerate(blocks):
+        # in[B1] = {} where B1 is the initial block
+        # in[B] = intersection of out[P] for P in pred(B) for B not initial
+        if i:
+            b.copy_in = set()
+
+            for p in pred(b):
+                b.copy_in &= p.copy_out
+
+        # out[B] = c_gen[B] | (in[B] - c_kill[B])
+        in_minus_kill = set()
+
+        for x, y in b.copy_in:
+            if x not in b.c_kill and y not in b.c_kill:
+                print '%s, %s not in c_kill' % (x, y)
+                in_minus_kill.add((x, y))
+
+        b.copy_out = b.c_gen | in_minus_kill
+
+        #for successor in b.edges_to:
+        #    create_sets(successor)
+
+    #create_sets(blocks[0], True)
+
+
+def propagate_copies(block):
+    changed = False
+
+    # For each copy statement s: x = y do
+    for s in block:
+        if s.is_command('move'):
+            x, y = s
+
+            # Determine the uses of x reached by this definition of x
+            uses = filter(lambda suc: s.sid in suc.reach_in, block.edges_to)
+
+            # Determine if for each of those uses this is the only
+            # definition reaching it -> s in in[B_use]
+            only_def = True
+
+            for b_use in uses:
+                if (x, y) not in b_use.copy_in:
+                    only_def = False
+
+            # If so, remove s and replace the uses of x by uses of y
+            if only_def:
+                for use in uses:
+                    print 'use:', use
+                    for statement in use:
+                        if statement.uses(x):
+                            statement.replace_usage(x, y)
+                            message = ' Replaced %s with %s' % (x, y)
+                            print message
+                            statement.set_inline_comment(message)
+                            changed = True
+
+    return changed

+ 2 - 2
src/optimize/advanced.py

@@ -446,8 +446,8 @@ def copy_propagation(block):
 
             # Moves to reserved registers will never be removed, so don't
             # bother replacing them
-            #if x in RESERVED_REGISTERS:
-            #    continue
+            if x in RESERVED_REGISTERS:
+                continue
 
             # Determine the uses of x reached by this definition of x
             for s2 in block[block.pointer:]:

+ 4 - 4
src/statement.py

@@ -40,10 +40,10 @@ class Statement:
                 % (self.stype, self.name, self.args)
 
     def set_message(self, message):
-        if len(self.options.get('message', '')):
-            self.options['message'] += ' |' + message
-        else:
-            self.options['message'] = message
+        if 'message' not in self.options:
+            self.options['message'] = [message]
+        elif message not in self.options['message']:
+            self.options['message'].append(message)
 
     def set_inline_comment(self, comment):
         self.options['comment'] = comment

+ 1 - 1
src/writer.py

@@ -54,7 +54,7 @@ def write_statements(statements, verbose=0):
         if s.has_inline_comment():
             comment = s.options['comment']
         elif verbose:
-            comment = s.options.get('message', '')
+            comment = ' |'.join(s.options.get('message', []))
 
         if len(comment):
             start = INLINE_COMMENT_LEVEL * TABSIZE