Skip to content

Commit 00a1609

Browse files
fluffysquirrelsFirestar99
authored andcommitted
dedup builtins: fix linker builtin dedup bug, was merging all kinds of variables
1 parent 9a9f4f2 commit 00a1609

File tree

2 files changed

+40
-20
lines changed

2 files changed

+40
-20
lines changed

crates/rustc_codegen_spirv/src/linker/duplicates.rs

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::custom_insts::{self, CustomOp};
22
use rspirv::binary::Assemble;
33
use rspirv::dr::{Instruction, Module, Operand};
4-
use rspirv::spirv::{BuiltIn, Decoration, Op, Word};
4+
use rspirv::spirv::{BuiltIn, Decoration, Op, StorageClass, Word};
55
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
66
use rustc_middle::bug;
77
use smallvec::SmallVec;
@@ -552,15 +552,13 @@ pub fn remove_duplicate_debuginfo(module: &mut Module) {
552552
}
553553
}
554554

555-
pub fn remove_duplicate_builtin_variables(module: &mut Module) {
556-
// Find the variables decorated as builtins, and any duplicates of each builtin.
555+
pub fn remove_duplicate_builtin_input_variables(module: &mut Module) {
556+
// Find the variables decorated as input builtins, and any duplicates of them..
557557

558-
// A map from deleted duplicate variable ID to the new, de-duplicated ID.
559-
let duplicate_vars: FxHashMap<Word, Word> = {
560-
// A map from builtin to a de-duplicated variable decorated as that builtin.
561-
let mut builtin_to_var_id = FxHashMap::<BuiltIn, Word>::default();
562-
563-
let mut duplicate_vars = FxHashMap::<Word, Word>::default();
558+
// Build a map: from a variable ID to the builtin it's decorated with.
559+
let var_id_to_builtin: FxHashMap<Word, BuiltIn>;
560+
{
561+
let mut var_id_to_builtin_mut = FxHashMap::default();
564562

565563
for inst in module.annotations.iter() {
566564
if inst.class.opcode == Op::Decorate
@@ -570,23 +568,46 @@ pub fn remove_duplicate_builtin_variables(module: &mut Module) {
570568
Operand::BuiltIn(builtin),
571569
] = inst.operands[..]
572570
{
573-
match builtin_to_var_id.entry(builtin) {
574-
// first variable we've seen for this builtin,
571+
// Ignore multiple BuiltIn's for one variable ID;
572+
// they're invalid AFAIK, but later validation will catch them.
573+
let _prev = var_id_to_builtin_mut.insert(var_id, builtin);
574+
}
575+
}
576+
// Rebind as immutable.
577+
var_id_to_builtin = var_id_to_builtin_mut;
578+
};
579+
580+
// Build a map from deleted duplicate input variable ID to the de-duplicated ID.
581+
let duplicate_vars: FxHashMap<Word, Word>;
582+
{
583+
let mut duplicate_in_vars_mut = FxHashMap::<Word, Word>::default();
584+
585+
// Map from builtin to de-duped input variable ID.
586+
let mut builtin_to_input_var_id = FxHashMap::<BuiltIn, Word>::default();
587+
588+
for inst in module.types_global_values.iter() {
589+
if inst.class.opcode == Op::Variable
590+
&& let [Operand::StorageClass(StorageClass::Input), ..] = inst.operands[..]
591+
&& let Some(var_id) = inst.result_id
592+
&& let Some(builtin) = var_id_to_builtin.get(&var_id)
593+
{
594+
match builtin_to_input_var_id.entry(*builtin) {
595+
// first input variable we've seen for this builtin,
575596
// record it in the builtins map.
576597
hash_map::Entry::Vacant(vacant) => {
577598
vacant.insert(var_id);
578599
}
579600

580-
// this builtin already has a variable,
601+
// this builtin already has an input variable,
581602
// record it in the duplicates map.
582603
hash_map::Entry::Occupied(occupied) => {
583-
duplicate_vars.insert(var_id, *occupied.get());
604+
duplicate_in_vars_mut.insert(var_id, *occupied.get());
584605
}
585606
};
586607
}
587608
}
588-
// Rebind as immutable in fn scope.
589-
duplicate_vars
609+
// Rebind as immutable.
610+
duplicate_vars = duplicate_in_vars_mut;
590611
};
591612

592613
// Rewrite entry points, removing duplicate variables.
@@ -620,10 +641,9 @@ pub fn remove_duplicate_builtin_variables(module: &mut Module) {
620641
}
621642

622643
// Remove the duplicate variable definitions.
623-
module.types_global_values.retain(|inst| {
624-
!matches!(inst.result_id,
625-
Some(id) if duplicate_vars.contains_key(&id))
626-
});
644+
module
645+
.types_global_values
646+
.retain(|inst| !matches!(inst.result_id, Some(id) if duplicate_vars.contains_key(&id)));
627647

628648
// Rewrite function blocks to use de-duplicated variables.
629649
for inst in &mut module

crates/rustc_codegen_spirv/src/linker/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ pub fn link(
290290
duplicates::remove_duplicate_capabilities(&mut output);
291291
duplicates::remove_duplicate_ext_inst_imports(&mut output);
292292
duplicates::remove_duplicate_types(&mut output);
293-
duplicates::remove_duplicate_builtin_variables(&mut output);
293+
duplicates::remove_duplicate_builtin_input_variables(&mut output);
294294
// jb-todo: strip identical OpDecoration / OpDecorationGroups
295295
}
296296

0 commit comments

Comments
 (0)