Skip to content
This repository was archived by the owner on Jun 1, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5511dcd
Add `ConstKind::Undef` (i.e. SPIR-V `OpUndef`).
eddyb Oct 16, 2023
0a64880
Add `TypeKind::Scalar`&`ConstKind::Scalar` for bool/int/float types&c…
eddyb Oct 16, 2023
f31e5a2
Add `DataInstKind::Scalar` for pure scalars->scalars ops.
eddyb Oct 23, 2023
ad22784
Add `SelectionKind::Switch`, using one `scalar::Const` for each case'…
eddyb Nov 7, 2023
f61e300
WIP: OpSpecConstantOp
eddyb Nov 20, 2023
44faddc
Add `TypeKind::Vector`&`ConstKind::Scalar` for vector types&consts.
eddyb Nov 4, 2023
b349dea
Add `DataInstKind::Vector` for pure vector ops.
eddyb Nov 5, 2023
74fde56
qptr/analyze: fix some latent issues in merging, caused by ZSTs.
eddyb Oct 1, 2023
d4b0eb0
qptr/analyze: don't panic on oddball `Const` pointers.
eddyb Nov 7, 2023
44cf1cd
qptr: add an immediate `offset` to `Load`/`Store` ops.
eddyb Oct 1, 2023
145051e
qptr/lower: more aggressively strip `Offset(0)` and remove unused ins…
eddyb Oct 1, 2023
53c6cec
spv/lift: abandon `Result` for allocating IDs and do it far more eage…
eddyb Oct 1, 2023
22c8b95
spv/lower: don't assign IDs ahead of time.
eddyb Oct 1, 2023
d710313
spv: disaggregate by-value `OpTypeStruct`/`OpTypeArray` inputs/outputs.
eddyb Oct 1, 2023
fcc57bd
qptr/lower: expand aggregate `Op{Load,Store}` into leaf loads/stores.
eddyb Oct 1, 2023
d4a9443
qptr/lower: expand `OpCopyMemory` into leaf loads+stores (in the abse…
eddyb Oct 1, 2023
830b4e8
print: attempt to improve `GlobalVar` printing by using named arguments.
eddyb Oct 5, 2023
c61d096
[WIP] GV init disaggregate
eddyb Oct 3, 2023
d5824f1
qptr/lower: minimally support opaque handle `OpVariable`s.
eddyb Oct 1, 2023
9ed8a3b
qptr/layout: allow `qptr`s to have a memory layout (and thus be loade…
eddyb Oct 1, 2023
a8506cc
[WIP] qptr/simplify: add "partition" and "propagate" passes for funct…
eddyb Oct 1, 2023
4fce1b7
[WIP] add `flow` analysis framework experiment.
eddyb Oct 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,17 +135,17 @@ fn main() -> @location(0) i32 {
```cxx
#[spv.Decoration.Flat]
#[spv.Decoration.Location(Location: 0)]
global_var GV0 in spv.StorageClass.Output: s32
global_var GV0(spv.StorageClass.Output): s32

func F0() -> spv.OpTypeVoid {
func F0() {
loop(v0: s32 <- 1s32, v1: s32 <- 1s32) {
v2 = spv.OpSLessThan(v1, 10s32): bool
v2 = s.lt(v1, 10s32): bool
(v3: s32, v4: s32) = if v2 {
v5 = spv.OpIMul(v0, v1): s32
v6 = spv.OpIAdd(v1, 1s32): s32
v5 = i.mul(v0, v1): s32
v6 = i.add(v1, 1s32): s32
(v5, v6)
} else {
(spv.OpUndef: s32, spv.OpUndef: s32)
(undef: s32, undef: s32)
}
(v3, v4) -> (v0, v1)
} while v2
Expand Down
6 changes: 6 additions & 0 deletions examples/spv-lower-link-qptr-lift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ fn main() -> std::io::Result<()> {
eprintln!("qptr::lower_from_spv_ptrs");
after_pass("qptr::lower_from_spv_ptrs", &module)?;

eprint_duration(|| {
spirt::passes::qptr::partition_and_propagate(&mut module, layout_config)
});
eprintln!("qptr::partition_and_propagate");
after_pass("qptr::partition_and_propagate", &module)?;

eprint_duration(|| spirt::passes::qptr::analyze_uses(&mut module, layout_config));
eprintln!("qptr::analyze_uses");
after_pass("qptr::analyze_uses", &module)?;
Expand Down
48 changes: 8 additions & 40 deletions src/cfg.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
//! Control-flow graph (CFG) abstractions and utilities.

use crate::{
spv, AttrSet, Const, ConstDef, ConstKind, Context, ControlNode, ControlNodeDef,
scalar, spv, AttrSet, Const, ConstDef, ConstKind, Context, ControlNode, ControlNodeDef,
ControlNodeKind, ControlNodeOutputDecl, ControlRegion, ControlRegionDef,
EntityOrientedDenseMap, FuncDefBody, FxIndexMap, FxIndexSet, SelectionKind, Type, TypeKind,
Value,
EntityOrientedDenseMap, FuncDefBody, FxIndexMap, FxIndexSet, SelectionKind, Type, Value,
};
use itertools::{Either, Itertools};
use smallvec::SmallVec;
use std::mem;
use std::rc::Rc;

/// The control-flow graph (CFG) of a function, as control-flow instructions
/// ([`ControlInst`]s) attached to [`ControlRegion`]s, as an "action on exit", i.e.
Expand Down Expand Up @@ -53,7 +51,8 @@ pub enum ControlInstKind {
/// necessary preconditions for reaching this point, are never met.
Unreachable,

/// Leave the current function, optionally returning a value.
/// Leave the current function, returning some number of [`Value`]s, as per
/// the function's signature (`ret_types` in [`FuncDecl`](crate::FuncDecl)).
Return,

/// Leave the current invocation, similar to returning from every function
Expand Down Expand Up @@ -593,32 +592,9 @@ struct PartialControlRegion {

impl<'a> Structurizer<'a> {
pub fn new(cx: &'a Context, func_def_body: &'a mut FuncDefBody) -> Self {
// FIXME(eddyb) SPIR-T should have native booleans itself.
let wk = &spv::spec::Spec::get().well_known;
let type_bool = cx.intern(TypeKind::SpvInst {
spv_inst: wk.OpTypeBool.into(),
type_and_const_inputs: [].into_iter().collect(),
});
let const_true = cx.intern(ConstDef {
attrs: AttrSet::default(),
ty: type_bool,
kind: ConstKind::SpvInst {
spv_inst_and_const_inputs: Rc::new((
wk.OpConstantTrue.into(),
[].into_iter().collect(),
)),
},
});
let const_false = cx.intern(ConstDef {
attrs: AttrSet::default(),
ty: type_bool,
kind: ConstKind::SpvInst {
spv_inst_and_const_inputs: Rc::new((
wk.OpConstantFalse.into(),
[].into_iter().collect(),
)),
},
});
let type_bool = cx.intern(scalar::Type::Bool);
let const_true = cx.intern(scalar::Const::TRUE);
let const_false = cx.intern(scalar::Const::FALSE);

let (loop_header_to_exit_targets, incoming_edge_counts_including_loop_exits) =
func_def_body
Expand Down Expand Up @@ -1568,14 +1544,6 @@ impl<'a> Structurizer<'a> {
/// Create an undefined constant (as a placeholder where a value needs to be
/// present, but won't actually be used), of type `ty`.
fn const_undef(&self, ty: Type) -> Const {
// FIXME(eddyb) SPIR-T should have native undef itself.
let wk = &spv::spec::Spec::get().well_known;
self.cx.intern(ConstDef {
attrs: AttrSet::default(),
ty,
kind: ConstKind::SpvInst {
spv_inst_and_const_inputs: Rc::new((wk.OpUndef.into(), [].into_iter().collect())),
},
})
self.cx.intern(ConstDef { attrs: AttrSet::default(), ty, kind: ConstKind::Undef })
}
}
Loading