-
Notifications
You must be signed in to change notification settings - Fork 1.9k
C++: Remove infeasible edges to reachable blocks #694
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
Conversation
The existing unreachable IR removal code only retargeted an infeasible edge to an `Unreached` instruction if the successor of the edge was an unreachable block. This is too conservative, because it doesn't remove an infeasible edge that targets a block that is still reachable via other paths. The trivial example of this is `do { } while (false);`, where the back edge is infeasible, but the body block is still reachable from the loop entry.
This change retargets all infeasible edges to `Unreached` instructions, regardless of the reachability of the successor block.
|
This pull request introduces 126 alerts when merging 56bb9dc into b8877f1 - view on LGTM.com new alerts:
Comment posted by LGTM.com |
jbj
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise LGTM
|
|
||
| final ReachableBlock getAFeasibleSuccessor() { | ||
| this = getAFeasiblePredecessorBlock(result) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a dangerous API. It's easy to accidentally call getASuccessor instead of getAFeasibleSuccessor. How much of a hassle would it be to let ReachableBlock extend TIRBlock instead of IRBlock so it doesn't inherit getASuccessor? If it's not convenient to expose TIRBlock, an alternative is to make an IRBlockBase class like I've done with ControlFlowNodeBase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion. I've factored out IRBlockBase, and used it as the base type for both IRBlock and ReachableBlock.
| ) | ||
| // We need an `Unreached` instruction for the destination of each infeasible edge whose | ||
| // predecessor is reachable. | ||
| Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not have just a single Unreached instruction, shared by the whole function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered that, but eventually went with one Unreached per edge to avoid introducing "critical" edges (edges whose predecessor block has multiple successors and whose successor block has multiple predecessors). Critical edges make it difficult to insert inference operators. For these edges, though, I guess we wouldn't have anything interesting to infer anyway, so I'll try folding all of the Unreached instructions into one per function.
|
The tests failed: |
|
The test failures are in the IR Guards tests. Some of it is due to new unreachable edges that were removed, but most of the diffs are due to merging all of the |
Post-release preparation for codeql-cli-2.8.1
The existing unreachable IR removal code only retargeted an infeasible edge to an
Unreachedinstruction if the successor of the edge was an unreachable block. This is too conservative, because it doesn't remove an infeasible edge that targets a block that is still reachable via other paths. The trivial example of this isdo { } while (false);, where the back edge is infeasible, but the body block is still reachable from the loop entry.This change retargets all infeasible edges to
Unreachedinstructions, regardless of the reachability of the successor block.