diff --git a/src/nouveau/compiler/nak/ir.rs b/src/nouveau/compiler/nak/ir.rs index facb3bce267..bba05b04217 100644 --- a/src/nouveau/compiler/nak/ir.rs +++ b/src/nouveau/compiler/nak/ir.rs @@ -6504,6 +6504,140 @@ impl Op { _ => false, } } + + pub fn has_fixed_latency(&self, sm: u8) -> bool { + match self { + // Float ALU + Op::F2FP(_) + | Op::FAdd(_) + | Op::FFma(_) + | Op::FMnMx(_) + | Op::FMul(_) + | Op::FSet(_) + | Op::FSetP(_) + | Op::HAdd2(_) + | Op::HFma2(_) + | Op::HMul2(_) + | Op::HSet2(_) + | Op::HSetP2(_) + | Op::HMnMx2(_) + | Op::FSwzAdd(_) => true, + + // Multi-function unit is variable latency + Op::Rro(_) | Op::MuFu(_) => false, + + // Double-precision float ALU + Op::DAdd(_) + | Op::DFma(_) + | Op::DMnMx(_) + | Op::DMul(_) + | Op::DSetP(_) => false, + + // Integer ALU + Op::BRev(_) | Op::Flo(_) | Op::PopC(_) => false, + Op::IMad(_) | Op::IMul(_) => sm >= 70, + Op::BMsk(_) + | Op::IAbs(_) + | Op::IAdd2(_) + | Op::IAdd2X(_) + | Op::IAdd3(_) + | Op::IAdd3X(_) + | Op::IDp4(_) + | Op::IMad64(_) + | Op::IMnMx(_) + | Op::ISetP(_) + | Op::Lea(_) + | Op::LeaX(_) + | Op::Lop2(_) + | Op::Lop3(_) + | Op::Shf(_) + | Op::Shl(_) + | Op::Shr(_) + | Op::Bfe(_) => true, + + // Conversions are variable latency?!? + Op::F2F(_) | Op::F2I(_) | Op::I2F(_) | Op::I2I(_) | Op::FRnd(_) => { + false + } + + // Move ops + Op::Mov(_) | Op::Prmt(_) | Op::Sel(_) => true, + Op::Shfl(_) => false, + + // Predicate ops + Op::PLop3(_) | Op::PSetP(_) => true, + + // Uniform ops + Op::R2UR(_) => false, + + // Texture ops + Op::Tex(_) + | Op::Tld(_) + | Op::Tld4(_) + | Op::Tmml(_) + | Op::Txd(_) + | Op::Txq(_) => false, + + // Surface ops + Op::SuLd(_) | Op::SuSt(_) | Op::SuAtom(_) => false, + + // Memory ops + Op::Ld(_) + | Op::Ldc(_) + | Op::St(_) + | Op::Atom(_) + | Op::AL2P(_) + | Op::ALd(_) + | Op::ASt(_) + | Op::Ipa(_) + | Op::CCtl(_) + | Op::LdTram(_) + | Op::MemBar(_) => false, + + // Control-flow ops + Op::BClear(_) | Op::Break(_) | Op::BSSy(_) | Op::BSync(_) => true, + Op::SSy(_) + | Op::Sync(_) + | Op::Brk(_) + | Op::PBk(_) + | Op::Cont(_) + | Op::PCnt(_) => true, + Op::Bra(_) | Op::Exit(_) => true, + Op::WarpSync(_) => false, + + // The barrier half is HW scoreboarded by the GPR isn't. When + // moving from a GPR to a barrier, we still need a token for WaR + // hazards. + Op::BMov(_) => false, + + // Geometry ops + Op::Out(_) | Op::OutFinal(_) => false, + + // Miscellaneous ops + Op::Bar(_) + | Op::CS2R(_) + | Op::Isberd(_) + | Op::Kill(_) + | Op::PixLd(_) + | Op::S2R(_) => false, + Op::Nop(_) | Op::Vote(_) => true, + + // Virtual ops + Op::Undef(_) + | Op::SrcBar(_) + | Op::PhiSrcs(_) + | Op::PhiDsts(_) + | Op::Copy(_) + | Op::Pin(_) + | Op::Unpin(_) + | Op::Swap(_) + | Op::ParCopy(_) + | Op::RegOut(_) + | Op::Annotate(_) => { + panic!("Not a hardware opcode") + } + } + } } #[derive(Clone, Copy, Eq, Hash, PartialEq)] @@ -6869,137 +7003,7 @@ impl Instr { } pub fn has_fixed_latency(&self, sm: u8) -> bool { - match &self.op { - // Float ALU - Op::F2FP(_) - | Op::FAdd(_) - | Op::FFma(_) - | Op::FMnMx(_) - | Op::FMul(_) - | Op::FSet(_) - | Op::FSetP(_) - | Op::HAdd2(_) - | Op::HFma2(_) - | Op::HMul2(_) - | Op::HSet2(_) - | Op::HSetP2(_) - | Op::HMnMx2(_) - | Op::FSwzAdd(_) => true, - - // Multi-function unit is variable latency - Op::Rro(_) | Op::MuFu(_) => false, - - // Double-precision float ALU - Op::DAdd(_) - | Op::DFma(_) - | Op::DMnMx(_) - | Op::DMul(_) - | Op::DSetP(_) => false, - - // Integer ALU - Op::BRev(_) | Op::Flo(_) | Op::PopC(_) => false, - Op::IMad(_) | Op::IMul(_) => sm >= 70, - Op::BMsk(_) - | Op::IAbs(_) - | Op::IAdd2(_) - | Op::IAdd2X(_) - | Op::IAdd3(_) - | Op::IAdd3X(_) - | Op::IDp4(_) - | Op::IMad64(_) - | Op::IMnMx(_) - | Op::ISetP(_) - | Op::Lea(_) - | Op::LeaX(_) - | Op::Lop2(_) - | Op::Lop3(_) - | Op::Shf(_) - | Op::Shl(_) - | Op::Shr(_) - | Op::Bfe(_) => true, - - // Conversions are variable latency?!? - Op::F2F(_) | Op::F2I(_) | Op::I2F(_) | Op::I2I(_) | Op::FRnd(_) => { - false - } - - // Move ops - Op::Mov(_) | Op::Prmt(_) | Op::Sel(_) => true, - Op::Shfl(_) => false, - - // Predicate ops - Op::PLop3(_) | Op::PSetP(_) => true, - - // Uniform ops - Op::R2UR(_) => false, - - // Texture ops - Op::Tex(_) - | Op::Tld(_) - | Op::Tld4(_) - | Op::Tmml(_) - | Op::Txd(_) - | Op::Txq(_) => false, - - // Surface ops - Op::SuLd(_) | Op::SuSt(_) | Op::SuAtom(_) => false, - - // Memory ops - Op::Ld(_) - | Op::Ldc(_) - | Op::St(_) - | Op::Atom(_) - | Op::AL2P(_) - | Op::ALd(_) - | Op::ASt(_) - | Op::Ipa(_) - | Op::CCtl(_) - | Op::LdTram(_) - | Op::MemBar(_) => false, - - // Control-flow ops - Op::BClear(_) | Op::Break(_) | Op::BSSy(_) | Op::BSync(_) => true, - Op::SSy(_) - | Op::Sync(_) - | Op::Brk(_) - | Op::PBk(_) - | Op::Cont(_) - | Op::PCnt(_) => true, - Op::Bra(_) | Op::Exit(_) => true, - Op::WarpSync(_) => false, - - // The barrier half is HW scoreboarded by the GPR isn't. When - // moving from a GPR to a barrier, we still need a token for WaR - // hazards. - Op::BMov(_) => false, - - // Geometry ops - Op::Out(_) | Op::OutFinal(_) => false, - - // Miscellaneous ops - Op::Bar(_) - | Op::CS2R(_) - | Op::Isberd(_) - | Op::Kill(_) - | Op::PixLd(_) - | Op::S2R(_) => false, - Op::Nop(_) | Op::Vote(_) => true, - - // Virtual ops - Op::Undef(_) - | Op::SrcBar(_) - | Op::PhiSrcs(_) - | Op::PhiDsts(_) - | Op::Copy(_) - | Op::Pin(_) - | Op::Unpin(_) - | Op::Swap(_) - | Op::ParCopy(_) - | Op::RegOut(_) - | Op::Annotate(_) => { - panic!("Not a hardware opcode") - } - } + self.op.has_fixed_latency(sm) } pub fn needs_yield(&self) -> bool {