i965: Add and use foreach_block macro.

Use this as an opportunity to rename 'block_num' to 'num'. block->num is
clear, and block->block_num has always been redundant.
This commit is contained in:
Matt Turner 2014-07-11 22:31:39 -07:00
parent d688667c7f
commit 596990d91e
14 changed files with 119 additions and 143 deletions

View File

@ -51,7 +51,7 @@ link(void *mem_ctx, bblock_t *block)
} }
bblock_t::bblock_t() : bblock_t::bblock_t() :
start_ip(0), end_ip(0), block_num(0) start_ip(0), end_ip(0), num(0)
{ {
start = NULL; start = NULL;
end = NULL; end = NULL;
@ -284,7 +284,7 @@ cfg_t::set_next_block(bblock_t **cur, bblock_t *block, int ip)
} }
block->start_ip = ip; block->start_ip = ip;
block->block_num = num_blocks++; block->num = num_blocks++;
block_list.push_tail(&block->link); block_list.push_tail(&block->link);
*cur = block; *cur = block;
} }
@ -295,7 +295,7 @@ cfg_t::make_block_array()
blocks = ralloc_array(mem_ctx, bblock_t *, num_blocks); blocks = ralloc_array(mem_ctx, bblock_t *, num_blocks);
int i = 0; int i = 0;
foreach_list_typed(bblock_t, block, link, &block_list) { foreach_block (block, this) {
blocks[i++] = block; blocks[i++] = block;
} }
assert(i == num_blocks); assert(i == num_blocks);
@ -304,19 +304,18 @@ cfg_t::make_block_array()
void void
cfg_t::dump(backend_visitor *v) cfg_t::dump(backend_visitor *v)
{ {
for (int b = 0; b < this->num_blocks; b++) { foreach_block (block, this) {
bblock_t *block = this->blocks[b]; fprintf(stderr, "START B%d", block->num);
fprintf(stderr, "START B%d", b);
foreach_list_typed(bblock_link, link, link, &block->parents) { foreach_list_typed(bblock_link, link, link, &block->parents) {
fprintf(stderr, " <-B%d", fprintf(stderr, " <-B%d",
link->block->block_num); link->block->num);
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
block->dump(v); block->dump(v);
fprintf(stderr, "END B%d", b); fprintf(stderr, "END B%d", block->num);
foreach_list_typed(bblock_link, link, link, &block->children) { foreach_list_typed(bblock_link, link, link, &block->children) {
fprintf(stderr, " ->B%d", fprintf(stderr, " ->B%d",
link->block->block_num); link->block->num);
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }

View File

@ -71,7 +71,7 @@ struct bblock_t {
struct exec_list parents; struct exec_list parents;
struct exec_list children; struct exec_list children;
int block_num; int num;
/* If the current basic block ends in an IF, ELSE, or ENDIF instruction, /* If the current basic block ends in an IF, ELSE, or ENDIF instruction,
* these pointers will hold the locations of the other associated control * these pointers will hold the locations of the other associated control
@ -109,6 +109,9 @@ struct cfg_t {
foreach_block (__block, __cfg) \ foreach_block (__block, __cfg) \
foreach_inst_in_block (__type, __inst, __block) foreach_inst_in_block (__type, __inst, __block)
#define foreach_block(__block, __cfg) \
foreach_list_typed (bblock_t, __block, link, &(__cfg)->block_list)
#define foreach_inst_in_block(__type, __inst, __block) \ #define foreach_inst_in_block(__type, __inst, __block) \
for (__type *__inst = (__type *)__block->start; \ for (__type *__inst = (__type *)__block->start; \
__inst != __block->end->next; \ __inst != __block->end->next; \

View File

@ -42,8 +42,7 @@ dead_control_flow_eliminate(backend_visitor *v)
v->calculate_cfg(); v->calculate_cfg();
for (int b = 0; b < v->cfg->num_blocks; b++) { foreach_block (block, v->cfg) {
bblock_t *block = v->cfg->blocks[b];
bool found = false; bool found = false;
/* ENDIF instructions, by definition, can only be found at the start of /* ENDIF instructions, by definition, can only be found at the start of

View File

@ -104,9 +104,9 @@ fs_copy_prop_dataflow::fs_copy_prop_dataflow(void *mem_ctx, cfg_t *cfg,
bd = rzalloc_array(mem_ctx, struct block_data, cfg->num_blocks); bd = rzalloc_array(mem_ctx, struct block_data, cfg->num_blocks);
num_acp = 0; num_acp = 0;
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
for (int i = 0; i < ACP_HASH_SIZE; i++) { for (int i = 0; i < ACP_HASH_SIZE; i++) {
num_acp += out_acp[b][i].length(); num_acp += out_acp[block->num][i].length();
} }
} }
@ -115,21 +115,21 @@ fs_copy_prop_dataflow::fs_copy_prop_dataflow(void *mem_ctx, cfg_t *cfg,
bitset_words = BITSET_WORDS(num_acp); bitset_words = BITSET_WORDS(num_acp);
int next_acp = 0; int next_acp = 0;
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bd[b].livein = rzalloc_array(bd, BITSET_WORD, bitset_words); bd[block->num].livein = rzalloc_array(bd, BITSET_WORD, bitset_words);
bd[b].liveout = rzalloc_array(bd, BITSET_WORD, bitset_words); bd[block->num].liveout = rzalloc_array(bd, BITSET_WORD, bitset_words);
bd[b].copy = rzalloc_array(bd, BITSET_WORD, bitset_words); bd[block->num].copy = rzalloc_array(bd, BITSET_WORD, bitset_words);
bd[b].kill = rzalloc_array(bd, BITSET_WORD, bitset_words); bd[block->num].kill = rzalloc_array(bd, BITSET_WORD, bitset_words);
for (int i = 0; i < ACP_HASH_SIZE; i++) { for (int i = 0; i < ACP_HASH_SIZE; i++) {
foreach_in_list(acp_entry, entry, &out_acp[b][i]) { foreach_in_list(acp_entry, entry, &out_acp[block->num][i]) {
acp[next_acp] = entry; acp[next_acp] = entry;
/* opt_copy_propagate_local populates out_acp with copies created /* opt_copy_propagate_local populates out_acp with copies created
* in a block which are still live at the end of the block. This * in a block which are still live at the end of the block. This
* is exactly what we want in the COPY set. * is exactly what we want in the COPY set.
*/ */
BITSET_SET(bd[b].copy, next_acp); BITSET_SET(bd[block->num].copy, next_acp);
next_acp++; next_acp++;
} }
@ -150,9 +150,7 @@ void
fs_copy_prop_dataflow::setup_initial_values() fs_copy_prop_dataflow::setup_initial_values()
{ {
/* Initialize the COPY and KILL sets. */ /* Initialize the COPY and KILL sets. */
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b];
foreach_inst_in_block(fs_inst, inst, block) { foreach_inst_in_block(fs_inst, inst, block) {
if (inst->dst.file != GRF) if (inst->dst.file != GRF)
continue; continue;
@ -161,7 +159,7 @@ fs_copy_prop_dataflow::setup_initial_values()
for (int i = 0; i < num_acp; i++) { for (int i = 0; i < num_acp; i++) {
if (inst->overwrites_reg(acp[i]->dst) || if (inst->overwrites_reg(acp[i]->dst) ||
inst->overwrites_reg(acp[i]->src)) { inst->overwrites_reg(acp[i]->src)) {
BITSET_SET(bd[b].kill, i); BITSET_SET(bd[block->num].kill, i);
} }
} }
} }
@ -172,17 +170,16 @@ fs_copy_prop_dataflow::setup_initial_values()
* For the others, set liveout to 0 (the empty set) and livein to ~0 * For the others, set liveout to 0 (the empty set) and livein to ~0
* (the universal set). * (the universal set).
*/ */
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b];
if (block->parents.is_empty()) { if (block->parents.is_empty()) {
for (int i = 0; i < bitset_words; i++) { for (int i = 0; i < bitset_words; i++) {
bd[b].livein[i] = 0u; bd[block->num].livein[i] = 0u;
bd[b].liveout[i] = bd[b].copy[i]; bd[block->num].liveout[i] = bd[block->num].copy[i];
} }
} else { } else {
for (int i = 0; i < bitset_words; i++) { for (int i = 0; i < bitset_words; i++) {
bd[b].liveout[i] = 0u; bd[block->num].liveout[i] = 0u;
bd[b].livein[i] = ~0u; bd[block->num].livein[i] = ~0u;
} }
} }
} }
@ -201,17 +198,18 @@ fs_copy_prop_dataflow::run()
progress = false; progress = false;
/* Update liveout for all blocks. */ /* Update liveout for all blocks. */
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
if (cfg->blocks[b]->parents.is_empty()) if (block->parents.is_empty())
continue; continue;
for (int i = 0; i < bitset_words; i++) { for (int i = 0; i < bitset_words; i++) {
const BITSET_WORD old_liveout = bd[b].liveout[i]; const BITSET_WORD old_liveout = bd[block->num].liveout[i];
bd[b].liveout[i] = bd[block->num].liveout[i] =
bd[b].copy[i] | (bd[b].livein[i] & ~bd[b].kill[i]); bd[block->num].copy[i] | (bd[block->num].livein[i] &
~bd[block->num].kill[i]);
if (old_liveout != bd[b].liveout[i]) if (old_liveout != bd[block->num].liveout[i])
progress = true; progress = true;
} }
} }
@ -219,20 +217,20 @@ fs_copy_prop_dataflow::run()
/* Update livein for all blocks. If a copy is live out of all parent /* Update livein for all blocks. If a copy is live out of all parent
* blocks, it's live coming in to this block. * blocks, it's live coming in to this block.
*/ */
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
if (cfg->blocks[b]->parents.is_empty()) if (block->parents.is_empty())
continue; continue;
for (int i = 0; i < bitset_words; i++) { for (int i = 0; i < bitset_words; i++) {
const BITSET_WORD old_livein = bd[b].livein[i]; const BITSET_WORD old_livein = bd[block->num].livein[i];
bd[b].livein[i] = ~0u; bd[block->num].livein[i] = ~0u;
foreach_list_typed(bblock_link, link, link, &cfg->blocks[b]->parents) { foreach_list_typed(bblock_link, parent_link, link, &block->parents) {
bblock_t *block = link->block; bblock_t *parent = parent_link->block;
bd[b].livein[i] &= bd[block->block_num].liveout[i]; bd[block->num].livein[i] &= bd[parent->num].liveout[i];
} }
if (old_livein != bd[b].livein[i]) if (old_livein != bd[block->num].livein[i])
progress = true; progress = true;
} }
} }
@ -242,27 +240,26 @@ fs_copy_prop_dataflow::run()
void void
fs_copy_prop_dataflow::dump_block_data() const fs_copy_prop_dataflow::dump_block_data() const
{ {
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b]; fprintf(stderr, "Block %d [%d, %d] (parents ", block->num,
fprintf(stderr, "Block %d [%d, %d] (parents ", block->block_num,
block->start_ip, block->end_ip); block->start_ip, block->end_ip);
foreach_list_typed(bblock_link, link, link, &block->parents) { foreach_list_typed(bblock_link, link, link, &block->parents) {
bblock_t *parent = link->block; bblock_t *parent = link->block;
fprintf(stderr, "%d ", parent->block_num); fprintf(stderr, "%d ", parent->num);
} }
fprintf(stderr, "):\n"); fprintf(stderr, "):\n");
fprintf(stderr, " livein = 0x"); fprintf(stderr, " livein = 0x");
for (int i = 0; i < bitset_words; i++) for (int i = 0; i < bitset_words; i++)
fprintf(stderr, "%08x", bd[b].livein[i]); fprintf(stderr, "%08x", bd[block->num].livein[i]);
fprintf(stderr, ", liveout = 0x"); fprintf(stderr, ", liveout = 0x");
for (int i = 0; i < bitset_words; i++) for (int i = 0; i < bitset_words; i++)
fprintf(stderr, "%08x", bd[b].liveout[i]); fprintf(stderr, "%08x", bd[block->num].liveout[i]);
fprintf(stderr, ",\n copy = 0x"); fprintf(stderr, ",\n copy = 0x");
for (int i = 0; i < bitset_words; i++) for (int i = 0; i < bitset_words; i++)
fprintf(stderr, "%08x", bd[b].copy[i]); fprintf(stderr, "%08x", bd[block->num].copy[i]);
fprintf(stderr, ", kill = 0x"); fprintf(stderr, ", kill = 0x");
for (int i = 0; i < bitset_words; i++) for (int i = 0; i < bitset_words; i++)
fprintf(stderr, "%08x", bd[b].kill[i]); fprintf(stderr, "%08x", bd[block->num].kill[i]);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
} }
@ -607,11 +604,9 @@ fs_visitor::opt_copy_propagate()
/* First, walk through each block doing local copy propagation and getting /* First, walk through each block doing local copy propagation and getting
* the set of copies available at the end of the block. * the set of copies available at the end of the block.
*/ */
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b];
progress = opt_copy_propagate_local(copy_prop_ctx, block, progress = opt_copy_propagate_local(copy_prop_ctx, block,
out_acp[b]) || progress; out_acp[block->num]) || progress;
} }
/* Do dataflow analysis for those available copies. */ /* Do dataflow analysis for those available copies. */
@ -620,12 +615,11 @@ fs_visitor::opt_copy_propagate()
/* Next, re-run local copy propagation, this time with the set of copies /* Next, re-run local copy propagation, this time with the set of copies
* provided by the dataflow analysis available at the start of a block. * provided by the dataflow analysis available at the start of a block.
*/ */
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b];
exec_list in_acp[ACP_HASH_SIZE]; exec_list in_acp[ACP_HASH_SIZE];
for (int i = 0; i < dataflow.num_acp; i++) { for (int i = 0; i < dataflow.num_acp; i++) {
if (BITSET_TEST(dataflow.bd[b].livein, i)) { if (BITSET_TEST(dataflow.bd[block->num].livein, i)) {
struct acp_entry *entry = dataflow.acp[i]; struct acp_entry *entry = dataflow.acp[i];
in_acp[entry->dst.reg % ACP_HASH_SIZE].push_tail(entry); in_acp[entry->dst.reg % ACP_HASH_SIZE].push_tail(entry);
} }

View File

@ -316,9 +316,7 @@ fs_visitor::opt_cse()
calculate_live_intervals(); calculate_live_intervals();
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b];
progress = opt_cse_local(block) || progress; progress = opt_cse_local(block) || progress;
} }

View File

@ -44,9 +44,8 @@ fs_visitor::dead_code_eliminate()
int num_vars = live_intervals->num_vars; int num_vars = live_intervals->num_vars;
BITSET_WORD *live = ralloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars)); BITSET_WORD *live = ralloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b]; memcpy(live, live_intervals->bd[block->num].liveout,
memcpy(live, live_intervals->bd[b].liveout,
sizeof(BITSET_WORD) * BITSET_WORDS(num_vars)); sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
foreach_inst_in_block_reverse(fs_inst, inst, block) { foreach_inst_in_block_reverse(fs_inst, inst, block) {

View File

@ -100,8 +100,8 @@ fs_live_variables::setup_one_read(bblock_t *block, fs_inst *inst,
* channel) without having completely defined that variable within the * channel) without having completely defined that variable within the
* block. * block.
*/ */
if (!BITSET_TEST(bd[block->block_num].def, var)) if (!BITSET_TEST(bd[block->num].def, var))
BITSET_SET(bd[block->block_num].use, var); BITSET_SET(bd[block->num].use, var);
} }
void void
@ -118,8 +118,8 @@ fs_live_variables::setup_one_write(bblock_t *block, fs_inst *inst,
* screens off previous updates of that variable (VGRF channel). * screens off previous updates of that variable (VGRF channel).
*/ */
if (inst->dst.file == GRF && !inst->is_partial_write()) { if (inst->dst.file == GRF && !inst->is_partial_write()) {
if (!BITSET_TEST(bd[block->block_num].use, var)) if (!BITSET_TEST(bd[block->num].use, var))
BITSET_SET(bd[block->block_num].def, var); BITSET_SET(bd[block->num].def, var);
} }
} }
@ -137,12 +137,10 @@ fs_live_variables::setup_def_use()
{ {
int ip = 0; int ip = 0;
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b];
assert(ip == block->start_ip); assert(ip == block->start_ip);
if (b > 0) if (block->num > 0)
assert(cfg->blocks[b - 1]->end_ip == ip - 1); assert(cfg->blocks[block->num - 1]->end_ip == ip - 1);
foreach_inst_in_block(fs_inst, inst, block) { foreach_inst_in_block(fs_inst, inst, block) {
/* Set use[] for this instruction */ /* Set use[] for this instruction */
@ -186,26 +184,27 @@ fs_live_variables::compute_live_variables()
while (cont) { while (cont) {
cont = false; cont = false;
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
/* Update livein */ /* Update livein */
for (int i = 0; i < bitset_words; i++) { for (int i = 0; i < bitset_words; i++) {
BITSET_WORD new_livein = (bd[b].use[i] | BITSET_WORD new_livein = (bd[block->num].use[i] |
(bd[b].liveout[i] & ~bd[b].def[i])); (bd[block->num].liveout[i] &
if (new_livein & ~bd[b].livein[i]) { ~bd[block->num].def[i]));
bd[b].livein[i] |= new_livein; if (new_livein & ~bd[block->num].livein[i]) {
bd[block->num].livein[i] |= new_livein;
cont = true; cont = true;
} }
} }
/* Update liveout */ /* Update liveout */
foreach_list_typed(bblock_link, link, link, &cfg->blocks[b]->children) { foreach_list_typed(bblock_link, child_link, link, &block->children) {
bblock_t *block = link->block; bblock_t *child = child_link->block;
for (int i = 0; i < bitset_words; i++) { for (int i = 0; i < bitset_words; i++) {
BITSET_WORD new_liveout = (bd[block->block_num].livein[i] & BITSET_WORD new_liveout = (bd[child->num].livein[i] &
~bd[b].liveout[i]); ~bd[block->num].liveout[i]);
if (new_liveout) { if (new_liveout) {
bd[b].liveout[i] |= new_liveout; bd[block->num].liveout[i] |= new_liveout;
cont = true; cont = true;
} }
} }
@ -221,16 +220,16 @@ fs_live_variables::compute_live_variables()
void void
fs_live_variables::compute_start_end() fs_live_variables::compute_start_end()
{ {
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
for (int i = 0; i < num_vars; i++) { for (int i = 0; i < num_vars; i++) {
if (BITSET_TEST(bd[b].livein, i)) { if (BITSET_TEST(bd[block->num].livein, i)) {
start[i] = MIN2(start[i], cfg->blocks[b]->start_ip); start[i] = MIN2(start[i], block->start_ip);
end[i] = MAX2(end[i], cfg->blocks[b]->start_ip); end[i] = MAX2(end[i], block->start_ip);
} }
if (BITSET_TEST(bd[b].liveout, i)) { if (BITSET_TEST(bd[block->num].liveout, i)) {
start[i] = MIN2(start[i], cfg->blocks[b]->end_ip); start[i] = MIN2(start[i], block->end_ip);
end[i] = MAX2(end[i], cfg->blocks[b]->end_ip); end[i] = MAX2(end[i], block->end_ip);
} }
} }

View File

@ -47,9 +47,7 @@ fs_visitor::opt_peephole_predicated_break()
calculate_cfg(); calculate_cfg();
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b];
/* BREAK and CONTINUE instructions, by definition, can only be found at /* BREAK and CONTINUE instructions, by definition, can only be found at
* the ends of basic blocks. * the ends of basic blocks.
*/ */
@ -81,11 +79,6 @@ fs_visitor::opt_peephole_predicated_break()
if_inst->remove(); if_inst->remove();
endif_inst->remove(); endif_inst->remove();
/* By removing the ENDIF instruction we removed a basic block. Skip over
* it for the next iteration.
*/
b++;
progress = true; progress = true;
} }

View File

@ -95,9 +95,8 @@ fs_visitor::opt_saturate_propagation()
calculate_live_intervals(); calculate_live_intervals();
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
progress = opt_saturate_propagation_local(this, cfg->blocks[b]) progress = opt_saturate_propagation_local(this, block) || progress;
|| progress;
} }
if (progress) if (progress)

View File

@ -129,9 +129,7 @@ fs_visitor::opt_peephole_sel()
calculate_cfg(); calculate_cfg();
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b];
/* IF instructions, by definition, can only be found at the ends of /* IF instructions, by definition, can only be found at the ends of
* basic blocks. * basic blocks.
*/ */

View File

@ -753,13 +753,11 @@ vec4_visitor::opt_set_dependency_control()
assert(prog_data->total_grf || assert(prog_data->total_grf ||
!"Must be called after register allocation"); !"Must be called after register allocation");
for (int i = 0; i < cfg->num_blocks; i++) { foreach_block (block, cfg) {
bblock_t *bblock = cfg->blocks[i];
memset(last_grf_write, 0, sizeof(last_grf_write)); memset(last_grf_write, 0, sizeof(last_grf_write));
memset(last_mrf_write, 0, sizeof(last_mrf_write)); memset(last_mrf_write, 0, sizeof(last_mrf_write));
foreach_inst_in_block (vec4_instruction, inst, bblock) { foreach_inst_in_block (vec4_instruction, inst, block) {
/* If we read from a register that we were doing dependency control /* If we read from a register that we were doing dependency control
* on, don't do dependency control across the read. * on, don't do dependency control across the read.
*/ */

View File

@ -251,9 +251,7 @@ vec4_visitor::opt_cse()
calculate_live_intervals(); calculate_live_intervals();
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b];
progress = opt_cse_local(block) || progress; progress = opt_cse_local(block) || progress;
} }

View File

@ -65,12 +65,10 @@ vec4_live_variables::setup_def_use()
{ {
int ip = 0; int ip = 0;
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
bblock_t *block = cfg->blocks[b];
assert(ip == block->start_ip); assert(ip == block->start_ip);
if (b > 0) if (block->num > 0)
assert(cfg->blocks[b - 1]->end_ip == ip - 1); assert(cfg->blocks[block->num - 1]->end_ip == ip - 1);
foreach_inst_in_block(vec4_instruction, inst, block) { foreach_inst_in_block(vec4_instruction, inst, block) {
/* Set use[] for this instruction */ /* Set use[] for this instruction */
@ -80,8 +78,8 @@ vec4_live_variables::setup_def_use()
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
int c = BRW_GET_SWZ(inst->src[i].swizzle, j); int c = BRW_GET_SWZ(inst->src[i].swizzle, j);
if (!BITSET_TEST(bd[b].def, reg * 4 + c)) if (!BITSET_TEST(bd[block->num].def, reg * 4 + c))
BITSET_SET(bd[b].use, reg * 4 + c); BITSET_SET(bd[block->num].use, reg * 4 + c);
} }
} }
} }
@ -96,8 +94,8 @@ vec4_live_variables::setup_def_use()
for (int c = 0; c < 4; c++) { for (int c = 0; c < 4; c++) {
if (inst->dst.writemask & (1 << c)) { if (inst->dst.writemask & (1 << c)) {
int reg = inst->dst.reg; int reg = inst->dst.reg;
if (!BITSET_TEST(bd[b].use, reg * 4 + c)) if (!BITSET_TEST(bd[block->num].use, reg * 4 + c))
BITSET_SET(bd[b].def, reg * 4 + c); BITSET_SET(bd[block->num].def, reg * 4 + c);
} }
} }
} }
@ -121,26 +119,27 @@ vec4_live_variables::compute_live_variables()
while (cont) { while (cont) {
cont = false; cont = false;
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
/* Update livein */ /* Update livein */
for (int i = 0; i < bitset_words; i++) { for (int i = 0; i < bitset_words; i++) {
BITSET_WORD new_livein = (bd[b].use[i] | BITSET_WORD new_livein = (bd[block->num].use[i] |
(bd[b].liveout[i] & ~bd[b].def[i])); (bd[block->num].liveout[i] &
if (new_livein & ~bd[b].livein[i]) { ~bd[block->num].def[i]));
bd[b].livein[i] |= new_livein; if (new_livein & ~bd[block->num].livein[i]) {
bd[block->num].livein[i] |= new_livein;
cont = true; cont = true;
} }
} }
/* Update liveout */ /* Update liveout */
foreach_list_typed(bblock_link, link, link, &cfg->blocks[b]->children) { foreach_list_typed(bblock_link, child_link, link, &block->children) {
bblock_t *block = link->block; bblock_t *child = child_link->block;
for (int i = 0; i < bitset_words; i++) { for (int i = 0; i < bitset_words; i++) {
BITSET_WORD new_liveout = (bd[block->block_num].livein[i] & BITSET_WORD new_liveout = (bd[child->num].livein[i] &
~bd[b].liveout[i]); ~bd[block->num].liveout[i]);
if (new_liveout) { if (new_liveout) {
bd[b].liveout[i] |= new_liveout; bd[block->num].liveout[i] |= new_liveout;
cont = true; cont = true;
} }
} }
@ -251,16 +250,16 @@ vec4_visitor::calculate_live_intervals()
calculate_cfg(); calculate_cfg();
vec4_live_variables livevars(this, cfg); vec4_live_variables livevars(this, cfg);
for (int b = 0; b < cfg->num_blocks; b++) { foreach_block (block, cfg) {
for (int i = 0; i < livevars.num_vars; i++) { for (int i = 0; i < livevars.num_vars; i++) {
if (BITSET_TEST(livevars.bd[b].livein, i)) { if (BITSET_TEST(livevars.bd[block->num].livein, i)) {
start[i] = MIN2(start[i], cfg->blocks[b]->start_ip); start[i] = MIN2(start[i], block->start_ip);
end[i] = MAX2(end[i], cfg->blocks[b]->start_ip); end[i] = MAX2(end[i], block->start_ip);
} }
if (BITSET_TEST(livevars.bd[b].liveout, i)) { if (BITSET_TEST(livevars.bd[block->num].liveout, i)) {
start[i] = MIN2(start[i], cfg->blocks[b]->end_ip); start[i] = MIN2(start[i], block->end_ip);
end[i] = MAX2(end[i], cfg->blocks[b]->end_ip); end[i] = MAX2(end[i], block->end_ip);
} }
} }
} }

View File

@ -42,11 +42,11 @@ dump_assembly(void *assembly, int num_annotations, struct annotation *annotation
int end_offset = annotation[i + 1].offset; int end_offset = annotation[i + 1].offset;
if (annotation[i].block_start) { if (annotation[i].block_start) {
fprintf(stderr, " START B%d", annotation[i].block_start->block_num); fprintf(stderr, " START B%d", annotation[i].block_start->num);
foreach_list_typed(struct bblock_link, predecessor_link, link, foreach_list_typed(struct bblock_link, predecessor_link, link,
&annotation[i].block_start->parents) { &annotation[i].block_start->parents) {
struct bblock_t *predecessor_block = predecessor_link->block; struct bblock_t *predecessor_block = predecessor_link->block;
fprintf(stderr, " <-B%d", predecessor_block->block_num); fprintf(stderr, " <-B%d", predecessor_block->num);
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
@ -79,11 +79,11 @@ dump_assembly(void *assembly, int num_annotations, struct annotation *annotation
brw_disassemble(brw, assembly, start_offset, end_offset, stderr); brw_disassemble(brw, assembly, start_offset, end_offset, stderr);
if (annotation[i].block_end) { if (annotation[i].block_end) {
fprintf(stderr, " END B%d", annotation[i].block_end->block_num); fprintf(stderr, " END B%d", annotation[i].block_end->num);
foreach_list_typed(struct bblock_link, successor_link, link, foreach_list_typed(struct bblock_link, successor_link, link,
&annotation[i].block_end->children) { &annotation[i].block_end->children) {
struct bblock_t *successor_block = successor_link->block; struct bblock_t *successor_block = successor_link->block;
fprintf(stderr, " ->B%d", successor_block->block_num); fprintf(stderr, " ->B%d", successor_block->num);
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }