@@ -10,16 +10,16 @@ use super::{get_name, get_names};
10
10
use rspirv:: dr:: { Block , Function , Instruction , Module , ModuleHeader , Operand } ;
11
11
use rspirv:: spirv:: { FunctionControl , Op , StorageClass , Word } ;
12
12
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
13
- use rustc_errors:: ErrorGuaranteed ;
14
13
use rustc_session:: Session ;
15
14
use std:: mem:: take;
16
15
17
16
type FunctionMap = FxHashMap < Word , Function > ;
18
17
19
18
pub fn inline ( sess : & Session , module : & mut Module ) -> super :: Result < ( ) > {
20
19
// 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
+ }
23
23
let functions = module
24
24
. functions
25
25
. iter ( )
@@ -35,11 +35,13 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
35
35
// Drop all the functions we'll be inlining. (This also means we won't waste time processing
36
36
// inlines in functions that will get inlined)
37
37
let mut dropped_ids = FxHashSet :: default ( ) ;
38
- let mut inlined_dont_inlines = Vec :: new ( ) ;
39
38
module. functions . retain ( |f| {
40
39
if should_inline ( & disallowed_argument_types, & disallowed_return_types, f) {
41
40
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
+ ) ) ;
43
45
}
44
46
// TODO: We should insert all defined IDs in this function.
45
47
dropped_ids. insert ( f. def_id ( ) . unwrap ( ) ) ;
@@ -48,16 +50,6 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
48
50
true
49
51
}
50
52
} ) ;
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
-
61
53
// Drop OpName etc. for inlined functions
62
54
module. debug_names . retain ( |inst| {
63
55
!inst. operands . iter ( ) . any ( |op| {
@@ -81,7 +73,7 @@ pub fn inline(sess: &Session, module: &mut Module) -> super::Result<()> {
81
73
}
82
74
83
75
// 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 {
85
77
let func_to_index: FxHashMap < Word , usize > = module
86
78
. functions
87
79
. iter ( )
@@ -90,7 +82,7 @@ fn deny_recursion_in_module(sess: &Session, module: &Module) -> super::Result<()
90
82
. collect ( ) ;
91
83
let mut discovered = vec ! [ false ; module. functions. len( ) ] ;
92
84
let mut finished = vec ! [ false ; module. functions. len( ) ] ;
93
- let mut has_recursion = None ;
85
+ let mut has_recursion = false ;
94
86
for index in 0 ..module. functions . len ( ) {
95
87
if !discovered[ index] && !finished[ index] {
96
88
visit (
@@ -111,7 +103,7 @@ fn deny_recursion_in_module(sess: &Session, module: &Module) -> super::Result<()
111
103
current : usize ,
112
104
discovered : & mut Vec < bool > ,
113
105
finished : & mut Vec < bool > ,
114
- has_recursion : & mut Option < ErrorGuaranteed > ,
106
+ has_recursion : & mut bool ,
115
107
func_to_index : & FxHashMap < Word , usize > ,
116
108
) {
117
109
discovered[ current] = true ;
@@ -121,10 +113,11 @@ fn deny_recursion_in_module(sess: &Session, module: &Module) -> super::Result<()
121
113
let names = get_names ( module) ;
122
114
let current_name = get_name ( & names, module. functions [ current] . def_id ( ) . unwrap ( ) ) ;
123
115
let next_name = get_name ( & names, module. functions [ next] . def_id ( ) . unwrap ( ) ) ;
124
- * has_recursion = Some ( sess. err ( & format ! (
116
+ sess. err ( & format ! (
125
117
"module has recursion, which is not allowed: `{}` calls `{}`" ,
126
118
current_name, next_name
127
- ) ) ) ;
119
+ ) ) ;
120
+ * has_recursion = true ;
128
121
break ;
129
122
}
130
123
@@ -158,10 +151,7 @@ fn deny_recursion_in_module(sess: &Session, module: &Module) -> super::Result<()
158
151
} )
159
152
}
160
153
161
- match has_recursion {
162
- Some ( err) => Err ( err) ,
163
- None => Ok ( ( ) ) ,
164
- }
154
+ has_recursion
165
155
}
166
156
167
157
fn compute_disallowed_argument_and_return_types (
@@ -218,29 +208,28 @@ fn compute_disallowed_argument_and_return_types(
218
208
( disallowed_argument_types, disallowed_return_types)
219
209
}
220
210
221
- fn has_dont_inline ( function : & Function ) -> bool {
211
+ fn has_dont_inline (
212
+ function : & Function ,
213
+ ) -> bool {
222
214
let def = function. def . as_ref ( ) . unwrap ( ) ;
223
215
let control = def. operands [ 0 ] . unwrap_function_control ( ) ;
224
216
control. contains ( FunctionControl :: DONT_INLINE )
225
217
}
226
218
219
+
227
220
fn should_inline (
228
221
disallowed_argument_types : & FxHashSet < Word > ,
229
222
disallowed_return_types : & FxHashSet < Word > ,
230
223
function : & Function ,
231
224
) -> bool {
232
225
let def = function. def . as_ref ( ) . unwrap ( ) ;
233
226
let control = def. operands [ 0 ] . unwrap_function_control ( ) ;
234
- let should = control. contains ( FunctionControl :: INLINE )
227
+ control. contains ( FunctionControl :: INLINE )
235
228
|| function
236
229
. parameters
237
230
. iter ( )
238
231
. 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 ( ) )
244
233
}
245
234
246
235
// This should be more general, but a very common problem is passing an OpAccessChain to an
0 commit comments