mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
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:
parent
eb5454f20a
commit
3dadc1e3cc
4 changed files with 139 additions and 0 deletions
|
|
@ -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
|
||||
|
|
|
|||
130
src/mesa/drivers/dri/i965/brw_vec4.cpp
Normal file
130
src/mesa/drivers/dri/i965/brw_vec4.cpp
Normal 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 */
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue