1
1
//! A frontend for building Cranelift IR from other languages.
2
- use crate :: ssa:: { SSABlock , SSABuilder , SideEffects } ;
2
+ use crate :: ssa:: { SSABuilder , SideEffects } ;
3
3
use crate :: variable:: Variable ;
4
4
use cranelift_codegen:: cursor:: { Cursor , FuncCursor } ;
5
5
use cranelift_codegen:: entity:: { EntitySet , SecondaryMap } ;
@@ -35,7 +35,7 @@ pub struct FunctionBuilder<'a> {
35
35
srcloc : ir:: SourceLoc ,
36
36
37
37
func_ctx : & ' a mut FunctionBuilderContext ,
38
- position : Position ,
38
+ position : PackedOption < Block > ,
39
39
}
40
40
41
41
#[ derive( Clone , Default ) ]
@@ -54,25 +54,6 @@ struct BlockData {
54
54
user_param_count : usize ,
55
55
}
56
56
57
- #[ derive( Default ) ]
58
- struct Position {
59
- block : PackedOption < Block > ,
60
- basic_block : PackedOption < SSABlock > ,
61
- }
62
-
63
- impl Position {
64
- fn at ( block : Block , basic_block : SSABlock ) -> Self {
65
- Self {
66
- block : PackedOption :: from ( block) ,
67
- basic_block : PackedOption :: from ( basic_block) ,
68
- }
69
- }
70
-
71
- fn is_default ( & self ) -> bool {
72
- self . block . is_none ( ) && self . basic_block . is_none ( )
73
- }
74
- }
75
-
76
57
impl FunctionBuilderContext {
77
58
/// Creates a FunctionBuilderContext structure. The structure is automatically cleared after
78
59
/// each [`FunctionBuilder`](struct.FunctionBuilder.html) completes translating a function.
@@ -158,25 +139,22 @@ impl<'short, 'long> InstBuilderBase<'short> for FuncInstBuilder<'short, 'long> {
158
139
. iter ( )
159
140
. filter ( |& dest_block| unique. insert ( * dest_block) )
160
141
{
142
+ // Call `declare_block_predecessor` instead of `declare_successor` for
143
+ // avoiding the borrow checker.
161
144
self . builder . func_ctx . ssa . declare_block_predecessor (
162
145
* dest_block,
163
- self . builder . position . basic_block . unwrap ( ) ,
146
+ self . builder . position . unwrap ( ) ,
164
147
inst,
165
148
) ;
166
149
}
167
- self . builder . func_ctx . ssa . declare_block_predecessor (
168
- destination,
169
- self . builder . position . basic_block . unwrap ( ) ,
170
- inst,
171
- ) ;
150
+ self . builder . declare_successor ( destination, inst) ;
172
151
}
173
152
}
174
153
}
175
154
}
155
+
176
156
if data. opcode ( ) . is_terminator ( ) {
177
157
self . builder . fill_current_block ( )
178
- } else if data. opcode ( ) . is_branch ( ) {
179
- self . builder . move_to_next_basic_block ( )
180
158
}
181
159
( inst, & mut self . builder . func . dfg )
182
160
}
@@ -224,7 +202,7 @@ impl<'a> FunctionBuilder<'a> {
224
202
func,
225
203
srcloc : Default :: default ( ) ,
226
204
func_ctx,
227
- position : Position :: default ( ) ,
205
+ position : Default :: default ( ) ,
228
206
}
229
207
}
230
208
@@ -236,7 +214,7 @@ impl<'a> FunctionBuilder<'a> {
236
214
/// Creates a new `Block` and returns its reference.
237
215
pub fn create_block ( & mut self ) -> Block {
238
216
let block = self . func . dfg . make_block ( ) ;
239
- self . func_ctx . ssa . declare_block_header_block ( block) ;
217
+ self . func_ctx . ssa . declare_block ( block) ;
240
218
self . func_ctx . blocks [ block] = BlockData {
241
219
filled : false ,
242
220
pristine : true ,
@@ -255,7 +233,7 @@ impl<'a> FunctionBuilder<'a> {
255
233
pub fn switch_to_block ( & mut self , block : Block ) {
256
234
// First we check that the previous block has been filled.
257
235
debug_assert ! (
258
- self . position. is_default ( )
236
+ self . position. is_none ( )
259
237
|| self . is_unreachable( )
260
238
|| self . is_pristine( )
261
239
|| self . is_filled( ) ,
@@ -267,9 +245,8 @@ impl<'a> FunctionBuilder<'a> {
267
245
"you cannot switch to a block which is already filled"
268
246
) ;
269
247
270
- let basic_block = self . func_ctx . ssa . header_block ( block) ;
271
248
// Then we change the cursor position.
272
- self . position = Position :: at ( block, basic_block ) ;
249
+ self . position = PackedOption :: from ( block) ;
273
250
}
274
251
275
252
/// Declares that all the predecessors of this block are known.
@@ -278,7 +255,7 @@ impl<'a> FunctionBuilder<'a> {
278
255
/// created. Forgetting to call this method on every block will cause inconsistencies in the
279
256
/// produced functions.
280
257
pub fn seal_block ( & mut self , block : Block ) {
281
- let side_effects = self . func_ctx . ssa . seal_block_header_block ( block, self . func ) ;
258
+ let side_effects = self . func_ctx . ssa . seal_block ( block, self . func ) ;
282
259
self . handle_ssa_side_effects ( side_effects) ;
283
260
}
284
261
@@ -289,7 +266,7 @@ impl<'a> FunctionBuilder<'a> {
289
266
/// function can be used at the end of translating all blocks to ensure
290
267
/// that everything is sealed.
291
268
pub fn seal_all_blocks ( & mut self ) {
292
- let side_effects = self . func_ctx . ssa . seal_all_block_header_blocks ( self . func ) ;
269
+ let side_effects = self . func_ctx . ssa . seal_all_blocks ( self . func ) ;
293
270
self . handle_ssa_side_effects ( side_effects) ;
294
271
}
295
272
@@ -310,7 +287,7 @@ impl<'a> FunctionBuilder<'a> {
310
287
} ) ;
311
288
self . func_ctx
312
289
. ssa
313
- . use_var ( self . func , var, ty, self . position . basic_block . unwrap ( ) )
290
+ . use_var ( self . func , var, ty, self . position . unwrap ( ) )
314
291
} ;
315
292
self . handle_ssa_side_effects ( side_effects) ;
316
293
val
@@ -330,9 +307,7 @@ impl<'a> FunctionBuilder<'a> {
330
307
val
331
308
) ;
332
309
333
- self . func_ctx
334
- . ssa
335
- . def_var ( var, val, self . position . basic_block . unwrap ( ) ) ;
310
+ self . func_ctx . ssa . def_var ( var, val, self . position . unwrap ( ) ) ;
336
311
}
337
312
338
313
/// Set label for Value
@@ -395,14 +370,13 @@ impl<'a> FunctionBuilder<'a> {
395
370
pub fn ins < ' short > ( & ' short mut self ) -> FuncInstBuilder < ' short , ' a > {
396
371
let block = self
397
372
. position
398
- . block
399
373
. expect ( "Please call switch_to_block before inserting instructions" ) ;
400
374
FuncInstBuilder :: new ( self , block)
401
375
}
402
376
403
377
/// Make sure that the current block is inserted in the layout.
404
378
pub fn ensure_inserted_block ( & mut self ) {
405
- let block = self . position . block . unwrap ( ) ;
379
+ let block = self . position . unwrap ( ) ;
406
380
if self . func_ctx . blocks [ block] . pristine {
407
381
if !self . func . layout . is_block_inserted ( block) {
408
382
self . func . layout . append_block ( block) ;
@@ -424,7 +398,7 @@ impl<'a> FunctionBuilder<'a> {
424
398
self . ensure_inserted_block ( ) ;
425
399
FuncCursor :: new ( self . func )
426
400
. with_srcloc ( self . srcloc )
427
- . at_bottom ( self . position . block . unwrap ( ) )
401
+ . at_bottom ( self . position . unwrap ( ) )
428
402
}
429
403
430
404
/// Append parameters to the given `Block` corresponding to the function
@@ -495,7 +469,7 @@ impl<'a> FunctionBuilder<'a> {
495
469
496
470
// Reset srcloc and position to initial states.
497
471
self . srcloc = Default :: default ( ) ;
498
- self . position = Position :: default ( ) ;
472
+ self . position = Default :: default ( ) ;
499
473
}
500
474
}
501
475
@@ -560,26 +534,26 @@ impl<'a> FunctionBuilder<'a> {
560
534
pub fn is_unreachable ( & self ) -> bool {
561
535
let is_entry = match self . func . layout . entry_block ( ) {
562
536
None => false ,
563
- Some ( entry) => self . position . block . unwrap ( ) == entry,
537
+ Some ( entry) => self . position . unwrap ( ) == entry,
564
538
} ;
565
539
!is_entry
566
- && self . func_ctx . ssa . is_sealed ( self . position . block . unwrap ( ) )
540
+ && self . func_ctx . ssa . is_sealed ( self . position . unwrap ( ) )
567
541
&& !self
568
542
. func_ctx
569
543
. ssa
570
- . has_any_predecessors ( self . position . block . unwrap ( ) )
544
+ . has_any_predecessors ( self . position . unwrap ( ) )
571
545
}
572
546
573
547
/// Returns `true` if and only if no instructions have been added since the last call to
574
548
/// `switch_to_block`.
575
549
pub fn is_pristine ( & self ) -> bool {
576
- self . func_ctx . blocks [ self . position . block . unwrap ( ) ] . pristine
550
+ self . func_ctx . blocks [ self . position . unwrap ( ) ] . pristine
577
551
}
578
552
579
553
/// Returns `true` if and only if a terminator instruction has been inserted since the
580
554
/// last call to `switch_to_block`.
581
555
pub fn is_filled ( & self ) -> bool {
582
- self . func_ctx . blocks [ self . position . block . unwrap ( ) ] . filled
556
+ self . func_ctx . blocks [ self . position . unwrap ( ) ] . filled
583
557
}
584
558
585
559
/// Returns a displayable object for the function as it is.
@@ -824,25 +798,15 @@ fn greatest_divisible_power_of_two(size: u64) -> u64 {
824
798
825
799
// Helper functions
826
800
impl < ' a > FunctionBuilder < ' a > {
827
- fn move_to_next_basic_block ( & mut self ) {
828
- self . position . basic_block = PackedOption :: from (
829
- self . func_ctx
830
- . ssa
831
- . declare_block_body_block ( self . position . basic_block . unwrap ( ) ) ,
832
- ) ;
833
- }
834
-
835
801
/// A Block is 'filled' when a terminator instruction is present.
836
802
fn fill_current_block ( & mut self ) {
837
- self . func_ctx . blocks [ self . position . block . unwrap ( ) ] . filled = true ;
803
+ self . func_ctx . blocks [ self . position . unwrap ( ) ] . filled = true ;
838
804
}
839
805
840
806
fn declare_successor ( & mut self , dest_block : Block , jump_inst : Inst ) {
841
- self . func_ctx . ssa . declare_block_predecessor (
842
- dest_block,
843
- self . position . basic_block . unwrap ( ) ,
844
- jump_inst,
845
- ) ;
807
+ self . func_ctx
808
+ . ssa
809
+ . declare_block_predecessor ( dest_block, self . position . unwrap ( ) , jump_inst) ;
846
810
}
847
811
848
812
fn handle_ssa_side_effects ( & mut self , side_effects : SideEffects ) {
0 commit comments