From 63db86042a36f919c55b1b495d8d7b1f18098111 Mon Sep 17 00:00:00 2001 From: Toby Hutton Date: Wed, 3 Aug 2022 12:52:13 +1000 Subject: [PATCH] Add an overall description to the `simplify-cfg` IR pass. (#2446) Co-authored-by: Alex Hansen --- sway-ir/src/optimize/simplify_cfg.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/sway-ir/src/optimize/simplify_cfg.rs b/sway-ir/src/optimize/simplify_cfg.rs index 06c682c2346..df0d16f3e1c 100644 --- a/sway-ir/src/optimize/simplify_cfg.rs +++ b/sway-ir/src/optimize/simplify_cfg.rs @@ -1,3 +1,13 @@ +//! ## Simplify Control Flow Graph +//! +//! The optimizations here aim to reduce the complexity in control flow by removing basic blocks. +//! This may be done by removing 'dead' blocks which are no longer called (or in other words, have +//! no predecessors) or by merging blocks which are linked by a single unconditional branch. +//! +//! Removing blocks will make the IR neater and more efficient but will also remove indirection of +//! data flow via PHI instructions which in turn can make analyses for passes like constant folding +//! much simpler. + use crate::{ block::Block, context::Context, error::IrError, function::Function, instruction::Instruction, value::ValueDatum, @@ -130,20 +140,9 @@ fn merge_blocks(context: &mut Context, function: &Function) -> Result>(); + .collect::>(); for succ in succs { - if let Some(phi_content) = context.values.get_mut(succ.get_phi(context).0) { - if let ValueDatum::Instruction(Instruction::Phi(els)) = &mut phi_content.value { - // This is the phi for a successor block of `to_block` which we're about to - // remove/merge with `from_block`, so the predecessor needs to change from `to_block` - // to `from_block`. - els.iter_mut().for_each(|(block, _)| { - if *block == final_to_block { - *block = from_block; - } - }); - } - }; + succ.update_phi_source_block(context, final_to_block, from_block) } Ok(true)