Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 18 additions & 16 deletions c2rust-transpile/src/cfg/loops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,28 +170,30 @@ impl<Lbl: Hash + Eq + Clone> LoopInfo<Lbl> {
self.loops.extend(other.loops);
}

/// Find the smallest possible loop that contains all of the items
/// Finds the smallest possible loop that contains all of the entries.
pub fn tightest_common_loop<E: Iterator<Item = Lbl>>(&self, mut entries: E) -> Option<LoopId> {
// Start with the loop containing the first entry.
let first = entries.next()?;

let mut loop_id = *self.node_loops.get(&first)?;

// Widen the loop until it contains the all of our entries, or it can no longer
// be widened.
for entry in entries {
// Widen the loop until it contains the `entry`, or it can no longer be widened.
loop {
match self.loops.get(&loop_id) {
Some((ref in_loop, parent_id)) => {
if in_loop.contains(&entry) {
break;
}
loop_id = if let Some(i) = parent_id {
*i
} else {
return None;
};
}

None => return None,
// NOTE: We currently bail out in the case where there is no loop data
// corresponding to the current loop ID, but it's unclear if that's the right
// thing to do. In theory we should always have loop data corresponding to a
// loop ID, but the `nested_goto.c` test definitely ends up with a loop ID that
// doesn't have corresponding info. We should investigate why that happens and
// determine if it's valid or not.
let (in_loop, parent_id) = self.loops.get(&loop_id)?;

// If our current loop contains the entry, move on to the next entry. Otherwise
// move on to the next wider loop if there is one.
if in_loop.contains(&entry) {
break;
} else {
loop_id = parent_id.clone()?;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions c2rust-transpile/src/cfg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
//! - simplify that sequence of `Structure<Stmt>`s into another such sequence
//! - convert the `Vec<Structure<Stmt>>` back into a `Vec<Stmt>`
//!
//! See the [`relooper`] module for more details about the Relooper algorithm.

use crate::c_ast::iterators::{DFExpr, SomeId};
use crate::c_ast::CLabelId;
Expand Down
Loading