-
-
Notifications
You must be signed in to change notification settings - Fork 795
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
fix[venom]: fix invalid phi
s after SCCP
#4181
fix[venom]: fix invalid phi
s after SCCP
#4181
Conversation
shouldn't we fix up the phi nodes during sccp directly? |
vyper/venom/passes/sccp/sccp.py
Outdated
@@ -305,6 +311,9 @@ def _replace_constants(self, inst: IRInstruction): | |||
inst.opcode = "jmp" | |||
inst.operands = [target] | |||
self.cfg_dirty = True | |||
for bb in inst.parent.cfg_out: | |||
if bb.label == target: | |||
self.cfg_phi_fix_needed.add(bb) |
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 self._fix_phi_bb_r(bb, OrderedSet())
here and remove all the need for self.cfg_phi_fix_needed
and iterating later?
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.
The reason was not to iterate over some basic block multiple times. Since solutions only detects start from which the occurrence of faulty phi node could be possible but not the end there could be a lot of overlap. In this case since I iterate over possible positions of the faulty phi nodes at the end I visit every possible basic block only once.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #4181 +/- ##
==========================================
- Coverage 91.35% 88.22% -3.14%
==========================================
Files 109 109
Lines 15641 15672 +31
Branches 3443 3454 +11
==========================================
- Hits 14289 13826 -463
- Misses 920 1314 +394
- Partials 432 532 +100 ☔ View full report in Codecov by Sentry. |
vyper/venom/passes/sccp/sccp.py
Outdated
from_src_bb = filter(lambda x: x[0] == src_bb.label, phi_inst.phi_operands) | ||
operands = list(map(lambda x: x[1], from_src_bb)) |
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.
please use a list comprehension here
from_src_bb = filter(lambda x: x[0] == src_bb.label, phi_inst.phi_operands) | |
operands = list(map(lambda x: x[1], from_src_bb)) | |
operands = [op for label, op in phi_inst.phi_operands if label == src_bb.label] |
vyper/venom/passes/sccp/sccp.py
Outdated
|
||
assert len(operands) == 1 | ||
assert isinstance(operands[0], IRVariable) | ||
assert phi_inst.output is not None |
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.
assert phi_inst.output is not None | |
assert phi_inst.output is not None | |
vyper/venom/passes/sccp/sccp.py
Outdated
@@ -305,6 +311,9 @@ def _replace_constants(self, inst: IRInstruction): | |||
inst.opcode = "jmp" | |||
inst.operands = [target] | |||
self.cfg_dirty = True | |||
for bb in inst.parent.cfg_out: | |||
if bb.label == target: | |||
self.cfg_phi_fix_needed.add(bb) |
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.
self.cfg_phi_fix_needed.add(bb) | |
self.cfg_phi_fix_needed.add(bb) | |
break |
vyper/venom/passes/sccp/sccp.py
Outdated
for next_bb in bb.cfg_out: | ||
self._fix_phi_bb_r(next_bb, visited) | ||
|
||
def _fix_phi_node_inst(self, phi_inst: IRInstruction): |
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.
def _fix_phi_node_inst(self, phi_inst: IRInstruction): | |
def _fix_phi_inst(self, phi_inst: IRInstruction): |
vyper/venom/passes/sccp/sccp.py
Outdated
@@ -329,6 +338,40 @@ def _replace_constants(self, inst: IRInstruction): | |||
if isinstance(lat, IRLiteral): | |||
inst.operands[i] = lat | |||
|
|||
def _fix_phi_nodes(self): | |||
visited: OrderedSet[IRBasicBlock] = OrderedSet() |
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 keep track of visited, instead of just iterating over fn.get_basic_blocks()
?
vyper/venom/passes/sccp/sccp.py
Outdated
assert len(operands) == 1 | ||
assert isinstance(operands[0], IRVariable) | ||
assert phi_inst.output is not None | ||
phi_inst.output.value = operands[0] |
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 modify the instruction if it gets removed on the next line?
vyper/venom/passes/sccp/sccp.py
Outdated
self._fix_phi_bb_r(next_bb, visited) | ||
|
||
def _fix_phi_node_inst(self, phi_inst: IRInstruction): | ||
if len(phi_inst.parent.cfg_in) != 1: |
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.
when can this happen? shouldn't we handle this case?
i pushed some cleanup here: HodanPlodky#2. it feels like a kludge though, since it seems like we really should be fixing up these phi nodes inside of |
simplify the cleanup - transforming phis to store instead of removing them
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.
pushed some stuff, lgtm now. @harkal mind taking a look?
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.
lgtm
phi
s after SCCP
This commit reduces `phi` nodes which, after SCCP, refer to a basic block which is unreachable. This could happen when the SCCP would replace a `jnz` by a `jmp` instruction, resulting in a `phi` instruction which refers to a non-existent block, or a `phi` instruction in a basic block which only has one predecessor. This commit reduces such `phi` instructions into `store` instructions. --------- Co-authored-by: Harry Kalogirou <[email protected]> Co-authored-by: Charles Cooper <[email protected]>
What I did
Fix for issues #4162 and #4070
How I did it
Removed the phi nodes which were not in use after
SCCP
pass. This could happen when theSCCP
would replacejnz
byjmp
instruction and by this removing need forphi
instruction (this is the case in #4162). More over the when merging the basic block in theSimplifyCFGPass
there could be problem when renaming the labels inphi
nodes since it went only into the firstcfg_out
basic block (this is the case in #4070)How to verify it
So far both of the POC from compile correctly
Commit message