Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ssa): don't deduplicate constraints in blocks that are not dominated #6627

Merged
merged 23 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
2d19468
Add a test that fails
asterite Nov 26, 2024
98d246b
Add simplify function
aakoshh Nov 26, 2024
2dec436
Add SimplificationCache
aakoshh Nov 26, 2024
f27b1d2
Add docs
aakoshh Nov 26, 2024
4e9c140
Fix bug by restriting view
aakoshh Nov 26, 2024
2c95130
Allow multiple blocks
aakoshh Nov 26, 2024
fd19fb0
Add a regression test for instruction hoisting
asterite Nov 26, 2024
cd26a1b
Don't hoist instructions that have side effects
asterite Nov 26, 2024
85fbebd
Move Dom up
aakoshh Nov 26, 2024
7b28c59
Merge branch 'ab/constant_folding_bug' of github.com:noir-lang/noir i…
aakoshh Nov 26, 2024
e17a570
Use BTreeMap to store block IDs
aakoshh Nov 27, 2024
069f260
Walk up the dominator tree to find the first simplification
aakoshh Nov 27, 2024
3db0696
Do not find anything for unreachable nodes
aakoshh Nov 27, 2024
5b196d5
Add Instruction::has_side_effect and use it to disable hoisting
aakoshh Nov 27, 2024
911aedb
Update compiler/noirc_evaluator/src/ssa/opt/constant_folding.rs
aakoshh Nov 27, 2024
c07d760
Remove Predicate
aakoshh Nov 27, 2024
41502f6
No need for mutable any more. No need to check empty either
aakoshh Nov 27, 2024
8572b40
Merge branch 'master' into ab/constant_folding_bug
aakoshh Nov 27, 2024
05cf0a9
Fix comment
aakoshh Nov 27, 2024
1a9bb76
Merge branch 'ab/constant_folding_bug' of github.com:noir-lang/noir i…
aakoshh Nov 27, 2024
ae1da8d
Merge remote-tracking branch 'origin/master' into ab/constant_folding…
aakoshh Nov 27, 2024
1e835b5
Use requires_acir_gen_predicate in has_side_effects
aakoshh Nov 27, 2024
75090df
Merge branch 'master' into ab/constant_folding_bug
TomAFrench Nov 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ir/dom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,29 @@ impl DominatorTree {
}
}

/// Walk up the dominator tree until we find a block for which `f` returns `Some` value.
/// Otherwise return `None` when we reach the top.
///
/// Similar to `Iterator::filter_map` but only returns the first hit.
pub(crate) fn find_map_dominator<T>(
&self,
mut block_id: BasicBlockId,
f: impl Fn(BasicBlockId) -> Option<T>,
) -> Option<T> {
if !self.is_reachable(block_id) {
return None;
}
loop {
if let Some(value) = f(block_id) {
return Some(value);
}
block_id = match self.immediate_dominator(block_id) {
Some(immediate_dominator) => immediate_dominator,
None => return None,
}
}
}

/// Allocate and compute a dominator tree from a pre-computed control flow graph and
/// post-order counterpart.
pub(crate) fn with_cfg_and_post_order(cfg: &ControlFlowGraph, post_order: &PostOrder) -> Self {
Expand Down Expand Up @@ -448,4 +471,22 @@ mod tests {
assert!(dt.dominates(block2_id, block1_id));
assert!(dt.dominates(block2_id, block2_id));
}

#[test]
fn test_find_map_dominator() {
let (dt, b0, b1, b2, _b3) = unreachable_node_setup();

assert_eq!(
dt.find_map_dominator(b2, |b| if b == b0 { Some("root") } else { None }),
Some("root")
);
assert_eq!(
dt.find_map_dominator(b1, |b| if b == b0 { Some("unreachable") } else { None }),
None
);
assert_eq!(
dt.find_map_dominator(b1, |b| if b == b1 { Some("not part of tree") } else { None }),
None
);
}
}
38 changes: 38 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ir/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,44 @@
matches!(self.result_type(), InstructionResultType::Unknown)
}

/// Indicates if the instruction has a side effect, ie. it can fail, or it interacts with memory.
///
/// This is similar to `can_be_deduplicated`, but it doesn't depend on whether the caller takes
/// constraints into account, because it might not use it to isolate the side effects across branches.
pub(crate) fn has_side_effects(&self, dfg: &DataFlowGraph) -> bool {
use Instruction::*;

match self {
// These either have side-effects or interact with memory
EnableSideEffectsIf { .. }
| Allocate
| Load { .. }
| Store { .. }
| IncrementRc { .. }
| DecrementRc { .. } => true,

Call { func, .. } => match dfg[*func] {
Value::Intrinsic(intrinsic) => intrinsic.has_side_effects(),
_ => true, // Be conservative and assume other functions can have side effects.
},

// These can fail.
Constrain(..) | RangeCheck { .. } => true,

// This should never be side-effectful

Check warning on line 389 in compiler/noirc_evaluator/src/ssa/ir/instruction.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (effectful)
MakeArray { .. } => false,

// These can have different behavior depending on the EnableSideEffectsIf context.
Binary(_)
| Cast(_, _)
| Not(_)
| Truncate { .. }
| IfElse { .. }
| ArrayGet { .. }
| ArraySet { .. } => self.requires_acir_gen_predicate(dfg),
}
}

/// Indicates if the instruction can be safely replaced with the results of another instruction with the same inputs.
/// If `deduplicate_with_predicate` is set, we assume we're deduplicating with the instruction
/// and its predicate, rather than just the instruction. Setting this means instructions that
Expand Down Expand Up @@ -397,7 +435,7 @@
// We can deduplicate these instructions if we know the predicate is also the same.
Constrain(..) | RangeCheck { .. } => deduplicate_with_predicate,

// This should never be side-effectful

Check warning on line 438 in compiler/noirc_evaluator/src/ssa/ir/instruction.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (effectful)
MakeArray { .. } => true,

// These can have different behavior depending on the EnableSideEffectsIf context.
Expand Down
Loading
Loading