diff options
author | Eric Anholt <eric@anholt.net> | 2010-05-05 09:31:53 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-05-05 09:32:44 -0700 |
commit | 8e75de31649f877f24f460bc887c827227968403 (patch) | |
tree | 59c44a4285977eb9611617c4d3a7d15ca7f00d40 | |
parent | 4e2c0b99d932577d082b95d54e4ed1ba1d5d686b (diff) |
ir_copy_propagation: Return true if we optimized out any assignments.
This may trigger other optimization phases to make more progress themselves.
-rw-r--r-- | ir_basic_block.cpp | 22 | ||||
-rw-r--r-- | ir_basic_block.h | 4 | ||||
-rw-r--r-- | ir_copy_propagation.cpp | 15 |
3 files changed, 25 insertions, 16 deletions
diff --git a/ir_basic_block.cpp b/ir_basic_block.cpp index b10a25c535..455398e499 100644 --- a/ir_basic_block.cpp +++ b/ir_basic_block.cpp @@ -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); } } diff --git a/ir_basic_block.h b/ir_basic_block.h index e7993b3b04..dbd678b5c4 100644 --- a/ir_basic_block.h +++ b/ir_basic_block.h @@ -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); diff --git a/ir_copy_propagation.cpp b/ir_copy_propagation.cpp index 526ff96e62..1f8c3590c2 100644 --- a/ir_copy_propagation.cpp +++ b/ir_copy_propagation.cpp @@ -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; } |