Remove defunct OPs in Perl_scalar/Perl_scalarvoid#23890
Remove defunct OPs in Perl_scalar/Perl_scalarvoid#23890richardleach wants to merge 1 commit intoPerl:bleadfrom
Conversation
cc16f93 to
64b96de
Compare
`my $x = (1,2,3);` produces the following OP tree in blead:
2 <;> nextstate(main 1 -e:1) v:{ ->3
6 <1> padsv_store[$x:1,2] vKS/LVINTRO ->7
5 <@> list sKP ->6
3 <0> pushmark v ->4
- <0> ex-const v ->-
- <0> ex-const v ->4
4 <$> const(IV 3) s ->5
- <0> ex-padsv sRM*/LVINTRO ->6
This is functionally equivalent to `my $x = 3;`:
2 <;> nextstate(main 1 -e:1) v:{ ->3
4 <1> padsv_store[$x:1,2] vKS/LVINTRO ->5
3 <$> const(IV 3) s ->4
- <0> ex-padsv sRM*/LVINTRO ->4
Construction of the first tree typically generates "Useless use of X
in scalar context" warnings, but special cases such as the constants
`0` and `1` are excluded from these warnings.
This commit modifies the functions responsible for assigning scalar
or void context to OPs to remove:
* `OP_NULL` nodes with no kids and a following sibling.
* `OP_LIST` nodes with only a single-scalar-pushing kid OP.
This transforms the first OP tree above into the second.
Besides having a "cleaner-looking" optree that's easier to follow when
debuggging Perl code or porting, there are other practical benefits:
* If the op_next chain hasn't been built, LINKLIST won't have to traverse
these OP nodes and link them in. Subsequent compiler steps then won't
re-traverse the same nodes to optimize them out of the op_next chain.
* Anything traversing - or cloning - the full optree has fewer defunct
OP nodes to visit.
* OP slabs may contain a higher proportion of live OPs, reducing
TLB pressure (on systems or workloads where that matters).
64b96de to
9a9c29f
Compare
|
The change looks reasonable, though doing a coverage test they aren't hit much, the first part: The second part: |
Yeah, this is true. I'm not sure how much that will be inherently true and how much is because the test cases are well written - and some code in the wild might benefit more? The addition to |
| if (!sib2) { | ||
| if ( | ||
| PL_opargs[sib1->op_type] & OA_RETSCALAR |
There was a problem hiding this comment.
Rather than two nested ifs with no extra code, this might be neater and avoid a level of indent as if (!sib2 && (PL_op_args[sib1->op_type] & OA_RETSCALAR))
| if (OP_TYPE_IS(prev_kid, OP_NEXTSTATE) && sib | ||
| && OP_TYPE_IS(sib, OP_NEXTSTATE)) { | ||
| op_null(prev_kid); |
There was a problem hiding this comment.
Don't forget that under perl -d, these are OP_DBSTATE. I wrote a handy helper macro for such; OP_TYPE_IS_COP_NN.
if (OP_TYPE_IS_COP_NN(prev_kid) && OP_TYPE_IS_COP_NN(sib))| prev_kid = kid; | ||
| kid = sib; | ||
| } | ||
| } |
There was a problem hiding this comment.
The addition of this single brace that aligns with the one on the line above suggests something odd has happened with indentation here.
| kid->op_targ != OP_NEXTSTATE && | ||
| kid->op_targ != OP_DBSTATE |
There was a problem hiding this comment.
I wonder if this should be neatened by adding a similar OP_TYPE_WAS_COP_NN() macro.
There was a problem hiding this comment.
Yeah, I could see that being useful.
Although since there's an OP_TYPE_IS_OR_WAS, does that mean we should also have an OP_TYPE_IS_OR_WAS_COP_NN? (Serious question, honest. 😝 )
|
@richardleach is this p.r. something we're going to (or should) pursue in the current dev cycle? |
No. I still want to dig around it before deciding what to do with it, but it definitely shouldn't be merged this close to a stable release. Adding the defer-next-dev label. |
my $x = (1,2,3);produces the following OP tree in blead:This is functionally equivalent to
my $x = 3;:Construction of the first tree typically generates "Useless use of X in scalar context" warnings, but special cases such as the constants
0and1are excluded from these warnings.This commit modifies the functions responsible for assigning scalar or void context to OPs to remove:
OP_NULLnodes with no kids and a following sibling.OP_LISTnodes with only a single-scalar-pushing kid OP.This transforms the first OP tree above into the second.
Besides having a "cleaner-looking" optree that's easier to follow when debuggging Perl code or porting, there are other practical benefits:
Note: this PR replaces #23523. It was easier to implement in op.c than I'd
originally anticipated and, as mentioned above, doing so reduces the number of
times such defunct nodes have to be processed during compilation.