ir_visitor_status ir_constant_folding_visitor::visit_enter(ir_assignment *ir) { ir->rhs->accept(this); handle_rvalue(&ir->rhs); if (ir->condition) { ir->condition->accept(this); handle_rvalue(&ir->condition); ir_constant *const_val = ir->condition->as_constant(); /* If the condition is constant, either remove the condition or * remove the never-executed assignment. */ if (const_val) { if (const_val->value.b[0]) ir->condition = NULL; else ir->remove(); this->progress = true; } } /* Don't descend into the LHS because we want it to stay as a * variable dereference. FINISHME: We probably should to get array * indices though. */ return visit_continue_with_parent; }
ir_visitor_status ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir) { handle_rvalue(&ir->coordinate); handle_rvalue(&ir->projector); handle_rvalue(&ir->shadow_comparitor); handle_rvalue(&ir->offset); switch (ir->op) { case ir_tex: case ir_lod: case ir_query_levels: break; case ir_txb: handle_rvalue(&ir->lod_info.bias); break; case ir_txf: case ir_txl: case ir_txs: handle_rvalue(&ir->lod_info.lod); break; case ir_txf_ms: handle_rvalue(&ir->lod_info.sample_index); break; case ir_txd: handle_rvalue(&ir->lod_info.grad.dPdx); handle_rvalue(&ir->lod_info.grad.dPdy); break; case ir_tg4: handle_rvalue(&ir->lod_info.component); break; } return visit_continue; }
ir_visitor_status ir_rvalue_base_visitor::rvalue_visit(ir_assignment *ir) { handle_rvalue(&ir->rhs); handle_rvalue(&ir->condition); return visit_continue; }
ir_visitor_status ir_rvalue_base_visitor::rvalue_visit(ir_dereference_array *ir) { /* The array index is not the target of the assignment, so clear the * 'in_assignee' flag. Restore it after returning from the array index. */ const bool was_in_assignee = this->in_assignee; this->in_assignee = false; handle_rvalue(&ir->array_index); this->in_assignee = was_in_assignee; handle_rvalue(&ir->array); return visit_continue; }
ir_visitor_status ir_rvalue_visitor::visit_leave(ir_texture *ir) { handle_rvalue(&ir->coordinate); handle_rvalue(&ir->projector); handle_rvalue(&ir->shadow_comparitor); handle_rvalue(&ir->offset); switch (ir->op) { case ir_tex: break; case ir_txb: handle_rvalue(&ir->lod_info.bias); break; case ir_txf: case ir_txl: handle_rvalue(&ir->lod_info.lod); break; case ir_txd: handle_rvalue(&ir->lod_info.grad.dPdx); handle_rvalue(&ir->lod_info.grad.dPdy); break; } return visit_continue; }
/** * Replace any assignment having gl_ClipDistance (undereferenced) as its LHS * or RHS with a sequence of assignments, one for each component of the array. * Each of these assignments is lowered to refer to gl_ClipDistanceMESA as * appropriate. */ ir_visitor_status lower_clip_distance_visitor::visit_leave(ir_assignment *ir) { ir_dereference_variable *lhs_var = ir->lhs->as_dereference_variable(); ir_dereference_variable *rhs_var = ir->rhs->as_dereference_variable(); if ((lhs_var && lhs_var->var == this->old_clip_distance_var) || (rhs_var && rhs_var->var == this->old_clip_distance_var)) { /* LHS or RHS of the assignment is the entire gl_ClipDistance array. * Since we are reshaping gl_ClipDistance from an array of floats to an * array of vec4's, this isn't going to work as a bulk assignment * anymore, so unroll it to element-by-element assignments and lower * each of them. * * Note: to unroll into element-by-element assignments, we need to make * clones of the LHS and RHS. This is safe because expressions and * l-values are side-effect free. */ void *ctx = ralloc_parent(ir); int array_size = this->old_clip_distance_var->type->array_size(); for (int i = 0; i < array_size; ++i) { ir_dereference_array *new_lhs = new(ctx) ir_dereference_array( ir->lhs->clone(ctx, NULL), new(ctx) ir_constant(i)); ir_dereference_array *new_rhs = new(ctx) ir_dereference_array( ir->rhs->clone(ctx, NULL), new(ctx) ir_constant(i)); this->handle_rvalue((ir_rvalue **) &new_rhs); /* Handle the LHS after creating the new assignment. This must * happen in this order because handle_rvalue may replace the old LHS * with an ir_expression of ir_binop_vector_extract. Since this is * not a valide l-value, this will cause an assertion in the * ir_assignment constructor to fail. * * If this occurs, replace the mangled LHS with a dereference of the * vector, and replace the RHS with an ir_triop_vector_insert. */ ir_assignment *const assign = new(ctx) ir_assignment(new_lhs, new_rhs); this->handle_rvalue((ir_rvalue **) &assign->lhs); this->fix_lhs(assign); this->base_ir->insert_before(assign); } ir->remove(); return visit_continue; } /* Handle the LHS as if it were an r-value. Normally * rvalue_visit(ir_assignment *) only visits the RHS, but we need to lower * expressions in the LHS as well. * * This may cause the LHS to get replaced with an ir_expression of * ir_binop_vector_extract. If this occurs, replace it with a dereference * of the vector, and replace the RHS with an ir_triop_vector_insert. */ handle_rvalue((ir_rvalue **)&ir->lhs); this->fix_lhs(ir); return rvalue_visit(ir); }
ir_visitor_status ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir) { handle_rvalue(&ir->coordinate); handle_rvalue(&ir->offset); switch (ir->op) { case ir_tex: case ir_lod: break; case ir_txb: handle_rvalue(&ir->lod_info.bias); break; case ir_txf: case ir_txl: case ir_txs: handle_rvalue(&ir->lod_info.lod); break; case ir_txf_ms: handle_rvalue(&ir->lod_info.sample_index); break; case ir_txd: handle_rvalue(&ir->lod_info.grad.dPdx); handle_rvalue(&ir->lod_info.grad.dPdy); break; } return visit_continue; }
ir_visitor_status ir_rvalue_base_visitor::rvalue_visit(ir_expression *ir) { unsigned int operand; for (operand = 0; operand < ir->get_num_operands(); operand++) { handle_rvalue(&ir->operands[operand]); } return visit_continue; }
ir_visitor_status ir_constant_folding_visitor::visit_enter(ir_discard *ir) { if (ir->condition) { ir->condition->accept(this); handle_rvalue(&ir->condition); ir_constant *const_val = ir->condition->as_constant(); /* If the condition is constant, either remove the condition or * remove the never-executed assignment. */ if (const_val) { if (const_val->value.b[0]) ir->condition = NULL; else ir->remove(); this->progress = true; } } return visit_continue_with_parent; }
ir_visitor_status ir_rvalue_base_visitor::rvalue_visit(ir_swizzle *ir) { handle_rvalue(&ir->val); return visit_continue; }
ir_visitor_status ir_rvalue_base_visitor::rvalue_visit(ir_dereference_record *ir) { handle_rvalue(&ir->record); return visit_continue; }