{
bool progress = false;
- cfg_t cfg(&v->instructions);
+ v->calculate_cfg();
- for (int b = 0; b < cfg.num_blocks; b++) {
- bblock_t *block = cfg.blocks[b];
+ for (int b = 0; b < v->cfg->num_blocks; b++) {
+ bblock_t *block = v->cfg->blocks[b];
bool found = false;
/* ENDIF instructions, by definition, can only be found at the start of
void assign_constant_locations();
void demote_pull_constants();
void invalidate_live_intervals();
- void calculate_live_intervals(const cfg_t *cfg = NULL);
+ void calculate_live_intervals();
void calculate_register_pressure();
bool opt_algebraic();
bool opt_cse();
{
bool progress = false;
- cfg_t cfg(&instructions);
- calculate_live_intervals(&cfg);
+ calculate_live_intervals();
- for (int b = 0; b < cfg.num_blocks; b++) {
- bblock_t *block = cfg.blocks[b];
+ for (int b = 0; b < cfg->num_blocks; b++) {
+ bblock_t *block = cfg->blocks[b];
progress = opt_cse_local(block) || progress;
}
{
bool progress = false;
- cfg_t cfg(&instructions);
-
- calculate_live_intervals(&cfg);
+ calculate_live_intervals();
int num_vars = live_intervals->num_vars;
BITSET_WORD *live = ralloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
- for (int b = 0; b < cfg.num_blocks; b++) {
- bblock_t *block = cfg.blocks[b];
+ for (int b = 0; b < cfg->num_blocks; b++) {
+ bblock_t *block = cfg->blocks[b];
memcpy(live, live_intervals->bd[b].liveout,
sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
{
ralloc_free(live_intervals);
live_intervals = NULL;
+
+ invalidate_cfg();
}
/**
* information about whole VGRFs.
*/
void
-fs_visitor::calculate_live_intervals(const cfg_t *cfg)
+fs_visitor::calculate_live_intervals()
{
if (this->live_intervals)
return;
virtual_grf_end[i] = -1;
}
- if (cfg) {
- this->live_intervals = new(mem_ctx) fs_live_variables(this, cfg);
- } else {
- cfg_t cfg(&instructions);
- this->live_intervals = new(mem_ctx) fs_live_variables(this, &cfg);
- }
+ calculate_cfg();
+ this->live_intervals = new(mem_ctx) fs_live_variables(this, cfg);
/* Merge the per-component live ranges to whole VGRF live ranges. */
for (int i = 0; i < live_intervals->num_vars; i++) {
{
bool progress = false;
- cfg_t cfg(&instructions);
+ calculate_live_intervals();
- calculate_live_intervals(&cfg);
-
- for (int b = 0; b < cfg.num_blocks; b++) {
- progress = opt_saturate_propagation_local(this, cfg.blocks[b])
+ for (int b = 0; b < cfg->num_blocks; b++) {
+ progress = opt_saturate_propagation_local(this, cfg->blocks[b])
|| progress;
}
(struct brw_shader *)shader_prog->_LinkedShaders[stage] : NULL),
shader_prog(shader_prog),
prog(prog),
- stage_prog_data(stage_prog_data)
+ stage_prog_data(stage_prog_data),
+ cfg(NULL)
{
}
}
}
+void
+backend_visitor::calculate_cfg()
+{
+ if (this->cfg)
+ return;
+ cfg = new(mem_ctx) cfg_t(&this->instructions);
+}
+
+void
+backend_visitor::invalidate_cfg()
+{
+ ralloc_free(this->cfg);
+ this->cfg = NULL;
+}
/**
* Sets up the starting offsets for the groups of binding table entries
*/
exec_list instructions;
+ cfg_t *cfg;
+
virtual void dump_instruction(backend_instruction *inst) = 0;
virtual void dump_instruction(backend_instruction *inst, FILE *file) = 0;
virtual void dump_instructions();
virtual void dump_instructions(const char *name);
+ void calculate_cfg();
+ void invalidate_cfg();
+
void assign_common_binding_table_offsets(uint32_t next_binding_table_offset);
virtual void invalidate_live_intervals() = 0;
* The control flow-aware analysis was done at a channel level, while at
* this point we're distilling it down to vgrfs.
*/
- cfg_t cfg(&instructions);
- vec4_live_variables livevars(this, &cfg);
+ calculate_cfg();
+ vec4_live_variables livevars(this, cfg);
- for (int b = 0; b < cfg.num_blocks; b++) {
+ for (int b = 0; b < cfg->num_blocks; b++) {
for (int i = 0; i < livevars.num_vars; i++) {
if (BITSET_TEST(livevars.bd[b].livein, i)) {
- start[i] = MIN2(start[i], cfg.blocks[b]->start_ip);
- end[i] = MAX2(end[i], cfg.blocks[b]->start_ip);
+ start[i] = MIN2(start[i], cfg->blocks[b]->start_ip);
+ end[i] = MAX2(end[i], cfg->blocks[b]->start_ip);
}
if (BITSET_TEST(livevars.bd[b].liveout, i)) {
- start[i] = MIN2(start[i], cfg.blocks[b]->end_ip);
- end[i] = MAX2(end[i], cfg.blocks[b]->end_ip);
+ start[i] = MIN2(start[i], cfg->blocks[b]->end_ip);
+ end[i] = MAX2(end[i], cfg->blocks[b]->end_ip);
}
}
}
vec4_visitor::invalidate_live_intervals()
{
live_intervals_valid = false;
+
+ invalidate_cfg();
}
bool