i965/vs: Copy the live intervals calculation over from the FS.

This is a rather pessimistic calculation, since it doesn't distinguish
individual channels of a vec4, or elements of an array, but should be
a minimum start for register allocation.
This commit is contained in:
Eric Anholt 2011-08-16 15:09:48 -07:00
parent eb5454f20a
commit 3dadc1e3cc
4 changed files with 139 additions and 0 deletions

View file

@ -125,6 +125,7 @@ CXX_SOURCES = \
brw_fs_schedule_instructions.cpp \
brw_fs_vector_splitting.cpp \
brw_shader.cpp \
brw_vec4.cpp \
brw_vec4_emit.cpp \
brw_vec4_reg_allocate.cpp \
brw_vec4_visitor.cpp

View file

@ -0,0 +1,130 @@
/*
* Copyright © 2011 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "brw_vec4.h"
extern "C" {
#include "main/macros.h"
#include "program/prog_parameter.h"
}
#define MAX_INSTRUCTION (1 << 30)
namespace brw {
void
vec4_visitor::calculate_live_intervals()
{
int *def = ralloc_array(mem_ctx, int, virtual_grf_count);
int *use = ralloc_array(mem_ctx, int, virtual_grf_count);
int loop_depth = 0;
int loop_start = 0;
if (this->live_intervals_valid)
return;
for (int i = 0; i < virtual_grf_count; i++) {
def[i] = MAX_INSTRUCTION;
use[i] = -1;
}
int ip = 0;
foreach_list(node, &this->instructions) {
vec4_instruction *inst = (vec4_instruction *)node;
if (inst->opcode == BRW_OPCODE_DO) {
if (loop_depth++ == 0)
loop_start = ip;
} else if (inst->opcode == BRW_OPCODE_WHILE) {
loop_depth--;
if (loop_depth == 0) {
/* Patches up the use of vars marked for being live across
* the whole loop.
*/
for (int i = 0; i < virtual_grf_count; i++) {
if (use[i] == loop_start) {
use[i] = ip;
}
}
}
} else {
for (unsigned int i = 0; i < 3; i++) {
if (inst->src[i].file == GRF) {
int reg = inst->src[i].reg;
if (!loop_depth) {
use[reg] = ip;
} else {
def[reg] = MIN2(loop_start, def[reg]);
use[reg] = loop_start;
/* Nobody else is going to go smash our start to
* later in the loop now, because def[reg] now
* points before the bb header.
*/
}
}
}
if (inst->dst.file == GRF) {
int reg = inst->dst.reg;
if (!loop_depth) {
def[reg] = MIN2(def[reg], ip);
} else {
def[reg] = MIN2(def[reg], loop_start);
}
}
}
ip++;
}
ralloc_free(this->virtual_grf_def);
ralloc_free(this->virtual_grf_use);
this->virtual_grf_def = def;
this->virtual_grf_use = use;
this->live_intervals_valid = true;
}
bool
vec4_visitor::virtual_grf_interferes(int a, int b)
{
int start = MAX2(this->virtual_grf_def[a], this->virtual_grf_def[b]);
int end = MIN2(this->virtual_grf_use[a], this->virtual_grf_use[b]);
/* We can't handle dead register writes here, without iterating
* over the whole instruction stream to find every single dead
* write to that register to compare to the live interval of the
* other register. Just assert that dead_code_eliminate() has been
* called.
*/
assert((this->virtual_grf_use[a] != -1 ||
this->virtual_grf_def[a] == MAX_INSTRUCTION) &&
(this->virtual_grf_use[b] != -1 ||
this->virtual_grf_def[b] == MAX_INSTRUCTION));
return start < end;
}
} /* namespace brw */

View file

@ -320,6 +320,9 @@ public:
int virtual_grf_count;
int virtual_grf_array_size;
int first_non_payload_grf;
int *virtual_grf_def;
int *virtual_grf_use;
bool live_intervals_valid;
dst_reg *variable_storage(ir_variable *var);
@ -377,6 +380,8 @@ public:
void reg_allocate_trivial();
void reg_allocate();
void move_grf_array_access_to_scratch();
void calculate_live_intervals();
bool virtual_grf_interferes(int a, int b);
vec4_instruction *emit(enum opcode opcode);

View file

@ -2109,9 +2109,12 @@ vec4_visitor::vec4_visitor(struct brw_vs_compile *c,
hash_table_pointer_hash,
hash_table_pointer_compare);
this->virtual_grf_def = NULL;
this->virtual_grf_use = NULL;
this->virtual_grf_sizes = NULL;
this->virtual_grf_count = 0;
this->virtual_grf_array_size = 0;
this->live_intervals_valid = false;
this->uniforms = 0;