+ if (inst->opcode == SHADER_OPCODE_SEND && inst->ex_mlen > 0 &&
+ inst->src[2].file == VGRF && inst->src[3].file == VGRF &&
+ inst->src[2].nr != inst->src[3].nr)
+ ra_add_node_interference(g, first_vgrf_node + inst->src[2].nr,
+ first_vgrf_node + inst->src[3].nr);
+ }
+
+ /* When we do send-from-GRF for FB writes, we need to ensure that the last
+ * write instruction sends from a high register. This is because the
+ * vertex fetcher wants to start filling the low payload registers while
+ * the pixel data port is still working on writing out the memory. If we
+ * don't do this, we get rendering artifacts.
+ *
+ * We could just do "something high". Instead, we just pick the highest
+ * register that works.
+ */
+ if (inst->eot) {
+ const int vgrf = inst->opcode == SHADER_OPCODE_SEND ?
+ inst->src[2].nr : inst->src[0].nr;
+ int size = fs->alloc.sizes[vgrf];
+ int reg = compiler->fs_reg_sets[rsi].class_to_ra_reg_range[size] - 1;
+
+ if (first_mrf_hack_node >= 0) {
+ /* If something happened to spill, we want to push the EOT send
+ * register early enough in the register file that we don't
+ * conflict with any used MRF hack registers.
+ */
+ reg -= BRW_MAX_MRF(devinfo->gen) - spill_base_mrf(fs);
+ } else if (grf127_send_hack_node >= 0) {
+ /* Avoid r127 which might be unusable if the node was previously
+ * written by a SIMD8 SEND message with source/destination overlap.
+ */
+ reg--;
+ }
+
+ ra_set_node_reg(g, first_vgrf_node + vgrf, reg);
+ }
+}
+
+void
+fs_reg_alloc::build_interference_graph(bool allow_spilling)
+{
+ /* Compute the RA node layout */
+ node_count = 0;
+ first_payload_node = node_count;
+ node_count += payload_node_count;
+ if (devinfo->gen >= 7 && allow_spilling) {
+ first_mrf_hack_node = node_count;
+ node_count += BRW_MAX_GRF - GEN7_MRF_HACK_START;
+ } else {
+ first_mrf_hack_node = -1;
+ }
+ if (devinfo->gen >= 8) {
+ grf127_send_hack_node = node_count;
+ node_count ++;
+ } else {
+ grf127_send_hack_node = -1;
+ }
+ first_vgrf_node = node_count;
+ node_count += fs->alloc.count;
+ first_spill_node = node_count;
+
+ fs->calculate_payload_ranges(payload_node_count,
+ payload_last_use_ip);
+
+ assert(g == NULL);
+ g = ra_alloc_interference_graph(compiler->fs_reg_sets[rsi].regs, node_count);
+ ralloc_steal(mem_ctx, g);
+
+ /* Set up the payload nodes */
+ for (int i = 0; i < payload_node_count; i++) {
+ /* Mark each payload node as being allocated to its physical register.
+ *
+ * The alternative would be to have per-physical-register classes, which
+ * would just be silly.
+ */
+ if (devinfo->gen <= 5 && fs->dispatch_width >= 16) {
+ /* We have to divide by 2 here because we only have even numbered
+ * registers. Some of the payload registers will be odd, but
+ * that's ok because their physical register numbers have already
+ * been assigned. The only thing this is used for is interference.
+ */
+ ra_set_node_reg(g, first_payload_node + i, i / 2);
+ } else {
+ ra_set_node_reg(g, first_payload_node + i, i);
+ }
+ }
+
+ if (first_mrf_hack_node >= 0) {
+ /* Mark each MRF reg node as being allocated to its physical
+ * register.
+ *
+ * The alternative would be to have per-physical-register classes,
+ * which would just be silly.
+ */
+ for (int i = 0; i < BRW_MAX_MRF(devinfo->gen); i++) {
+ ra_set_node_reg(g, first_mrf_hack_node + i,
+ GEN7_MRF_HACK_START + i);
+ }
+ }
+
+ if (grf127_send_hack_node >= 0)
+ ra_set_node_reg(g, grf127_send_hack_node, 127);
+
+ /* Specify the classes of each virtual register. */
+ for (unsigned i = 0; i < fs->alloc.count; i++) {
+ unsigned size = fs->alloc.sizes[i];
+
+ assert(size <= ARRAY_SIZE(compiler->fs_reg_sets[rsi].classes) &&
+ "Register allocation relies on split_virtual_grfs()");
+
+ ra_set_node_class(g, first_vgrf_node + i,
+ compiler->fs_reg_sets[rsi].classes[size - 1]);
+ }
+
+ /* Special case: on pre-Gen7 hardware that supports PLN, the second operand
+ * of a PLN instruction needs to be an even-numbered register, so we have a
+ * special register class aligned_bary_class to handle this case.
+ */
+ if (compiler->fs_reg_sets[rsi].aligned_bary_class >= 0) {