ir_copy_propagation: Return true if we optimized out any assignments.
authorEric Anholt <eric@anholt.net>
Wed, 5 May 2010 16:31:53 +0000 (09:31 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 5 May 2010 16:32:44 +0000 (09:32 -0700)
This may trigger other optimization phases to make more progress themselves.

ir_basic_block.cpp
ir_basic_block.h
ir_copy_propagation.cpp

index b10a25c..455398e 100644 (file)
@@ -61,7 +61,9 @@ has_call_callback(ir_instruction *ir, void *data)
  */
 void call_for_basic_blocks(exec_list *instructions,
                           void (*callback)(ir_instruction *first,
-                                           ir_instruction *last))
+                                           ir_instruction *last,
+                                           void *data),
+                          void *data)
 {
    ir_instruction *leader = NULL;
    ir_instruction *last = NULL;
@@ -76,17 +78,17 @@ void call_for_basic_blocks(exec_list *instructions,
         leader = ir;
 
       if ((ir_if = ir->as_if())) {
-        callback(leader, ir);
+        callback(leader, ir, data);
         leader = NULL;
 
-        call_for_basic_blocks(&ir_if->then_instructions, callback);
-        call_for_basic_blocks(&ir_if->else_instructions, callback);
+        call_for_basic_blocks(&ir_if->then_instructions, callback, data);
+        call_for_basic_blocks(&ir_if->else_instructions, callback, data);
       } else if ((ir_loop = ir->as_loop())) {
-        callback(leader, ir);
+        callback(leader, ir, data);
         leader = NULL;
-        call_for_basic_blocks(&ir_loop->body_instructions, callback);
+        call_for_basic_blocks(&ir_loop->body_instructions, callback, data);
       } else if (ir->as_return() || ir->as_call()) {
-        callback(leader, ir);
+        callback(leader, ir, data);
         leader = NULL;
       } else if ((ir_function = ir->as_function())) {
         /* A function definition doesn't interrupt our basic block
@@ -103,7 +105,7 @@ void call_for_basic_blocks(exec_list *instructions,
 
            ir_sig = (ir_function_signature *)fun_iter.get();
 
-           call_for_basic_blocks(&ir_sig->body, callback);
+           call_for_basic_blocks(&ir_sig->body, callback, data);
         }
       } else if (ir->as_assignment()) {
         bool has_call = false;
@@ -124,13 +126,13 @@ void call_for_basic_blocks(exec_list *instructions,
         ir_visit_tree(ir, has_call_callback, &has_call);
 
         if (has_call) {
-           callback(leader, ir);
+           callback(leader, ir, data);
            leader = NULL;
         }
       }
       last = ir;
    }
    if (leader) {
-      callback(leader, last);
+      callback(leader, last, data);
    }
 }
index e7993b3..dbd678b 100644 (file)
@@ -23,4 +23,6 @@
 
 void call_for_basic_blocks(exec_list *instructions,
                           void (*callback)(ir_instruction *first,
-                                           ir_instruction *last));
+                                           ir_instruction *last,
+                                           void *data),
+                          void *data);
index 526ff96..1f8c359 100644 (file)
@@ -216,12 +216,14 @@ ir_copy_propagation_visitor::visit(ir_if *ir)
    ir->condition->accept(this);
 }
 
-static void
+static bool
 propagate_copies(ir_instruction *ir, exec_list *acp)
 {
    ir_copy_propagation_visitor v(acp);
 
    ir->accept(&v);
+
+   return v.progress;
 }
 
 static void
@@ -288,16 +290,19 @@ add_copy(ir_assignment *ir, exec_list *acp)
 
 static void
 copy_propagation_basic_block(ir_instruction *first,
-                            ir_instruction *last)
+                            ir_instruction *last,
+                            void *data)
 {
    ir_instruction *ir;
    /* List of avaialble_copy */
    exec_list acp;
+   bool *out_progress = (bool *)data;
+   bool progress = false;
 
    for (ir = first;; ir = (ir_instruction *)ir->next) {
       ir_assignment *ir_assign = ir->as_assignment();
 
-      propagate_copies(ir, &acp);
+      progress = propagate_copies(ir, &acp) || progress;
 
       if (ir_assign) {
         kill_invalidated_copies(ir_assign, &acp);
@@ -307,6 +312,7 @@ copy_propagation_basic_block(ir_instruction *first,
       if (ir == last)
         break;
    }
+   *out_progress = progress;
 }
 
 /**
@@ -317,8 +323,7 @@ do_copy_propagation(exec_list *instructions)
 {
    bool progress = false;
 
-   call_for_basic_blocks(instructions, copy_propagation_basic_block);
+   call_for_basic_blocks(instructions, copy_propagation_basic_block, &progress);
 
-   /* FINISHME: Return a legit progress value. */
    return progress;
 }