@@ -10,16 +10,16 @@ use super::{get_name, get_names};
1010use rspirv:: dr:: { Block , Function , Instruction , Module , ModuleHeader , Operand } ;
1111use rspirv:: spirv:: { FunctionControl , Op , StorageClass , Word } ;
1212use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
13- use rustc_errors:: ErrorGuaranteed ;
1413use rustc_session:: Session ;
1514use std:: mem:: take;
1615
1716type FunctionMap = FxHashMap < Word , Function > ;
1817
1918pub fn inline ( sess : & Session , module : & mut Module ) -> super :: Result < ( ) > {
2019 // This algorithm gets real sad if there's recursion - but, good news, SPIR-V bans recursion
21- deny_recursion_in_module ( sess, module) ?;
22-
20+ if module_has_recursion ( sess, module) {
21+ return Err ( rustc_errors:: ErrorReported ) ;
22+ }
2323 let functions = module
2424 . functions
2525 . iter ( )
@@ -35,11 +35,13 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
3535 // Drop all the functions we'll be inlining. (This also means we won't waste time processing
3636 // inlines in functions that will get inlined)
3737 let mut dropped_ids = FxHashSet :: default ( ) ;
38- let mut inlined_dont_inlines = Vec :: new ( ) ;
3938 module. functions . retain ( |f| {
4039 if should_inline ( & disallowed_argument_types, & disallowed_return_types, f) {
4140 if has_dont_inline ( f) {
42- inlined_dont_inlines. push ( f. def_id ( ) . unwrap ( ) ) ;
41+ sess. warn ( & format ! (
42+ "Function `{}` has `dont_inline` attribute, but need to be inlined because it has illegal argument or return types" ,
43+ get_name( & get_names( module) , f. def_id( ) . unwrap( ) )
44+ ) ) ;
4345 }
4446 // TODO: We should insert all defined IDs in this function.
4547 dropped_ids. insert ( f. def_id ( ) . unwrap ( ) ) ;
@@ -48,16 +50,6 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
4850 true
4951 }
5052 } ) ;
51- if !inlined_dont_inlines. is_empty ( ) {
52- let names = get_names ( module) ;
53- for f in inlined_dont_inlines {
54- sess. warn ( & format ! (
55- "function `{}` has `dont_inline` attribute, but need to be inlined because it has illegal argument or return types" ,
56- get_name( & names, f)
57- ) ) ;
58- }
59- }
60-
6153 // Drop OpName etc. for inlined functions
6254 module. debug_names . retain ( |inst| {
6355 !inst. operands . iter ( ) . any ( |op| {
@@ -81,7 +73,7 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
8173}
8274
8375// https://stackoverflow.com/a/53995651
84- fn deny_recursion_in_module ( sess : & Session , module : & Module ) -> super :: Result < ( ) > {
76+ fn module_has_recursion ( sess : & Session , module : & Module ) -> bool {
8577 let func_to_index: FxHashMap < Word , usize > = module
8678 . functions
8779 . iter ( )
@@ -90,7 +82,7 @@ fn deny_recursion_in_module(sess: &Session, module: &Module) -> super::Result<()
9082 . collect ( ) ;
9183 let mut discovered = vec ! [ false ; module. functions. len( ) ] ;
9284 let mut finished = vec ! [ false ; module. functions. len( ) ] ;
93- let mut has_recursion = None ;
85+ let mut has_recursion = false ;
9486 for index in 0 ..module. functions . len ( ) {
9587 if !discovered[ index] && !finished[ index] {
9688 visit (
@@ -111,7 +103,7 @@ fn deny_recursion_in_module(sess: &Session, module: &Module) -> super::Result<()
111103 current : usize ,
112104 discovered : & mut Vec < bool > ,
113105 finished : & mut Vec < bool > ,
114- has_recursion : & mut Option < ErrorGuaranteed > ,
106+ has_recursion : & mut bool ,
115107 func_to_index : & FxHashMap < Word , usize > ,
116108 ) {
117109 discovered[ current] = true ;
@@ -121,10 +113,11 @@ fn deny_recursion_in_module(sess: &Session, module: &Module) -> super::Result<()
121113 let names = get_names ( module) ;
122114 let current_name = get_name ( & names, module. functions [ current] . def_id ( ) . unwrap ( ) ) ;
123115 let next_name = get_name ( & names, module. functions [ next] . def_id ( ) . unwrap ( ) ) ;
124- * has_recursion = Some ( sess. err ( & format ! (
116+ sess. err ( & format ! (
125117 "module has recursion, which is not allowed: `{}` calls `{}`" ,
126118 current_name, next_name
127- ) ) ) ;
119+ ) ) ;
120+ * has_recursion = true ;
128121 break ;
129122 }
130123
@@ -158,10 +151,7 @@ fn deny_recursion_in_module(sess: &Session, module: &Module) -> super::Result<()
158151 } )
159152 }
160153
161- match has_recursion {
162- Some ( err) => Err ( err) ,
163- None => Ok ( ( ) ) ,
164- }
154+ has_recursion
165155}
166156
167157fn compute_disallowed_argument_and_return_types (
@@ -218,29 +208,28 @@ fn compute_disallowed_argument_and_return_types(
218208 ( disallowed_argument_types, disallowed_return_types)
219209}
220210
221- fn has_dont_inline ( function : & Function ) -> bool {
211+ fn has_dont_inline (
212+ function : & Function ,
213+ ) -> bool {
222214 let def = function. def . as_ref ( ) . unwrap ( ) ;
223215 let control = def. operands [ 0 ] . unwrap_function_control ( ) ;
224216 control. contains ( FunctionControl :: DONT_INLINE )
225217}
226218
219+
227220fn should_inline (
228221 disallowed_argument_types : & FxHashSet < Word > ,
229222 disallowed_return_types : & FxHashSet < Word > ,
230223 function : & Function ,
231224) -> bool {
232225 let def = function. def . as_ref ( ) . unwrap ( ) ;
233226 let control = def. operands [ 0 ] . unwrap_function_control ( ) ;
234- let should = control. contains ( FunctionControl :: INLINE )
227+ control. contains ( FunctionControl :: INLINE )
235228 || function
236229 . parameters
237230 . iter ( )
238231 . any ( |inst| disallowed_argument_types. contains ( inst. result_type . as_ref ( ) . unwrap ( ) ) )
239- || disallowed_return_types. contains ( & function. def . as_ref ( ) . unwrap ( ) . result_type . unwrap ( ) ) ;
240- // if should && control.contains(FunctionControl::DONT_INLINE) {
241- // println!("should not be inlined!");
242- // }
243- should
232+ || disallowed_return_types. contains ( & function. def . as_ref ( ) . unwrap ( ) . result_type . unwrap ( ) )
244233}
245234
246235// This should be more general, but a very common problem is passing an OpAccessChain to an
0 commit comments