Skip to content

Commit 08ccd9d

Browse files
committed
dedup builtins: optimize builtin dedup
1 parent 3306d0c commit 08ccd9d

File tree

1 file changed

+23
-32
lines changed

1 file changed

+23
-32
lines changed

crates/rustc_codegen_spirv/src/linker/duplicates.rs

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -559,9 +559,12 @@ pub fn remove_duplicate_builtin_input_variables(module: &mut Module) {
559559
Operand::BuiltIn(builtin),
560560
] = inst.operands[..]
561561
{
562-
// Ignore multiple BuiltIn's for one variable ID;
563-
// they're invalid AFAIK, but later validation will catch them.
564-
let _prev = var_id_to_builtin_mut.insert(var_id, builtin);
562+
let prev = var_id_to_builtin_mut.insert(var_id, builtin);
563+
assert!(
564+
prev.is_none(),
565+
"An OpVariable `{inst:?}` shouldn't have more than one Builtin decoration, \
566+
but it has at least two: {builtin:?}, {prev:?}"
567+
);
565568
}
566569
}
567570
var_id_to_builtin = var_id_to_builtin_mut;
@@ -599,38 +602,11 @@ pub fn remove_duplicate_builtin_input_variables(module: &mut Module) {
599602
duplicate_vars = duplicate_in_vars_mut;
600603
};
601604

602-
// Rewrite entry points, removing duplicate variables.
603-
for entry in &mut module.entry_points {
604-
if entry.class.opcode != Op::EntryPoint {
605-
continue;
606-
}
607-
608-
entry
609-
.operands
610-
.retain(|op| !matches!(op, Operand::IdRef(id) if duplicate_vars.contains_key(id)));
611-
}
612-
613-
// Rewrite annotations for duplicates to point at de-duplicated variables;
614-
// this will merge the annotations sets but produce duplicate annotations
615-
// (which we will remove next).
616-
for inst in &mut module.annotations {
605+
// Rewrite entry points
606+
for inst in &mut module.entry_points {
617607
rewrite_inst_with_rules(inst, &duplicate_vars);
618608
}
619609

620-
// Merge the annotations for duplicate vars.
621-
{
622-
let mut annotations_set = FxHashSet::default();
623-
module
624-
.annotations
625-
// Note: insert returns true when an annotation is inserted for the first time.
626-
.retain(|inst| annotations_set.insert(inst.assemble()));
627-
}
628-
629-
// Remove the duplicate variable definitions.
630-
module
631-
.types_global_values
632-
.retain(|inst| !matches!(inst.result_id, Some(id) if duplicate_vars.contains_key(&id)));
633-
634610
// Rewrite function blocks to use de-duplicated variables.
635611
for inst in &mut module
636612
.functions
@@ -640,4 +616,19 @@ pub fn remove_duplicate_builtin_input_variables(module: &mut Module) {
640616
{
641617
rewrite_inst_with_rules(inst, &duplicate_vars);
642618
}
619+
620+
// Remove duplicate BuiltIn decorations
621+
module.annotations.retain(|inst| {
622+
!(inst.class.opcode == Op::Decorate
623+
&& matches!(inst.operands[..], [
624+
Operand::IdRef(var_id),
625+
Operand::Decoration(Decoration::BuiltIn),
626+
Operand::BuiltIn(_),
627+
] if duplicate_vars.contains_key(&var_id)))
628+
});
629+
630+
// Remove the duplicate variable definitions.
631+
module
632+
.types_global_values
633+
.retain(|inst| !matches!(inst.result_id, Some(id) if duplicate_vars.contains_key(&id)));
643634
}

0 commit comments

Comments
 (0)