Skip to content

Commit 603f989

Browse files
committed
Update spirt for DataInstForm interning.
1 parent b3670b2 commit 603f989

File tree

7 files changed

+126
-47
lines changed

7 files changed

+126
-47
lines changed

Cargo.lock

Lines changed: 36 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,6 @@ codegen-units = 256
5252
opt-level = 3
5353
incremental = true
5454
codegen-units = 256
55+
56+
[patch.crates-io]
57+
spirt = { git = "https://github.com/EmbarkStudios/spirt", branch = "main" }

crates/rustc_codegen_spirv/src/linker/spirt_passes/controlflow.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::custom_insts::{self, CustomInst, CustomOp};
44
use smallvec::SmallVec;
55
use spirt::func_at::FuncAt;
66
use spirt::{
7-
cfg, spv, Attr, AttrSet, ConstCtor, ConstDef, ControlNodeKind, DataInstKind, DeclDef,
8-
EntityDefs, ExportKey, Exportee, Module, Type, TypeCtor, TypeCtorArg, TypeDef, Value,
7+
cfg, spv, Attr, AttrSet, ConstCtor, ConstDef, ControlNodeKind, DataInstFormDef, DataInstKind,
8+
DeclDef, EntityDefs, ExportKey, Exportee, Module, Type, TypeCtor, TypeCtorArg, TypeDef, Value,
99
};
1010
use std::fmt::Write as _;
1111

@@ -108,14 +108,15 @@ pub fn convert_custom_aborts_to_unstructured_returns_in_entry_points(
108108
.into_iter()
109109
.filter_map(|func_at_inst| {
110110
let data_inst_def = func_at_inst.def();
111-
if let DataInstKind::SpvInst(spv_inst) = &data_inst_def.kind {
111+
let data_inst_form_def = &cx[data_inst_def.form];
112+
if let DataInstKind::SpvInst(spv_inst) = &data_inst_form_def.kind {
112113
if spv_inst.opcode == wk.OpLoad {
113114
if let Value::Const(ct) = data_inst_def.inputs[0] {
114115
if let ConstCtor::PtrToGlobalVar(gv) = cx[ct].ctor {
115116
if interface_global_vars.contains(&gv) {
116117
return Some((
117118
gv,
118-
data_inst_def.output_type.unwrap(),
119+
data_inst_form_def.output_type.unwrap(),
119120
Value::DataInstOutput(func_at_inst.position),
120121
));
121122
}
@@ -223,7 +224,7 @@ pub fn convert_custom_aborts_to_unstructured_returns_in_entry_points(
223224
let data_inst_def = func_at_inst.def();
224225
(
225226
func_at_inst,
226-
match data_inst_def.kind {
227+
match cx[data_inst_def.form].kind {
227228
DataInstKind::SpvExtInst { ext_set, inst }
228229
if ext_set == custom_ext_inst_set =>
229230
{
@@ -381,10 +382,13 @@ pub fn convert_custom_aborts_to_unstructured_returns_in_entry_points(
381382
fmt += "\n";
382383

383384
let abort_inst_def = &mut func_def_body.data_insts[abort_inst];
384-
abort_inst_def.kind = DataInstKind::SpvExtInst {
385-
ext_set: cx.intern("NonSemantic.DebugPrintf"),
386-
inst: 1,
387-
};
385+
abort_inst_def.form = cx.intern(DataInstFormDef {
386+
kind: DataInstKind::SpvExtInst {
387+
ext_set: cx.intern("NonSemantic.DebugPrintf"),
388+
inst: 1,
389+
},
390+
output_type: cx[abort_inst_def.form].output_type,
391+
});
388392
abort_inst_def.inputs = [Value::Const(mk_const_str(cx.intern(fmt)))]
389393
.into_iter()
390394
.chain(message_debug_printf_args)

crates/rustc_codegen_spirv/src/linker/spirt_passes/debuginfo.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub fn convert_custom_debuginfo_to_spv(module: &mut Module) {
2525

2626
seen_types: FxIndexSet::default(),
2727
seen_consts: FxIndexSet::default(),
28+
seen_data_inst_forms: FxIndexSet::default(),
2829
seen_global_vars: FxIndexSet::default(),
2930
seen_funcs: FxIndexSet::default(),
3031
};
@@ -82,7 +83,7 @@ impl Transformer for CustomDebuginfoToSpv<'_> {
8283
if let DataInstKind::SpvExtInst {
8384
ext_set,
8485
inst: ext_inst,
85-
} = data_inst_def.kind
86+
} = self.cx[data_inst_def.form].kind
8687
{
8788
if ext_set == self.custom_ext_inst_set {
8889
let custom_op = CustomOp::decode(ext_inst);

crates/rustc_codegen_spirv/src/linker/spirt_passes/diagnostics.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use spirt::func_at::FuncAt;
1111
use spirt::visit::{InnerVisit, Visitor};
1212
use spirt::{
1313
spv, Attr, AttrSet, AttrSetDef, Const, ConstCtor, Context, ControlNode, ControlNodeKind,
14-
DataInstDef, DataInstKind, Diag, DiagLevel, ExportKey, Exportee, Func, FuncDecl, GlobalVar,
15-
InternedStr, Module, Type, Value,
14+
DataInstDef, DataInstForm, DataInstKind, Diag, DiagLevel, ExportKey, Exportee, Func, FuncDecl,
15+
GlobalVar, InternedStr, Module, Type, Value,
1616
};
1717
use std::marker::PhantomData;
1818
use std::{mem, str};
@@ -251,7 +251,7 @@ impl UseOrigin<'_> {
251251
let wk = &super::SpvSpecWithExtras::get().well_known;
252252

253253
// FIXME(eddyb) deduplicate with `spirt_passes::diagnostics`.
254-
let custom_op = match debug_inst_def.kind {
254+
let custom_op = match cx[debug_inst_def.form].kind {
255255
DataInstKind::SpvExtInst {
256256
ext_set,
257257
inst: ext_inst,
@@ -518,6 +518,11 @@ impl<'a> Visitor<'a> for DiagnosticReporter<'a> {
518518
}
519519
}
520520
}
521+
fn visit_data_inst_form_use(&mut self, data_inst_form: DataInstForm) {
522+
// NOTE(eddyb) this contains no deduplication because each `DataInstDef`
523+
// will have any diagnostics reported separately.
524+
self.visit_data_inst_form_def(&self.cx[data_inst_form]);
525+
}
521526

522527
fn visit_global_var_use(&mut self, gv: GlobalVar) {
523528
if self.seen_global_vars.insert(gv) {
@@ -617,7 +622,7 @@ impl<'a> Visitor<'a> for DiagnosticReporter<'a> {
617622
if let DataInstKind::SpvExtInst {
618623
ext_set,
619624
inst: ext_inst,
620-
} = data_inst_def.kind
625+
} = self.cx[data_inst_def.form].kind
621626
{
622627
if ext_set == self.custom_ext_inst_set {
623628
match CustomOp::decode(ext_inst) {
@@ -687,7 +692,7 @@ impl<'a> Visitor<'a> for DiagnosticReporter<'a> {
687692
_ => unreachable!(),
688693
}
689694

690-
if let DataInstKind::FuncCall(func) = data_inst_def.kind {
695+
if let DataInstKind::FuncCall(func) = self.cx[data_inst_def.form].kind {
691696
// HACK(eddyb) visit `func` early, to control its `use_stack`, with
692697
// the later visit from `inner_visit_with` ignored as a duplicate.
693698
let old_origin = replace_origin(self, IntraFuncUseOrigin::CallCallee);

crates/rustc_codegen_spirv/src/linker/spirt_passes/mod.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use spirt::transform::InnerInPlaceTransform;
1313
use spirt::visit::{InnerVisit, Visitor};
1414
use spirt::{
1515
spv, AttrSet, Const, Context, ControlNode, ControlNodeKind, ControlRegion, DataInstDef,
16-
DataInstKind, DeclDef, EntityOrientedDenseMap, Func, FuncDefBody, GlobalVar, Module, Type,
17-
Value,
16+
DataInstForm, DataInstFormDef, DataInstKind, DeclDef, EntityOrientedDenseMap, Func,
17+
FuncDefBody, GlobalVar, Module, Type, Value,
1818
};
1919
use std::collections::VecDeque;
2020
use std::hash::Hash;
@@ -130,6 +130,7 @@ pub(super) fn run_func_passes<P>(
130130

131131
seen_types: FxIndexSet::default(),
132132
seen_consts: FxIndexSet::default(),
133+
seen_data_inst_forms: FxIndexSet::default(),
133134
seen_global_vars: FxIndexSet::default(),
134135
seen_funcs: FxIndexSet::default(),
135136
};
@@ -181,7 +182,7 @@ pub(super) fn run_func_passes<P>(
181182
pass_fn(cx, func_def_body);
182183

183184
// FIXME(eddyb) avoid doing this except where changes occurred.
184-
remove_unused_values_in_func(func_def_body);
185+
remove_unused_values_in_func(cx, func_def_body);
185186
}
186187
}
187188
after_pass(full_name, module, profiler);
@@ -196,6 +197,7 @@ struct ReachableUseCollector<'a> {
196197
// FIXME(eddyb) build some automation to avoid ever repeating these.
197198
seen_types: FxIndexSet<Type>,
198199
seen_consts: FxIndexSet<Const>,
200+
seen_data_inst_forms: FxIndexSet<DataInstForm>,
199201
seen_global_vars: FxIndexSet<GlobalVar>,
200202
seen_funcs: FxIndexSet<Func>,
201203
}
@@ -213,6 +215,11 @@ impl Visitor<'_> for ReachableUseCollector<'_> {
213215
self.visit_const_def(&self.cx[ct]);
214216
}
215217
}
218+
fn visit_data_inst_form_use(&mut self, data_inst_form: DataInstForm) {
219+
if self.seen_data_inst_forms.insert(data_inst_form) {
220+
self.visit_data_inst_form_def(&self.cx[data_inst_form]);
221+
}
222+
}
216223

217224
fn visit_global_var_use(&mut self, gv: GlobalVar) {
218225
if self.seen_global_vars.insert(gv) {
@@ -247,6 +254,7 @@ const _: () = {
247254
fn visit_attr_set_use(&mut self, _: AttrSet) {}
248255
fn visit_type_use(&mut self, _: Type) {}
249256
fn visit_const_use(&mut self, _: Const) {}
257+
fn visit_data_inst_form_use(&mut self, _: DataInstForm) {}
250258
fn visit_global_var_use(&mut self, _: GlobalVar) {}
251259
fn visit_func_use(&mut self, _: Func) {}
252260

@@ -354,7 +362,7 @@ const _: () = {
354362
/// a function body (both `DataInst`s and `ControlRegion` inputs/outputs).
355363
//
356364
// FIXME(eddyb) should this be a dedicated pass?
357-
fn remove_unused_values_in_func(func_def_body: &mut FuncDefBody) {
365+
fn remove_unused_values_in_func(cx: &Context, func_def_body: &mut FuncDefBody) {
358366
// Avoid having to support unstructured control-flow.
359367
if func_def_body.unstructured_cfg.is_some() {
360368
return;
@@ -473,7 +481,9 @@ fn remove_unused_values_in_func(func_def_body: &mut FuncDefBody) {
473481
for func_at_inst in func_at_control_node.at(insts) {
474482
// Ignore pure instructions (i.e. they're only used
475483
// if their output value is used, from somewhere else).
476-
if let DataInstKind::SpvInst(spv_inst) = &func_at_inst.def().kind {
484+
if let DataInstKind::SpvInst(spv_inst) =
485+
&cx[func_at_inst.def().form].kind
486+
{
477487
// HACK(eddyb) small selection relevant for now,
478488
// but should be extended using e.g. a bitset.
479489
if [wk.OpNop, wk.OpCompositeInsert].contains(&spv_inst.opcode) {
@@ -518,7 +528,9 @@ fn remove_unused_values_in_func(func_def_body: &mut FuncDefBody) {
518528
let mut all_nops = true;
519529
let mut func_at_inst_iter = func_def_body.at_mut(insts).into_iter();
520530
while let Some(mut func_at_inst) = func_at_inst_iter.next() {
521-
if let DataInstKind::SpvInst(spv_inst) = &func_at_inst.reborrow().def().kind {
531+
if let DataInstKind::SpvInst(spv_inst) =
532+
&cx[func_at_inst.reborrow().def().form].kind
533+
{
522534
if spv_inst.opcode == wk.OpNop {
523535
continue;
524536
}
@@ -528,10 +540,14 @@ fn remove_unused_values_in_func(func_def_body: &mut FuncDefBody) {
528540
{
529541
// Replace the removed `DataInstDef` itself with `OpNop`,
530542
// removing the ability to use its "name" as a value.
543+
//
544+
// FIXME(eddyb) cache the interned `OpNop`.
531545
*func_at_inst.def() = DataInstDef {
532546
attrs: Default::default(),
533-
kind: DataInstKind::SpvInst(wk.OpNop.into()),
534-
output_type: None,
547+
form: cx.intern(DataInstFormDef {
548+
kind: DataInstKind::SpvInst(wk.OpNop.into()),
549+
output_type: None,
550+
}),
535551
inputs: iter::empty().collect(),
536552
};
537553
continue;

0 commit comments

Comments
 (0)