Bring many basic types/insts into SPIR-T (instead of leaving them as SPIR-V).
eddyb opened this issue · 0 comments
Right now even e.g. bool
(OpTypeBool
) and its false
/true
constants, are represented through their SPIR-V instructions, and the few places that need to deal with them (e.g. cfg
, print
) work with that directly.
Ideally we would have at least these natively represented in SPIR-T:
- scalar (
bool
,iN
,fN
) types/consts - pure (and "universal") integer/generic ops (
OpI{Add,Sub,Mul,...}
,OpSelect
, etc.)- by "universal" I mostly mean "100% deterministic standard semantics", and so e.g. they can be trivially constant-folded without worrying about any kind of "modifiers"
- pure floating-point ops (but without necessarily assuming their semantics)
- EDIT:
rustc_apfloat
is now available (with license issues resolved) to use as a dependency - also relevant:
SPV_KHR_float_controls
adds entry-point decorations which control floating-point semantics (so they can be used to make decisions, or even give up on constant-folding specifically the cases where that information is lacking, which would still handle a lot of useful cases)
- EDIT:
- memory (load/store) ops
- this is where going further on the convergence with RVSDG would start becoming relevant, because its (linear) "state" dependencies allow seeing "all potential pasts" (e.g. a load instruction can walk up its "(memory) state" input and see all stores that could be relevant, from the same region/function/etc.)
A lot of the more "universal" concepts can be encoded very compactly (by e.g. factoring out "shapes" vs "inputs").
Also potentially relevant: Rust-GPU's SPIR-V type rules already describes many ops' "signatures" (when type-generic).
In order to make this manageable in terms of lower
/lift
(plus e.g. disallowing the SPIR-V instructions that have SPIR-T equivalents - see #2), it would probably be good to have as many of these cases handled by listing the equivalence in a macro that generates conversions both ways (and anything else we need), e.g.:
map_spirv_spirt! {
OpTypeBool <=> TypeCtorKind::Scalar(ScalarType::Bool),
OpConstantFalse <=> ConstCtorKind::Bool(false),
OpConstantTrue <=> ConstCtorKind::Bool(true),
}