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

Simplify the return path analysis #6541

Merged
merged 19 commits into from
Oct 24, 2024
Merged
Changes from 3 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8dfddf0
don't follow CFG edges to MethodDeclaration nodes during return path …
jjcnn Sep 12, 2024
e944f6a
Optimizations
jjcnn Sep 12, 2024
6674fe2
Merge branch 'master' into jjcnn/return_path_analysis_exit_fix
jjcnn Sep 12, 2024
8a777e9
Merge branch 'master' into jjcnn/return_path_analysis_exit_fix
jjcnn Sep 13, 2024
a9e30a4
Merge branch 'master' of github.com:FuelLabs/sway into jjcnn/return_p…
jjcnn Oct 7, 2024
0c3b6dc
Remove RPA graph edges into local impls and functions
jjcnn Oct 9, 2024
fe44323
Merge branch 'jjcnn/return_path_analysis_exit_fix' of github.com:Fuel…
jjcnn Oct 9, 2024
6c40932
Remove unnecessary function argument
jjcnn Oct 9, 2024
afba614
Simplify leaf datastructure now that at most one leaf is available
jjcnn Oct 9, 2024
8f28e71
Simplify RPA to make it clear we're only traversing the spine of the …
jjcnn Oct 9, 2024
689e8e4
clippy, fmt
jjcnn Oct 9, 2024
0c47f7d
Merge branch 'master' into jjcnn/return_path_analysis_exit_fix
jjcnn Oct 9, 2024
67cbb2b
Added test case for local functions
jjcnn Oct 9, 2024
d0ffba6
Merge branch 'jjcnn/return_path_analysis_exit_fix' of github.com:Fuel…
jjcnn Oct 9, 2024
445839d
Merge branch 'master' into jjcnn/return_path_analysis_exit_fix
IGI-111 Oct 17, 2024
45336a6
Merge branch 'master' into jjcnn/return_path_analysis_exit_fix
JoshuaBatty Oct 24, 2024
75bf0a0
Merge branch 'master' into jjcnn/return_path_analysis_exit_fix
jjcnn Oct 24, 2024
35340d3
Merge branch 'master' into jjcnn/return_path_analysis_exit_fix
jjcnn Oct 24, 2024
2285dcf
Merge branch 'master' into jjcnn/return_path_analysis_exit_fix
tritao Oct 24, 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
46 changes: 31 additions & 15 deletions sway-core/src/control_flow_analysis/analyze_return_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
type_system::*,
Engines,
};
use im::hashset::HashSet;
use petgraph::prelude::NodeIndex;
use sway_error::error::CompileError;
use sway_types::{ident::Ident, span::Span, IdentUnique};
Expand Down Expand Up @@ -81,31 +82,46 @@ impl<'cfg> ControlFlowGraph<'cfg> {
return_ty: &TypeInfo,
) -> Vec<CompileError> {
let mut rovers = vec![entry_point];
let mut visited = vec![];
let mut errors = vec![];
while !rovers.is_empty() && rovers[0] != exit_point {
rovers.retain(|idx| *idx != exit_point);

let mut visited = HashSet::<NodeIndex>::new();
// We don't need to visit the exit point, so for efficiency assume it has already been visited.
visited.insert(exit_point);

while !rovers.is_empty() {
let mut next_rovers = vec![];
let mut last_discovered_span;
for rover in rovers {
visited.push(rover);
last_discovered_span = match &self.graph[rover] {
ControlFlowGraphNode::ProgramNode { node, .. } => Some(node.span.clone()),
ControlFlowGraphNode::MethodDeclaration { span, .. } => Some(span.clone()),
_ => None,
};
// Ignore this node if it has been visited before
if visited.contains(&rover) {
continue;
}
// Ignore this node if it represents an inner method/function declaration - these
// have already been analyzed earlier, and do not represent legal control flow for
// the current method/function.
if rover != entry_point
&& matches!(
self.graph[rover],
ControlFlowGraphNode::MethodDeclaration { .. }
)
{
continue;
}

visited.insert(rover);

let mut neighbors = self
.graph
.neighbors_directed(rover, petgraph::Direction::Outgoing)
.collect::<Vec<_>>();

if neighbors.is_empty() && !return_ty.is_unit() {
let span = match last_discovered_span {
Some(ref o) => o.clone(),
None => {
let span = match &self.graph[rover] {
ControlFlowGraphNode::ProgramNode { node, .. } => node.span.clone(),
ControlFlowGraphNode::MethodDeclaration { span, .. } => span.clone(),
_ => {
errors.push(CompileError::Internal(
"Attempted to construct return path error \
but no source span was found.",
but no source span was found.",
Span::dummy(),
));
return errors;
Expand All @@ -120,9 +136,9 @@ impl<'cfg> ControlFlowGraph<'cfg> {
ty: engines.help_out(return_ty).to_string(),
});
}

next_rovers.append(&mut neighbors);
}
next_rovers.retain(|idx| !visited.contains(idx));
rovers = next_rovers;
}

Expand Down
Loading