#include "ir_optimization.h"
#include "glsl_types.h"
+namespace {
+
class acp_entry : public exec_node
{
public:
void *mem_ctx;
};
+} /* unnamed namespace */
+
ir_visitor_status
ir_copy_propagation_visitor::visit_enter(ir_function_signature *ir)
{
visit_list_elements(this, &ir->body);
+ ralloc_free(this->acp);
+ ralloc_free(this->kills);
+
this->kills = orig_kills;
this->acp = orig_acp;
this->killed_all = orig_killed_all;
ir_variable *var = ir->var;
- foreach_iter(exec_list_iterator, iter, *this->acp) {
- acp_entry *entry = (acp_entry *)iter.get();
-
+ foreach_in_list(acp_entry, entry, this->acp) {
if (var == entry->lhs) {
ir->var = entry->rhs;
this->progress = true;
ir_copy_propagation_visitor::visit_enter(ir_call *ir)
{
/* Do copy propagation on call parameters, but skip any out params */
- exec_list_iterator sig_param_iter = ir->get_callee()->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
- ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
- ir_instruction *ir = (ir_instruction *)iter.get();
- if (sig_param->mode != ir_var_out && sig_param->mode != ir_var_inout) {
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_variable *sig_param = (ir_variable *) formal_node;
+ ir_rvalue *ir = (ir_rvalue *) actual_node;
+ if (sig_param->data.mode != ir_var_function_out
+ && sig_param->data.mode != ir_var_function_inout) {
ir->accept(this);
}
- sig_param_iter.next();
}
- /* Since we're unlinked, we don't (necssarily) know the side effects of
+ /* Since we're unlinked, we don't (necessarily) know the side effects of
* this call. So kill all copies.
*/
acp->make_empty();
this->killed_all = false;
/* Populate the initial acp with a copy of the original */
- foreach_iter(exec_list_iterator, iter, *orig_acp) {
- acp_entry *a = (acp_entry *)iter.get();
- this->acp->push_tail(new(this->mem_ctx) acp_entry(a->lhs, a->rhs));
+ foreach_in_list(acp_entry, a, orig_acp) {
+ this->acp->push_tail(new(this->acp) acp_entry(a->lhs, a->rhs));
}
visit_list_elements(this, instructions);
exec_list *new_kills = this->kills;
this->kills = orig_kills;
+ ralloc_free(this->acp);
this->acp = orig_acp;
this->killed_all = this->killed_all || orig_killed_all;
- foreach_iter(exec_list_iterator, iter, *new_kills) {
- kill_entry *k = (kill_entry *)iter.get();
+ foreach_in_list(kill_entry, k, new_kills) {
kill(k->var);
}
+
+ ralloc_free(new_kills);
}
ir_visitor_status
exec_list *new_kills = this->kills;
this->kills = orig_kills;
+ ralloc_free(this->acp);
this->acp = orig_acp;
this->killed_all = this->killed_all || orig_killed_all;
- foreach_iter(exec_list_iterator, iter, *new_kills) {
- kill_entry *k = (kill_entry *)iter.get();
+ foreach_in_list(kill_entry, k, new_kills) {
kill(k->var);
}
+ ralloc_free(new_kills);
+
/* already descended into the children. */
return visit_continue_with_parent;
}
assert(var != NULL);
/* Remove any entries currently in the ACP for this kill. */
- foreach_iter(exec_list_iterator, iter, *acp) {
- acp_entry *entry = (acp_entry *)iter.get();
-
+ foreach_in_list_safe(acp_entry, entry, acp) {
if (entry->lhs == var || entry->rhs == var) {
entry->remove();
}
/* Add the LHS variable to the list of killed variables in this block.
*/
- this->kills->push_tail(new(this->mem_ctx) kill_entry(var));
+ this->kills->push_tail(new(this->kills) kill_entry(var));
}
/**
{
acp_entry *entry;
- if (ir->condition) {
- ir_constant *condition = ir->condition->as_constant();
- if (!condition || !condition->value.b[0])
- return;
- }
+ if (ir->condition)
+ return;
ir_variable *lhs_var = ir->whole_variable_written();
ir_variable *rhs_var = ir->rhs->whole_variable_referenced();
*/
ir->condition = new(ralloc_parent(ir)) ir_constant(false);
this->progress = true;
- } else {
- entry = new(this->mem_ctx) acp_entry(lhs_var, rhs_var);
+ } else if (lhs_var->data.mode != ir_var_shader_storage &&
+ lhs_var->data.mode != ir_var_shader_shared) {
+ entry = new(this->acp) acp_entry(lhs_var, rhs_var);
this->acp->push_tail(entry);
}
}