nak: Take loops into account in static cycle estimates

This assumes loops get executed 5 times each.  That's not accurate but
we're making estimates here.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36466>
This commit is contained in:
Faith Ekstrand
2025-07-30 10:10:21 -04:00
committed by Marge Bot
parent 0f81dd187f
commit 9f2538f1e7
3 changed files with 16 additions and 4 deletions
+5 -2
View File
@@ -4,6 +4,7 @@
use crate::api::{GetDebugFlags, DEBUG};
use crate::dataflow::ForwardDataflow;
use crate::ir::*;
use crate::opt_instr_sched_common::estimate_block_weight;
use crate::reg_tracker::RegTracker;
use rustc_hash::{FxHashMap, FxHashSet};
@@ -671,7 +672,8 @@ fn assign_barriers(f: &mut Function, sm: &dyn ShaderModel) {
fn calc_delays(f: &mut Function, sm: &dyn ShaderModel) -> u32 {
let mut min_num_static_cycles = 0;
for b in f.blocks.iter_mut().rev() {
for i in (0..f.blocks.len()).rev() {
let b = &mut f.blocks[i];
let mut cycle = 0_u32;
// Vector mapping IP to start cycle
@@ -772,7 +774,8 @@ fn calc_delays(f: &mut Function, sm: &dyn ShaderModel) -> u32 {
cycle = min_start;
}
min_num_static_cycles += cycle;
min_num_static_cycles += cycle * estimate_block_weight(&f.blocks, i);
}
let max_instr_delay = sm.max_instr_delay();
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: MIT
use crate::ir::*;
use compiler::cfg::CFG;
use std::cmp::max;
use std::cmp::Reverse;
@@ -239,6 +240,10 @@ pub fn side_effect_type(op: &Op) -> SideEffect {
}
}
pub fn estimate_block_weight(cfg: &CFG<BasicBlock>, block_idx: usize) -> u32 {
10_u32.pow(cfg.loop_depth(block_idx).try_into().unwrap())
}
/// Try to guess how many cycles a variable latency instruction will take
///
/// These values are based on the cycle estimates from ["Dissecting the NVidia
@@ -223,13 +223,17 @@ fn sched_buffer(
impl Function {
pub fn opt_instr_sched_postpass(&mut self, sm: &dyn ShaderModel) -> u32 {
let mut num_static_cycles = 0;
for block in &mut self.blocks {
for i in 0..self.blocks.len() {
let block = &mut self.blocks[i];
let orig_instr_count = block.instrs.len();
let instrs = std::mem::take(&mut block.instrs);
let (instrs, cycle_count) = sched_buffer(sm, instrs);
block.instrs = instrs.collect();
num_static_cycles += cycle_count;
assert_eq!(orig_instr_count, block.instrs.len());
num_static_cycles +=
cycle_count * estimate_block_weight(&self.blocks, i);
}
num_static_cycles
}