Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Commit 010ef5b

Browse files
committed
:const init - fold also ranges
if both ranges are constant ints, like my @A :const = (0..2);
1 parent 2f2a941 commit 010ef5b

File tree

3 files changed

+75
-18
lines changed

3 files changed

+75
-18
lines changed

.git-rr-cache

Submodule .git-rr-cache updated 88 files

op.c

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4672,7 +4672,10 @@ If not just const the left side.
46724672
OpSPECIAL on the assign op denotes :const. Undo temp. READONLY-ness via
46734673
a private OPpASSIGN_CONSTINIT bit during assignment at run-time.
46744674

4675-
Return the newASSIGNOP.
4675+
Do various compile-time assignments on const rhs values, to enable
4676+
constant folding.
4677+
4678+
Return the newASSIGNOP, or the folded assigned value.
46764679

46774680
=cut
46784681
*/
@@ -4694,7 +4697,7 @@ Perl_newASSIGNOP_maybe_const(pTHX_ OP *left, I32 optype, OP *right)
46944697
left = OpSIBLING(attr);
46954698
OpMORESIB_set(left, NULL);
46964699
OpMORESIB_set(attr, NULL);
4697-
/* Should constany folding be deferred to ck_[sa]assign? */
4700+
/* Should constant folding be deferred to ck_[sa]assign? */
46984701
if (IS_PADxV_OP(left) && left->op_targ && left->op_private == OPpLVAL_INTRO) {
46994702
if (IS_CONST_OP(right)) {
47004703
SV* lsv = PAD_SV(left->op_targ);
@@ -4717,23 +4720,60 @@ Perl_newASSIGNOP_maybe_const(pTHX_ OP *left, I32 optype, OP *right)
47174720
return ck_pad(left);
47184721
}
47194722
}
4720-
else if (IS_TYPE(left, PADAV) && IS_TYPE(right, LIST)) {
4723+
/* hashes not yet.
4724+
they don't fold and are not checked, so we can defer to run-time init */
4725+
else if (IS_TYPE(left, PADAV) &&
4726+
SvFLAGS(PAD_SV(left->op_targ)) == (SVpav_REAL|SVt_PVAV) &&
4727+
(IS_TYPE(right, LIST) ||
4728+
( IS_TYPE(right, NULL) && OpKIDS(right) &&
4729+
IS_TYPE(OpFIRST(right), FLOP)))) {
47214730
SSize_t i;
47224731
AV* lsv = (AV*)PAD_SV(left->op_targ);
47234732
/* check if all rhs elements are const */
4724-
OP *o = OpSIBLING(OpFIRST(right));
4725-
for (;o && IS_CONST_OP(o); o=OpSIBLING(o)) ;
4726-
if (!o) {
4727-
DEBUG_k(Perl_deb(aTHX_ "my %s[1] :const = (...)\n",
4728-
PAD_COMPNAME_PV(left->op_targ)));
4729-
for (i=0,o=OpSIBLING(OpFIRST(right)); o; o=OpSIBLING(o), i++) {
4730-
SV* rsv = cSVOPx_sv(o); /* XXX check for unique types */
4731-
av_store(lsv, i, SvREFCNT_inc_NN(rsv));
4733+
OP *o;
4734+
if (IS_TYPE(right, LIST)) {
4735+
for (o = OpSIBLING(OpFIRST(right));
4736+
o && IS_CONST_OP(o);
4737+
o=OpSIBLING(o)) ;
4738+
if (!o) { /* is const */
4739+
DEBUG_k(Perl_deb(aTHX_ "my %s[1] :const = (...)\n",
4740+
PAD_COMPNAME_PV(left->op_targ)));
4741+
for (i=0,o=OpSIBLING(OpFIRST(right)); o; o=OpSIBLING(o), i++) {
4742+
SV* rsv = cSVOPx_sv(o); /* XXX check for unique types */
4743+
av_store(lsv, i, SvREFCNT_inc_NN(rsv));
4744+
}
4745+
AvSHAPED_on(lsv); /* check if to set type */
4746+
SvREADONLY_on(lsv);
4747+
op_free(right);
4748+
return ck_pad(left);
4749+
}
4750+
} else { /* range */
4751+
o = OpFIRST(OpFIRST(right));
4752+
if (OpKIDS(o) && IS_TYPE(OpFIRST(o), RANGE)) {
4753+
o = OpFIRST(o); /* range */
4754+
if (IS_CONST_OP(OpNEXT(o)) && IS_CONST_OP(OpOTHER(o))) {
4755+
SV* from = cSVOPx_sv(OpNEXT(o));
4756+
SV* to = cSVOPx_sv(OpOTHER(o));
4757+
if (SvIOK(from) && SvIOK(to) && SvIVX(to) >= SvIVX(from)) {
4758+
SSize_t j = 0;
4759+
SSize_t fill = SvIVX(to) - SvIVX(from);
4760+
av_extend(lsv, fill);
4761+
DEBUG_k(Perl_deb(aTHX_
4762+
"my %s[%d] :const = (%" IVdf "..%" IVdf ")\n",
4763+
PAD_COMPNAME_PV(left->op_targ), (int)(fill+1),
4764+
SvIVX(from), SvIVX(to)));
4765+
/* XXX native int types */
4766+
for (i=SvIVX(from); j <= fill; j++) {
4767+
AvARRAY(lsv)[j] = newSViv(i++);
4768+
}
4769+
AvFILLp(lsv) = fill;
4770+
AvSHAPED_on(lsv);
4771+
SvREADONLY_on(lsv);
4772+
op_free(right);
4773+
return ck_pad(left);
4774+
}
4775+
}
47324776
}
4733-
AvSHAPED_on(lsv); /* we can even type it */
4734-
SvREADONLY_on(lsv);
4735-
op_free(right);
4736-
return ck_pad(left);
47374777
}
47384778
}
47394779
}
@@ -4781,8 +4821,8 @@ Perl_newASSIGNOP_maybe_const(pTHX_ OP *left, I32 optype, OP *right)
47814821
}
47824822
}
47834823
}
4784-
/* else not constant foldable. like a lhs ref or list. */
4785-
/* if :const is the only attrib skip attr */
4824+
/* else not constant foldable. like a lhs ref, hash or list. */
4825+
/* if :const is the only attr skip attributes->import */
47864826
if (num > 1) {
47874827
return op_append_list(OP_LINESEQ,
47884828
newASSIGNOP(OPf_STACKED|OPf_SPECIAL,

pod/perlcperl.pod

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,23 @@ functions, packages + classes. C<:const> hashes should of course be
769769
perfect, i.e. optimized to constant-time lookup, eliminating hash
770770
collisions.
771771

772+
The following declarations are all compile-time assigned, and allow subsequent
773+
constant folding on all usages. I.e. const assignments with all constant rhs
774+
values.
775+
776+
my $i :const = 1;
777+
our $i :const = 1;
778+
my @a :const = (1); # also sets the array shaped as int @a[1]
779+
my @a :const = (1,2); # shaped as int @a[2]
780+
my @a :const = (0..2); # shaped as int @a[3]
781+
782+
With non-constant right-hand side values the assignment is done at run-time
783+
and as thus only writes are caught at compile-time, but constant folding is not
784+
available. Hashes are also not yet compile-time assigned.
785+
786+
:const arrays with values of unique types will be optimized to native
787+
shaped arrays. See L</Typed and shaped arrays>.
788+
772789
See L<perltypes/:const>.
773790

774791
=head2 Compile-time optimizations

0 commit comments

Comments
 (0)