if (!sat_val)
return false;
+ this->result = reg_undef;
sat_val->accept(this);
fs_reg src = this->result;
if (try_emit_saturate(ir))
return;
+ /* This is where our caller would like us to put the result, if possible. */
+ fs_reg saved_result_storage = this->result;
+
for (operand = 0; operand < ir->get_num_operands(); operand++) {
+ this->result = reg_undef;
ir->operands[operand]->accept(this);
if (this->result.file == BAD_FILE) {
ir_print_visitor v;
assert(!ir->operands[operand]->type->is_vector());
}
- /* Storage for our result. If our result goes into an assignment, it will
- * just get copy-propagated out, so no worries.
+ /* Inherit storage from our parent if possible, and otherwise we
+ * alloc a temporary.
*/
- this->result = fs_reg(this, ir->type);
+ if (saved_result_storage.file == BAD_FILE) {
+ this->result = fs_reg(this, ir->type);
+ } else {
+ this->result = saved_result_storage;
+ }
switch (ir->operation) {
case ir_unop_logic_not:
case ir_unop_sign:
temp = fs_reg(this, ir->type);
+ /* Unalias the destination. (imagine a = sign(a)) */
+ this->result = fs_reg(this, ir->type);
+
emit(BRW_OPCODE_MOV, this->result, fs_reg(0.0f));
inst = emit(BRW_OPCODE_CMP, reg_null_f, op[0], fs_reg(0.0f));
break;
case ir_binop_min:
+ /* Unalias the destination */
+ this->result = fs_reg(this, ir->type);
+
inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]);
inst->conditional_mod = BRW_CONDITIONAL_L;
inst->predicated = true;
break;
case ir_binop_max:
+ /* Unalias the destination */
+ this->result = fs_reg(this, ir->type);
+
inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]);
inst->conditional_mod = BRW_CONDITIONAL_G;
l.type = brw_type_for_base_type(type);
r.type = brw_type_for_base_type(type);
- fs_inst *inst = emit(BRW_OPCODE_MOV, l, r);
- inst->predicated = predicated;
+ if (predicated || !l.equals(&r)) {
+ fs_inst *inst = emit(BRW_OPCODE_MOV, l, r);
+ inst->predicated = predicated;
+ }
l.reg_offset++;
r.reg_offset++;
fs_inst *inst;
/* FINISHME: arrays on the lhs */
+ this->result = reg_undef;
ir->lhs->accept(this);
l = this->result;
+ /* If we're doing a direct assignment, an RHS expression could
+ * drop its result right into our destination. Otherwise, tell it
+ * not to.
+ */
+ if (ir->condition ||
+ !(ir->lhs->type->is_scalar() ||
+ (ir->lhs->type->is_vector() &&
+ ir->write_mask == (1 << ir->lhs->type->vector_elements) - 1))) {
+ this->result = reg_undef;
+ }
+
ir->rhs->accept(this);
r = this->result;
ir->lhs->type->is_vector()) {
for (int i = 0; i < ir->lhs->type->vector_elements; i++) {
if (ir->write_mask & (1 << i)) {
- inst = emit(BRW_OPCODE_MOV, l, r);
- if (ir->condition)
+ if (ir->condition) {
+ inst = emit(BRW_OPCODE_MOV, l, r);
inst->predicated = true;
+ } else if (!l.equals(&r)) {
+ inst = emit(BRW_OPCODE_MOV, l, r);
+ }
+
r.reg_offset++;
}
l.reg_offset++;
emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), fs_reg(0.0f));
mlen++;
} else if (ir->op == ir_txb) {
+ this->result = reg_undef;
ir->lod_info.bias->accept(this);
emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
mlen++;
} else {
assert(ir->op == ir_txl);
+ this->result = reg_undef;
ir->lod_info.lod->accept(this);
emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
mlen++;
}
+ this->result = reg_undef;
ir->shadow_comparitor->accept(this);
emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
mlen++;
mlen += 6;
if (ir->op == ir_txb) {
+ this->result = reg_undef;
ir->lod_info.bias->accept(this);
emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
mlen++;
} else {
+ this->result = reg_undef;
ir->lod_info.lod->accept(this);
emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
mlen++;
if (ir->shadow_comparitor) {
mlen = MAX2(mlen, header_present + 4 * reg_width);
+ this->result = reg_undef;
ir->shadow_comparitor->accept(this);
emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
mlen += reg_width;
inst = emit(FS_OPCODE_TEX, dst);
break;
case ir_txb:
+ this->result = reg_undef;
ir->lod_info.bias->accept(this);
mlen = MAX2(mlen, header_present + 4 * reg_width);
emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
break;
case ir_txl:
+ this->result = reg_undef;
ir->lod_info.lod->accept(this);
mlen = MAX2(mlen, header_present + 4 * reg_width);
emit(BRW_OPCODE_MOV, fs_reg(MRF, base_mrf + mlen), this->result);
int sampler;
fs_inst *inst = NULL;
+ this->result = reg_undef;
ir->coordinate->accept(this);
fs_reg coordinate = this->result;
void
fs_visitor::visit(ir_swizzle *ir)
{
+ this->result = reg_undef;
ir->val->accept(this);
fs_reg val = this->result;
const unsigned size = type_size(ir->type->fields.array);
for (unsigned i = 0; i < ir->type->length; i++) {
+ this->result = reg_undef;
ir->array_elements[i]->accept(this);
fs_reg src_reg = this->result;
ir_instruction *const field = (ir_instruction *) node;
const unsigned size = type_size(field->type);
+ this->result = reg_undef;
field->accept(this);
fs_reg src_reg = this->result;
for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
assert(expr->operands[i]->type->is_scalar());
+ this->result = reg_undef;
expr->operands[i]->accept(this);
op[i] = this->result;
}
return;
}
+ this->result = reg_undef;
ir->accept(this);
if (intel->gen >= 6) {
for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
assert(expr->operands[i]->type->is_scalar());
+ this->result = reg_undef;
expr->operands[i]->accept(this);
op[i] = this->result;
}
return;
}
+ this->result = reg_undef;
ir->condition->accept(this);
fs_inst *inst = emit(BRW_OPCODE_IF, reg_null_d, this->result, fs_reg(0));
foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
ir_instruction *ir = (ir_instruction *)iter.get();
this->base_ir = ir;
-
+ this->result = reg_undef;
ir->accept(this);
}
foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
ir_instruction *ir = (ir_instruction *)iter.get();
this->base_ir = ir;
-
+ this->result = reg_undef;
ir->accept(this);
}
}
counter = *(variable_storage(ir->counter));
if (ir->from) {
+ this->result = counter;
+
this->base_ir = ir->from;
+ this->result = counter;
ir->from->accept(this);
- emit(BRW_OPCODE_MOV, counter, this->result);
+ if (!this->result.equals(&counter))
+ emit(BRW_OPCODE_MOV, counter, this->result);
}
}
if (ir->to) {
this->base_ir = ir->to;
+ this->result = reg_undef;
ir->to->accept(this);
fs_inst *inst = emit(BRW_OPCODE_CMP, reg_null_cmp, counter, this->result);
ir_instruction *ir = (ir_instruction *)iter.get();
this->base_ir = ir;
+ this->result = reg_undef;
ir->accept(this);
}
if (ir->increment) {
this->base_ir = ir->increment;
+ this->result = reg_undef;
ir->increment->accept(this);
emit(BRW_OPCODE_ADD, counter, counter, this->result);
}
foreach_iter(exec_list_iterator, iter, sig->body) {
ir_instruction *ir = (ir_instruction *)iter.get();
this->base_ir = ir;
-
+ this->result = reg_undef;
ir->accept(this);
}
}
foreach_iter(exec_list_iterator, iter, *shader->ir) {
ir_instruction *ir = (ir_instruction *)iter.get();
base_ir = ir;
+ this->result = reg_undef;
ir->accept(this);
}