mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 20:10:14 +01:00
112 lines
2.9 KiB
C++
112 lines
2.9 KiB
C++
|
|
/*
|
||
|
|
* Copyright © 2010-2012 Intel Corporation
|
||
|
|
* SPDX-License-Identifier: MIT
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "brw_analysis.h"
|
||
|
|
#include "brw_cfg.h"
|
||
|
|
#include "brw_fs.h"
|
||
|
|
|
||
|
|
using namespace brw;
|
||
|
|
|
||
|
|
/* Calculates the immediate dominator of each block, according to "A Simple,
|
||
|
|
* Fast Dominance Algorithm" by Keith D. Cooper, Timothy J. Harvey, and Ken
|
||
|
|
* Kennedy.
|
||
|
|
*
|
||
|
|
* The authors claim that for control flow graphs of sizes normally encountered
|
||
|
|
* (less than 1000 nodes) that this algorithm is significantly faster than
|
||
|
|
* others like Lengauer-Tarjan.
|
||
|
|
*/
|
||
|
|
idom_tree::idom_tree(const fs_visitor *s) :
|
||
|
|
num_parents(s->cfg->num_blocks),
|
||
|
|
parents(new bblock_t *[num_parents]())
|
||
|
|
{
|
||
|
|
bool changed;
|
||
|
|
|
||
|
|
parents[0] = s->cfg->blocks[0];
|
||
|
|
|
||
|
|
do {
|
||
|
|
changed = false;
|
||
|
|
|
||
|
|
foreach_block(block, s->cfg) {
|
||
|
|
if (block->num == 0)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
bblock_t *new_idom = NULL;
|
||
|
|
foreach_list_typed(bblock_link, parent_link, link, &block->parents) {
|
||
|
|
if (parent(parent_link->block)) {
|
||
|
|
new_idom = (new_idom ? intersect(new_idom, parent_link->block) :
|
||
|
|
parent_link->block);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (parent(block) != new_idom) {
|
||
|
|
parents[block->num] = new_idom;
|
||
|
|
changed = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} while (changed);
|
||
|
|
}
|
||
|
|
|
||
|
|
idom_tree::~idom_tree()
|
||
|
|
{
|
||
|
|
delete[] parents;
|
||
|
|
}
|
||
|
|
|
||
|
|
bblock_t *
|
||
|
|
idom_tree::intersect(bblock_t *b1, bblock_t *b2) const
|
||
|
|
{
|
||
|
|
/* Note, the comparisons here are the opposite of what the paper says
|
||
|
|
* because we index blocks from beginning -> end (i.e. reverse post-order)
|
||
|
|
* instead of post-order like they assume.
|
||
|
|
*/
|
||
|
|
while (b1->num != b2->num) {
|
||
|
|
while (b1->num > b2->num)
|
||
|
|
b1 = parent(b1);
|
||
|
|
while (b2->num > b1->num)
|
||
|
|
b2 = parent(b2);
|
||
|
|
}
|
||
|
|
assert(b1);
|
||
|
|
return b1;
|
||
|
|
}
|
||
|
|
|
||
|
|
void
|
||
|
|
idom_tree::dump(FILE *file) const
|
||
|
|
{
|
||
|
|
fprintf(file, "digraph DominanceTree {\n");
|
||
|
|
for (unsigned i = 0; i < num_parents; i++)
|
||
|
|
fprintf(file, "\t%d -> %d\n", parents[i]->num, i);
|
||
|
|
fprintf(file, "}\n");
|
||
|
|
}
|
||
|
|
|
||
|
|
register_pressure::register_pressure(const fs_visitor *v)
|
||
|
|
{
|
||
|
|
const fs_live_variables &live = v->live_analysis.require();
|
||
|
|
const unsigned num_instructions = v->cfg->num_blocks ?
|
||
|
|
v->cfg->blocks[v->cfg->num_blocks - 1]->end_ip + 1 : 0;
|
||
|
|
|
||
|
|
regs_live_at_ip = new unsigned[num_instructions]();
|
||
|
|
|
||
|
|
for (unsigned reg = 0; reg < v->alloc.count; reg++) {
|
||
|
|
for (int ip = live.vgrf_start[reg]; ip <= live.vgrf_end[reg]; ip++)
|
||
|
|
regs_live_at_ip[ip] += v->alloc.sizes[reg];
|
||
|
|
}
|
||
|
|
|
||
|
|
const unsigned payload_count = v->first_non_payload_grf;
|
||
|
|
|
||
|
|
int *payload_last_use_ip = new int[payload_count];
|
||
|
|
v->calculate_payload_ranges(true, payload_count, payload_last_use_ip);
|
||
|
|
|
||
|
|
for (unsigned reg = 0; reg < payload_count; reg++) {
|
||
|
|
for (int ip = 0; ip < payload_last_use_ip[reg]; ip++)
|
||
|
|
++regs_live_at_ip[ip];
|
||
|
|
}
|
||
|
|
|
||
|
|
delete[] payload_last_use_ip;
|
||
|
|
}
|
||
|
|
|
||
|
|
register_pressure::~register_pressure()
|
||
|
|
{
|
||
|
|
delete[] regs_live_at_ip;
|
||
|
|
}
|