ir_copy_propagation: Return true if we optimized out any assignments.
This may trigger other optimization phases to make more progress themselves.
This commit is contained in:
+12
-10
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -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);
|
||||
|
||||
+10
-5
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user