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

Remove restriction that no loop unrolling is done when breaks are in the loop #1518

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
17 changes: 4 additions & 13 deletions src/util/loopUnrolling.ml
Original file line number Diff line number Diff line change
Expand Up @@ -31,34 +31,25 @@ class checkNoBreakVisitor = object

end

let checkNoBreakStmt stmt =
let visitor = new checkNoBreakVisitor in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checkNoBreakVisitor itself is also unused now.

ignore @@ visitCilStmt visitor stmt

let checkNoBreakBlock block =
let visitor = new checkNoBreakVisitor in
ignore @@ visitCilBlock visitor block

class findBreakVisitor(compOption: exp option ref) = object
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this visitor now, I understand why it didn't want multiple breaks. It's main goal is to actually find the comparison for the loop, which will be an if with a break inside.
By only allowing one such break it guaranteed that the result is unambiguous: there couldn't be multiple such comparisons found.

Now, if there are multiple matching ifs with breaks inside, this will still find the first one because compOption is only assigned when it's None, so that can happen at most once.
Is the loop condition always in the first matching one though? If so, then why did the old version have a problem at all? Or maybe there are loops where the condition isn't actually the first one?

inherit nopCilVisitor

method! vstmt stmt =
match stmt.skind with
| Block _ -> DoChildren
| Break _ -> raise WrongOrMultiple
| Break _ -> SkipChildren
| If (cond, t, e, _, _) -> (
checkNoBreakBlock t;
match e.bstmts with
| [s] -> (
match s.skind with
| Break _ -> (
match !compOption with
| Some _ -> raise WrongOrMultiple (*more than one loop break*)
| Some _ -> SkipChildren (*more than one loop break*)
| _ -> compOption := Some cond; SkipChildren
)
| _ -> checkNoBreakStmt stmt; SkipChildren
| _ -> SkipChildren
)
| _ -> checkNoBreakStmt stmt; SkipChildren
| _ -> SkipChildren
)
| _ -> SkipChildren

Expand Down
Loading