diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/Makefile | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4.cpp | 130 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4.h | 5 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 3 |
4 files changed, 139 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 45a5350a383..d9c885da65b 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -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 diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp new file mode 100644 index 00000000000..a3ed31a9da0 --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp @@ -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 */ diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h index 620b05570a6..77a28c7cda7 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4.h +++ b/src/mesa/drivers/dri/i965/brw_vec4.h @@ -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); diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp index a60fc5f6ada..b3a07bd0539 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp @@ -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; |