@@ -11,11 +11,12 @@ use fxhash::FxHasher64;
1111use iter_extended:: vecmap;
1212use noirc_frontend:: hir_def:: types:: Type as HirType ;
1313
14- use crate :: ssa:: opt:: flatten_cfg:: value_merger:: ValueMerger ;
14+ use crate :: ssa:: { ir :: function :: RuntimeType , opt:: flatten_cfg:: value_merger:: ValueMerger } ;
1515
1616use super :: {
1717 basic_block:: BasicBlockId ,
1818 dfg:: { CallStack , DataFlowGraph } ,
19+ function:: Function ,
1920 map:: Id ,
2021 types:: { NumericType , Type } ,
2122 value:: { Value , ValueId } ,
@@ -269,15 +270,7 @@ pub(crate) enum Instruction {
269270 /// else_value
270271 /// }
271272 /// ```
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 } ,
281274
282275 /// Creates a new array or slice.
283276 ///
@@ -371,12 +364,12 @@ impl Instruction {
371364 }
372365 }
373366
374- pub ( crate ) fn can_eliminate_if_unused ( & self , dfg : & DataFlowGraph ) -> bool {
367+ pub ( crate ) fn can_eliminate_if_unused ( & self , function : & Function ) -> bool {
375368 use Instruction :: * ;
376369 match self {
377370 Binary ( binary) => {
378371 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 ) {
380373 rhs != FieldElement :: zero ( )
381374 } else {
382375 false
@@ -395,15 +388,26 @@ impl Instruction {
395388 | ArraySet { .. }
396389 | MakeArray { .. } => true ,
397390
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+
398403 Constrain ( ..)
399- | Store { .. }
400404 | EnableSideEffectsIf { .. }
401405 | IncrementRc { .. }
402406 | DecrementRc { .. }
403407 | RangeCheck { .. } => false ,
404408
405409 // 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] {
407411 // Explicitly allows removal of unused ec operations, even if they can fail
408412 Value :: Intrinsic ( Intrinsic :: BlackBox ( BlackBoxFunc :: MultiScalarMul ) )
409413 | Value :: Intrinsic ( Intrinsic :: BlackBox ( BlackBoxFunc :: EmbeddedCurveAdd ) ) => true ,
@@ -524,14 +528,11 @@ impl Instruction {
524528 assert_message : assert_message. clone ( ) ,
525529 }
526530 }
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+ } ,
535536 Instruction :: MakeArray { elements, typ } => Instruction :: MakeArray {
536537 elements : elements. iter ( ) . copied ( ) . map ( f) . collect ( ) ,
537538 typ : typ. clone ( ) ,
@@ -590,10 +591,9 @@ impl Instruction {
590591 | Instruction :: RangeCheck { value, .. } => {
591592 f ( * value) ;
592593 }
593- Instruction :: IfElse { then_condition, then_value, else_condition , else_value } => {
594+ Instruction :: IfElse { then_condition, then_value, else_value } => {
594595 f ( * then_condition) ;
595596 f ( * then_value) ;
596- f ( * else_condition) ;
597597 f ( * else_value) ;
598598 }
599599 Instruction :: MakeArray { elements, typ : _ } => {
@@ -756,7 +756,7 @@ impl Instruction {
756756 None
757757 }
758758 }
759- Instruction :: IfElse { then_condition, then_value, else_condition , else_value } => {
759+ Instruction :: IfElse { then_condition, then_value, else_value } => {
760760 let typ = dfg. type_of_value ( * then_value) ;
761761
762762 if let Some ( constant) = dfg. get_numeric_constant ( * then_condition) {
@@ -775,13 +775,11 @@ impl Instruction {
775775
776776 if matches ! ( & typ, Type :: Numeric ( _) ) {
777777 let then_condition = * then_condition;
778- let else_condition = * else_condition;
779778
780779 let result = ValueMerger :: merge_numeric_values (
781780 dfg,
782781 block,
783782 then_condition,
784- else_condition,
785783 then_value,
786784 else_value,
787785 ) ;
0 commit comments