*/
#include "brw_vec4.h"
+#include "brw_vec4_live_variables.h"
#include "brw_cfg.h"
using namespace brw;
case BRW_OPCODE_CMPN:
case BRW_OPCODE_ADD:
case BRW_OPCODE_MUL:
+ case SHADER_OPCODE_MULH:
case BRW_OPCODE_FRC:
case BRW_OPCODE_RNDU:
case BRW_OPCODE_RNDD:
case BRW_OPCODE_MAD:
case BRW_OPCODE_LRP:
case VEC4_OPCODE_UNPACK_UNIFORM:
+ case SHADER_OPCODE_FIND_LIVE_CHANNEL:
+ case SHADER_OPCODE_BROADCAST:
+ case TCS_OPCODE_SET_INPUT_URB_OFFSETS:
+ case TCS_OPCODE_SET_OUTPUT_URB_OFFSETS:
return true;
case SHADER_OPCODE_RCP:
case SHADER_OPCODE_RSQ:
}
static bool
-is_expression_commutative(enum opcode op)
+operands_match(const vec4_instruction *a, const vec4_instruction *b)
{
- switch (op) {
- case BRW_OPCODE_AND:
- case BRW_OPCODE_OR:
- case BRW_OPCODE_XOR:
- case BRW_OPCODE_ADD:
- case BRW_OPCODE_MUL:
- return true;
- default:
- return false;
- }
-}
+ const src_reg *xs = a->src;
+ const src_reg *ys = b->src;
-static bool
-operands_match(enum opcode op, src_reg *xs, src_reg *ys)
-{
- if (op == BRW_OPCODE_MAD) {
+ if (a->opcode == BRW_OPCODE_MAD) {
return xs[0].equals(ys[0]) &&
((xs[1].equals(ys[1]) && xs[2].equals(ys[2])) ||
(xs[2].equals(ys[1]) && xs[1].equals(ys[2])));
- } else if (!is_expression_commutative(op)) {
+ } else if (!a->is_commutative()) {
return xs[0].equals(ys[0]) && xs[1].equals(ys[1]) && xs[2].equals(ys[2]);
} else {
return (xs[0].equals(ys[0]) && xs[1].equals(ys[1])) ||
{
return a->opcode == b->opcode &&
a->saturate == b->saturate &&
+ a->predicate == b->predicate &&
+ a->predicate_inverse == b->predicate_inverse &&
a->conditional_mod == b->conditional_mod &&
+ a->flag_subreg == b->flag_subreg &&
a->dst.type == b->dst.type &&
+ a->offset == b->offset &&
+ a->mlen == b->mlen &&
+ a->base_mrf == b->base_mrf &&
+ a->header_size == b->header_size &&
+ a->shadow_compare == b->shadow_compare &&
a->dst.writemask == b->dst.writemask &&
- operands_match(a->opcode, a->src, b->src);
+ a->force_writemask_all == b->force_writemask_all &&
+ a->size_written == b->size_written &&
+ operands_match(a, b);
}
bool
foreach_inst_in_block (vec4_instruction, inst, block) {
/* Skip some cases. */
if (is_expression(inst) && !inst->predicate && inst->mlen == 0 &&
- (inst->dst.file != HW_REG || inst->dst.is_null()))
+ ((inst->dst.file != ARF && inst->dst.file != FIXED_GRF) ||
+ inst->dst.is_null()))
{
bool found = false;
foreach_in_list_use_after(aeb_entry, entry, &aeb) {
/* Match current instruction's expression against those in AEB. */
- if (instructions_match(inst, entry->generator)) {
+ if (!(entry->generator->dst.is_null() && !inst->dst.is_null()) &&
+ instructions_match(inst, entry->generator)) {
found = true;
progress = true;
break;
*/
bool no_existing_temp = entry->tmp.file == BAD_FILE;
if (no_existing_temp && !entry->generator->dst.is_null()) {
- entry->tmp = src_reg(this, glsl_type::float_type);
- entry->tmp.type = inst->dst.type;
- entry->tmp.swizzle = BRW_SWIZZLE_XYZW;
+ entry->tmp = retype(src_reg(VGRF, alloc.allocate(
+ regs_written(entry->generator)),
+ NULL), inst->dst.type);
+
+ for (unsigned i = 0; i < regs_written(entry->generator); ++i) {
+ vec4_instruction *copy = MOV(offset(entry->generator->dst, i),
+ offset(entry->tmp, i));
+ copy->force_writemask_all =
+ entry->generator->force_writemask_all;
+ entry->generator->insert_after(block, copy);
+ }
- vec4_instruction *copy = MOV(entry->generator->dst, entry->tmp);
- entry->generator->insert_after(block, copy);
entry->generator->dst = dst_reg(entry->tmp);
}
/* dest <- temp */
if (!inst->dst.is_null()) {
assert(inst->dst.type == entry->tmp.type);
- vec4_instruction *copy = MOV(inst->dst, entry->tmp);
- copy->force_writemask_all = inst->force_writemask_all;
- inst->insert_before(block, copy);
+
+ for (unsigned i = 0; i < regs_written(inst); ++i) {
+ vec4_instruction *copy = MOV(offset(inst->dst, i),
+ offset(entry->tmp, i));
+ copy->force_writemask_all = inst->force_writemask_all;
+ inst->insert_before(block, copy);
+ }
}
/* Set our iterator so that next time through the loop inst->next
* overwrote.
*/
if (inst->dst.file == entry->generator->src[i].file &&
- inst->dst.reg == entry->generator->src[i].reg) {
+ inst->dst.nr == entry->generator->src[i].nr) {
entry->remove();
ralloc_free(entry);
break;
/* Kill any AEB entries using registers that don't get reused any
* more -- a sure sign they'll fail operands_match().
*/
- if (src->file == GRF) {
- assert((src->reg * 4 + 3) < (virtual_grf_count * 4));
-
- int last_reg_use = MAX2(MAX2(virtual_grf_end[src->reg * 4 + 0],
- virtual_grf_end[src->reg * 4 + 1]),
- MAX2(virtual_grf_end[src->reg * 4 + 2],
- virtual_grf_end[src->reg * 4 + 3]));
- if (last_reg_use < ip) {
+ if (src->file == VGRF) {
+ if (var_range_end(var_from_reg(alloc, dst_reg(*src)), 4) < ip) {
entry->remove();
ralloc_free(entry);
break;