From a6ca1fdaca41968cf1d8d6ef45c3c858bde298a7 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 3 Oct 2024 18:41:43 +0000 Subject: [PATCH 1/3] optimize first array get from set even if the index is dynamic but at the same index --- .../noirc_evaluator/src/ssa/ir/instruction.rs | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 676bb48c4d9..84804207e04 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -623,11 +623,7 @@ impl Instruction { } } Instruction::ArrayGet { array, index } => { - if let Some(index) = dfg.get_numeric_constant(*index) { - try_optimize_array_get_from_previous_set(dfg, *array, index) - } else { - None - } + try_optimize_array_get_from_previous_set(dfg, *array, *index) } Instruction::ArraySet { array, index, value, .. } => { let array_const = dfg.get_array_constant(*array); @@ -776,9 +772,21 @@ impl Instruction { /// - If the array value is from a previous array-set, we recur. fn try_optimize_array_get_from_previous_set( dfg: &DataFlowGraph, - mut array_id: Id, - target_index: FieldElement, + mut array_id: ValueId, + target_index: ValueId, ) -> SimplifyResult { + if let Value::Instruction { instruction, .. } = &dfg[array_id] { + if let Instruction::ArraySet { index, value, .. } = &dfg[*instruction] { + if *index == target_index { + return SimplifyResult::SimplifiedTo(*value); + } + } + } + + let Some(target_index) = dfg.get_numeric_constant(target_index) else { + return SimplifyResult::None; + }; + let mut elements = None; // Arbitrary number of maximum tries just to prevent this optimization from taking too long. From 46773a6e408a3a557b3127c3bf3017e291292ea7 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 3 Oct 2024 19:26:34 +0000 Subject: [PATCH 2/3] expand comment --- compiler/noirc_evaluator/src/ssa/ir/instruction.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 84804207e04..140b0255cf8 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -755,6 +755,16 @@ impl Instruction { } } +/// If we have an array get whose array is from an array set at the same index, +/// we can simplify that array get to the value in that array set. +/// +/// Simple case: +/// v4 = array_set v1, index v2, value v3 +/// v5 = array_get v4, index v2 +/// +/// If we could not immediately simplify the array get, we can try to follow +/// the array set backwards in the case we have constant indices: +/// /// Given a chain of operations like: /// v1 = array_set [10, 11, 12], index 1, value: 5 /// v2 = array_set v1, index 2, value: 6 From 3797c089b77f2a3d2b597735215b6c3f174b6100 Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 3 Oct 2024 19:26:46 +0000 Subject: [PATCH 3/3] fmt --- compiler/noirc_evaluator/src/ssa/ir/instruction.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 140b0255cf8..ae4abdce56a 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -761,7 +761,7 @@ impl Instruction { /// Simple case: /// v4 = array_set v1, index v2, value v3 /// v5 = array_get v4, index v2 -/// +/// /// If we could not immediately simplify the array get, we can try to follow /// the array set backwards in the case we have constant indices: ///