@@ -11,11 +11,12 @@ use fxhash::FxHasher64;
11
11
use iter_extended:: vecmap;
12
12
use noirc_frontend:: hir_def:: types:: Type as HirType ;
13
13
14
- use crate :: ssa:: opt:: flatten_cfg:: value_merger:: ValueMerger ;
14
+ use crate :: ssa:: { ir :: function :: RuntimeType , opt:: flatten_cfg:: value_merger:: ValueMerger } ;
15
15
16
16
use super :: {
17
17
basic_block:: BasicBlockId ,
18
18
dfg:: { CallStack , DataFlowGraph } ,
19
+ function:: Function ,
19
20
map:: Id ,
20
21
types:: { NumericType , Type } ,
21
22
value:: { Value , ValueId } ,
@@ -269,15 +270,7 @@ pub(crate) enum Instruction {
269
270
/// else_value
270
271
/// }
271
272
/// ```
272
- ///
273
- /// Where we save the result of !then_condition so that we have the same
274
- /// ValueId for it each time.
275
- IfElse {
276
- then_condition : ValueId ,
277
- then_value : ValueId ,
278
- else_condition : ValueId ,
279
- else_value : ValueId ,
280
- } ,
273
+ IfElse { then_condition : ValueId , then_value : ValueId , else_value : ValueId } ,
281
274
282
275
/// Creates a new array or slice.
283
276
///
@@ -371,12 +364,12 @@ impl Instruction {
371
364
}
372
365
}
373
366
374
- pub ( crate ) fn can_eliminate_if_unused ( & self , dfg : & DataFlowGraph ) -> bool {
367
+ pub ( crate ) fn can_eliminate_if_unused ( & self , function : & Function ) -> bool {
375
368
use Instruction :: * ;
376
369
match self {
377
370
Binary ( binary) => {
378
371
if matches ! ( binary. operator, BinaryOp :: Div | BinaryOp :: Mod ) {
379
- if let Some ( rhs) = dfg. get_numeric_constant ( binary. rhs ) {
372
+ if let Some ( rhs) = function . dfg . get_numeric_constant ( binary. rhs ) {
380
373
rhs != FieldElement :: zero ( )
381
374
} else {
382
375
false
@@ -395,15 +388,26 @@ impl Instruction {
395
388
| ArraySet { .. }
396
389
| MakeArray { .. } => true ,
397
390
391
+ // Store instructions must be removed by DIE in acir code, any load
392
+ // instructions should already be unused by that point.
393
+ //
394
+ // Note that this check assumes that it is being performed after the flattening
395
+ // pass and after the last mem2reg pass. This is currently the case for the DIE
396
+ // pass where this check is done, but does mean that we cannot perform mem2reg
397
+ // after the DIE pass.
398
+ Store { .. } => {
399
+ matches ! ( function. runtime( ) , RuntimeType :: Acir ( _) )
400
+ && function. reachable_blocks ( ) . len ( ) == 1
401
+ }
402
+
398
403
Constrain ( ..)
399
- | Store { .. }
400
404
| EnableSideEffectsIf { .. }
401
405
| IncrementRc { .. }
402
406
| DecrementRc { .. }
403
407
| RangeCheck { .. } => false ,
404
408
405
409
// Some `Intrinsic`s have side effects so we must check what kind of `Call` this is.
406
- Call { func, .. } => match dfg[ * func] {
410
+ Call { func, .. } => match function . dfg [ * func] {
407
411
// Explicitly allows removal of unused ec operations, even if they can fail
408
412
Value :: Intrinsic ( Intrinsic :: BlackBox ( BlackBoxFunc :: MultiScalarMul ) )
409
413
| Value :: Intrinsic ( Intrinsic :: BlackBox ( BlackBoxFunc :: EmbeddedCurveAdd ) ) => true ,
@@ -524,14 +528,11 @@ impl Instruction {
524
528
assert_message : assert_message. clone ( ) ,
525
529
}
526
530
}
527
- Instruction :: IfElse { then_condition, then_value, else_condition, else_value } => {
528
- Instruction :: IfElse {
529
- then_condition : f ( * then_condition) ,
530
- then_value : f ( * then_value) ,
531
- else_condition : f ( * else_condition) ,
532
- else_value : f ( * else_value) ,
533
- }
534
- }
531
+ Instruction :: IfElse { then_condition, then_value, else_value } => Instruction :: IfElse {
532
+ then_condition : f ( * then_condition) ,
533
+ then_value : f ( * then_value) ,
534
+ else_value : f ( * else_value) ,
535
+ } ,
535
536
Instruction :: MakeArray { elements, typ } => Instruction :: MakeArray {
536
537
elements : elements. iter ( ) . copied ( ) . map ( f) . collect ( ) ,
537
538
typ : typ. clone ( ) ,
@@ -590,10 +591,9 @@ impl Instruction {
590
591
| Instruction :: RangeCheck { value, .. } => {
591
592
f ( * value) ;
592
593
}
593
- Instruction :: IfElse { then_condition, then_value, else_condition , else_value } => {
594
+ Instruction :: IfElse { then_condition, then_value, else_value } => {
594
595
f ( * then_condition) ;
595
596
f ( * then_value) ;
596
- f ( * else_condition) ;
597
597
f ( * else_value) ;
598
598
}
599
599
Instruction :: MakeArray { elements, typ : _ } => {
@@ -756,7 +756,7 @@ impl Instruction {
756
756
None
757
757
}
758
758
}
759
- Instruction :: IfElse { then_condition, then_value, else_condition , else_value } => {
759
+ Instruction :: IfElse { then_condition, then_value, else_value } => {
760
760
let typ = dfg. type_of_value ( * then_value) ;
761
761
762
762
if let Some ( constant) = dfg. get_numeric_constant ( * then_condition) {
@@ -775,13 +775,11 @@ impl Instruction {
775
775
776
776
if matches ! ( & typ, Type :: Numeric ( _) ) {
777
777
let then_condition = * then_condition;
778
- let else_condition = * else_condition;
779
778
780
779
let result = ValueMerger :: merge_numeric_values (
781
780
dfg,
782
781
block,
783
782
then_condition,
784
- else_condition,
785
783
then_value,
786
784
else_value,
787
785
) ;
0 commit comments