11use crate :: custom_insts:: { self , CustomOp } ;
22use rspirv:: binary:: Assemble ;
33use rspirv:: dr:: { Instruction , Module , Operand } ;
4- use rspirv:: spirv:: { BuiltIn , Decoration , Op , Word } ;
4+ use rspirv:: spirv:: { BuiltIn , Decoration , Op , StorageClass , Word } ;
55use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
66use rustc_middle:: bug;
77use 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
0 commit comments