* call takes place. Since we haven't emitted the call yet, we'll place
* the post-call conversions in a temporary exec_list, and emit them later.
*/
- exec_list_iterator actual_iter = actual_parameters->iterator();
- exec_list_iterator formal_iter = sig->parameters.iterator();
-
- while (actual_iter.has_next()) {
- ir_rvalue *actual = (ir_rvalue *) actual_iter.get();
- ir_variable *formal = (ir_variable *) formal_iter.get();
-
- assert(actual != NULL);
- assert(formal != NULL);
+ foreach_two_lists(formal_node, &sig->parameters,
+ actual_node, actual_parameters) {
+ ir_rvalue *actual = (ir_rvalue *) actual_node;
+ ir_variable *formal = (ir_variable *) formal_node;
if (formal->type->is_numeric() || formal->type->is_boolean()) {
switch (formal->data.mode) {
break;
}
}
-
- actual_iter.next();
- formal_iter.next();
}
/* If the function call is a constant expression, don't generate any
const char *
ir_function_signature::qualifiers_match(exec_list *params)
{
- exec_list_iterator iter_a = parameters.iterator();
- exec_list_iterator iter_b = params->iterator();
-
/* check that the qualifiers match. */
- while (iter_a.has_next()) {
- ir_variable *a = (ir_variable *)iter_a.get();
- ir_variable *b = (ir_variable *)iter_b.get();
+ foreach_two_lists(a_node, &this->parameters, b_node, params) {
+ ir_variable *a = (ir_variable *) a_node;
+ ir_variable *b = (ir_variable *) b_node;
if (a->data.read_only != b->data.read_only ||
!modes_match(a->data.mode, b->data.mode) ||
/* parameter a's qualifiers don't match */
return a->name;
}
-
- iter_a.next();
- iter_b.next();
}
return NULL;
}
virtual ir_visitor_status visit_enter(ir_call *ir)
{
- exec_list_iterator sig_iter = ir->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param_rval = (ir_rvalue *)iter.get();
- ir_variable *sig_param = (ir_variable *)sig_iter.get();
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_rvalue *param_rval = (ir_rvalue *) actual_node;
+ ir_variable *sig_param = (ir_variable *) formal_node;
if (sig_param->data.mode == ir_var_function_out ||
sig_param->data.mode == ir_var_function_inout) {
return visit_stop;
}
}
- sig_iter.next();
}
if (ir->return_deref != NULL) {
; (__node)->next != NULL \
; (__node) = (__node)->next)
+/**
+ * Iterate through two lists at once. Stops at the end of the shorter list.
+ *
+ * This is safe against either current node being removed or replaced.
+ */
+#define foreach_two_lists(__node1, __list1, __node2, __list2) \
+ for (exec_node * __node1 = (__list1)->head, \
+ * __node2 = (__list2)->head, \
+ * __next1 = __node1->next, \
+ * __next2 = __node2->next \
+ ; __next1 != NULL && __next2 != NULL \
+ ; __node1 = __next1, \
+ __node2 = __next2, \
+ __next1 = __next1->next, \
+ __next2 = __next2->next)
+
#define foreach_list_const(__node, __list) \
for (const exec_node * __node = (__list)->head \
; (__node)->next != NULL \
ir_constant_folding_visitor::visit_enter(ir_call *ir)
{
/* Attempt to constant fold parameters */
- exec_list_iterator sig_iter = ir->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param_rval = (ir_rvalue *)iter.get();
- ir_variable *sig_param = (ir_variable *)sig_iter.get();
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_rvalue *param_rval = (ir_rvalue *) actual_node;
+ ir_variable *sig_param = (ir_variable *) formal_node;
if (sig_param->data.mode == ir_var_function_in
|| sig_param->data.mode == ir_var_const_in) {
param_rval->replace_with(new_param);
}
}
- sig_iter.next();
}
/* Next, see if the call can be replaced with an assignment of a constant */
ir_constant_propagation_visitor::visit_enter(ir_call *ir)
{
/* Do constant propagation on call parameters, but skip any out params */
- exec_list_iterator sig_param_iter = ir->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
- ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
- ir_rvalue *param = (ir_rvalue *)iter.get();
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_variable *sig_param = (ir_variable *) formal_node;
+ ir_rvalue *param = (ir_rvalue *) actual_node;
if (sig_param->data.mode != ir_var_function_out
&& sig_param->data.mode != ir_var_function_inout) {
ir_rvalue *new_param = param;
else
param->accept(this);
}
- sig_param_iter.next();
}
/* Since we're unlinked, we don't (necssarily) know the side effects of
ir_constant_variable_visitor::visit_enter(ir_call *ir)
{
/* Mark any out parameters as assigned to */
- exec_list_iterator sig_iter = ir->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param_rval = (ir_rvalue *)iter.get();
- ir_variable *param = (ir_variable *)sig_iter.get();
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_rvalue *param_rval = (ir_rvalue *) actual_node;
+ ir_variable *param = (ir_variable *) formal_node;
if (param->data.mode == ir_var_function_out ||
param->data.mode == ir_var_function_inout) {
entry = get_assignment_entry(var, &this->list);
entry->assignment_count++;
}
- sig_iter.next();
}
/* Mark the return storage as having been assigned to */
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->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
- ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
- ir_rvalue *ir = (ir_rvalue *) iter.get();
+ 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 (necessarily) know the side effects of
ir_copy_propagation_elements_visitor::visit_enter(ir_call *ir)
{
/* Do copy propagation on call parameters, but skip any out params */
- exec_list_iterator sig_param_iter = ir->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
- ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
- ir_rvalue *ir = (ir_rvalue *) iter.get();
+ 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 (necessarily) know the side effects of
* and set up the mapping of real function body variables to ours.
*/
i = 0;
- exec_list_iterator sig_param_iter = this->callee->parameters.iterator();
- exec_list_iterator param_iter = this->actual_parameters.iterator();
- for (i = 0; i < num_parameters; i++) {
- ir_variable *sig_param = (ir_variable *) sig_param_iter.get();
- ir_rvalue *param = (ir_rvalue *) param_iter.get();
+ foreach_two_lists(formal_node, &this->callee->parameters,
+ actual_node, &this->actual_parameters) {
+ ir_variable *sig_param = (ir_variable *) formal_node;
+ ir_rvalue *param = (ir_rvalue *) actual_node;
/* Generate a new variable for the parameter. */
if (sig_param->type->contains_opaque()) {
next_ir->insert_before(assign);
}
- sig_param_iter.next();
- param_iter.next();
+ ++i;
}
exec_list new_instructions;
/* If any opaque types were passed in, replace any deref of the
* opaque variable with a deref of the argument.
*/
- param_iter = this->actual_parameters.iterator();
- sig_param_iter = this->callee->parameters.iterator();
- for (i = 0; i < num_parameters; i++) {
- ir_rvalue *const param = (ir_rvalue *) param_iter.get();
- ir_variable *sig_param = (ir_variable *) sig_param_iter.get();
+ foreach_two_lists(formal_node, &this->callee->parameters,
+ actual_node, &this->actual_parameters) {
+ ir_rvalue *const param = (ir_rvalue *) actual_node;
+ ir_variable *sig_param = (ir_variable *) formal_node;
if (sig_param->type->contains_opaque()) {
ir_dereference *deref = param->as_dereference();
assert(deref);
do_variable_replacement(&new_instructions, sig_param, deref);
}
- param_iter.next();
- sig_param_iter.next();
}
/* Now push those new instructions in. */
* variables to our own.
*/
i = 0;
- param_iter = this->actual_parameters.iterator();
- sig_param_iter = this->callee->parameters.iterator();
- for (i = 0; i < num_parameters; i++) {
- ir_rvalue *const param = (ir_rvalue *) param_iter.get();
- const ir_variable *const sig_param = (ir_variable *) sig_param_iter.get();
+ foreach_two_lists(formal_node, &this->callee->parameters,
+ actual_node, &this->actual_parameters) {
+ ir_rvalue *const param = (ir_rvalue *) actual_node;
+ const ir_variable *const sig_param = (ir_variable *) formal_node;
/* Move our param variable into the actual param if it's an 'out' type. */
if (parameters[i] && (sig_param->data.mode == ir_var_function_out ||
next_ir->insert_before(assign);
}
- param_iter.next();
- sig_param_iter.next();
+ ++i;
}
delete [] parameters;
ir_visitor_status
ir_tree_grafting_visitor::visit_enter(ir_call *ir)
{
- exec_list_iterator sig_iter = ir->callee->parameters.iterator();
- /* Reminder: iterating ir_call iterates its parameters. */
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_variable *sig_param = (ir_variable *)sig_iter.get();
- ir_rvalue *ir = (ir_rvalue *)iter.get();
+ 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;
ir_rvalue *new_ir = ir;
if (sig_param->data.mode != ir_var_function_in
ir->replace_with(new_ir);
return visit_stop;
}
- sig_iter.next();
}
if (ir->return_deref && check_graft(ir, ir->return_deref->var) == visit_stop)
int i;
/* Process in parameters. */
- exec_list_iterator sig_iter = sig->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param_rval = (ir_rvalue *)iter.get();
- ir_variable *param = (ir_variable *)sig_iter.get();
+ foreach_two_lists(formal_node, &sig->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_rvalue *param_rval = (ir_rvalue *) actual_node;
+ ir_variable *param = (ir_variable *) formal_node;
if (param->data.mode == ir_var_function_in ||
param->data.mode == ir_var_function_inout) {
r.index++;
}
}
-
- sig_iter.next();
}
- assert(!sig_iter.has_next());
/* Emit call instruction */
call_inst = emit(ir, TGSI_OPCODE_CAL);
call_inst->function = entry;
/* Process out parameters. */
- sig_iter = sig->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param_rval = (ir_rvalue *)iter.get();
- ir_variable *param = (ir_variable *)sig_iter.get();
+ foreach_two_lists(formal_node, &sig->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_rvalue *param_rval = (ir_rvalue *) actual_node;
+ ir_variable *param = (ir_variable *) formal_node;
if (param->data.mode == ir_var_function_out ||
param->data.mode == ir_var_function_inout) {
r.index++;
}
}
-
- sig_iter.next();
}
- assert(!sig_iter.has_next());
/* Process return value. */
this->result = entry->return_reg;