Perl / perl5

šŸŖ The Perl programming language
https://dev.perl.org/perl5/
Other
1.89k stars 538 forks source link

Optimizer isn't optimizing read-only value decisions #14305

Open p5pRT opened 9 years ago

p5pRT commented 9 years ago

Migrated from rt.perl.org#123370 (status was 'open')

Searchable as RT123370$

p5pRT commented 9 years ago

From @khwilliamson

This is a bug report for perl from khw@​khw.(none)\, generated with the help of perlbug 1.40 running under perl 5.21.7.


I noticed that expressions that contain read-only variables such as $^V or $]\, etc don't seem to get constant-folded\, so for example

  if($] \< 5.007) {   FOO()   } elsif ($] >= 5.007003) {   BAR()   } else {   BAZ()   }

should just have generated unconditional code that calls BAR()\, with everything else gone.

I was surprised to find this\, because I thought the optimizer handled such things\, and this seems like a blatant oversight.



Flags​:   category=core   severity=low


Site configuration information for perl 5.21.7​:

Configured by khw at Fri Dec 5 08​:31​:42 MST 2014.

Summary of my perl5 (revision 5 version 21 subversion 7) configuration​:   Commit id​: b173165cb2425ea00a041490534260cd10909456   Platform​:   osname=linux\, osvers=3.13.0-40-generic\, archname=x86_64-linux-thread-multi-ld   uname='linux khw 3.13.0-40-generic #69-ubuntu smp thu nov 13 17​:53​:56 utc 2014 x86_64 x86_64 x86_64 gnulinux '   config_args='-des -Uversiononly -Dprefix=/home/khw/blead -Dusedevel -D'optimize=-ggdb3' -A'optimize=-ggdb3' -A'optimize=-O0' -Accflags='-DPERL_BOOL_AS_CHAR' -Dman1dir=none -Dman3dir=none -DDEBUGGING -Dcc=g++ -Dusemorebits -Dusethreads'   hint=recommended\, useposix=true\, d_sigaction=define   useithreads=define\, usemultiplicity=define   use64bitint=define\, use64bitall=define\, uselongdouble=define   usemymalloc=n\, bincompat5005=undef   Compiler​:   cc='g++'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -DPERL_BOOL_AS_CHAR -fwrapv -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'\,   optimize=' -ggdb3 -O0'\,   cppflags='-D_REENTRANT -D_GNU_SOURCE -DPERL_BOOL_AS_CHAR -fwrapv -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'   ccversion=''\, gccversion='4.8.2'\, gccosandvers=''   intsize=4\, longsize=8\, ptrsize=8\, doublesize=8\, byteorder=12345678\, doublekind=3   d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=16\, longdblkind=3   ivtype='long'\, ivsize=8\, nvtype='long double'\, nvsize=16\, Off_t='off_t'\, lseeksize=8   alignbytes=16\, prototype=define   Linker and Libraries​:   ld='g++'\, ldflags =' -fstack-protector -L/usr/local/lib'   libpth=/usr/include/c++/4.8 /usr/include/x86_64-linux-gnu/c++/4.8 /usr/include/c++/4.8/backward /usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib   libs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc   perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc   libc=libc-2.19.so\, so=so\, useshrplib=false\, libperl=libperl.a   gnulibc_version='2.19'   Dynamic Linking​:   dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E'   cccdlflags='-fPIC'\, lddlflags='-shared -ggdb3 -ggdb3 -O0 -L/usr/local/lib -fstack-protector'


@​INC for perl 5.21.7​:   /home/khw/perl/blead/lib   /home/khw/blead/lib/perl5/site_perl/5.21.7/x86_64-linux-thread-multi-ld   /home/khw/blead/lib/perl5/site_perl/5.21.7   /home/khw/blead/lib/perl5/5.21.7/x86_64-linux-thread-multi-ld   /home/khw/blead/lib/perl5/5.21.7   /home/khw/blead/lib/perl5/site_perl/5.21.6   /home/khw/blead/lib/perl5/site_perl/5.21.5   /home/khw/blead/lib/perl5/site_perl/5.21.4   /home/khw/blead/lib/perl5/site_perl/5.21.3   /home/khw/blead/lib/perl5/site_perl/5.21.2   /home/khw/blead/lib/perl5/site_perl/5.21.1   /home/khw/blead/lib/perl5/site_perl/5.20.0   /home/khw/blead/lib/perl5/site_perl/5.19.12   /home/khw/blead/lib/perl5/site_perl/5.19.11   /home/khw/blead/lib/perl5/site_perl/5.19.10   /home/khw/blead/lib/perl5/site_perl   .


Environment for perl 5.21.7​:   HOME=/home/khw   LANG=en_US.UTF-8   LANGUAGE (unset)   LD_LIBRARY_PATH (unset)   LOGDIR (unset)

PATH=/home/khw/bin​:/home/khw/perl5/perlbrew/bin​:/home/khw/print/bin​:/bin​:/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/usr/games​:/usr/local/games​:/home/khw/iands/www​:/home/khw/cxoffice/bin   PERL5OPT=-w   PERL_BADLANG (unset)   PERL_POD_PEDANTIC=1   SHELL=/bin/ksh

p5pRT commented 9 years ago

From @cpansprout

On Fri Dec 05 12​:33​:28 2014\, public@​khwilliamson.com wrote​:

This is a bug report for perl from khw@​khw.(none)\, generated with the help of perlbug 1.40 running under perl 5.21.7.

----------------------------------------------------------------- I noticed that expressions that contain read-only variables such as $^V or $]\, etc don't seem to get constant-folded\, so for example

if($] \< 5.007) { FOO() } elsif ($] >= 5.007003) { BAR() } else { BAZ() }

should just have generated unconditional code that calls BAR()\, with everything else gone.

I was surprised to find this\, because I thought the optimizer handled such things\, and this seems like a blatant oversight.

$ perl -le 'local $]; $]=3; print $]' 3

That kind of thing can be useful for testing porpoises (and dolphins).

--

Father Chrysostomos

p5pRT commented 9 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 9 years ago

From @khwilliamson

On 12/05/2014 01​:41 PM\, Father Chrysostomos via RT wrote​:

On Fri Dec 05 12​:33​:28 2014\, public@​khwilliamson.com wrote​:

This is a bug report for perl from khw@​khw.(none)\, generated with the help of perlbug 1.40 running under perl 5.21.7.

----------------------------------------------------------------- I noticed that expressions that contain read-only variables such as $^V or $]\, etc don't seem to get constant-folded\, so for example

if($] \< 5.007) { FOO() } elsif ($] >= 5.007003) { BAR() } else { BAZ() }

should just have generated unconditional code that calls BAR()\, with everything else gone.

I was surprised to find this\, because I thought the optimizer handled such things\, and this seems like a blatant oversight.

$ perl -le 'local $]; $]=3; print $]' 3

That kind of thing can be useful for testing porpoises (and dolphins).

But if you do that\, your local $] isn't marked read-only\, so when a variable is read-only\, it could be constant-folded at compile time

p5pRT commented 9 years ago

From @cpansprout

On Fri Dec 05 12​:57​:57 2014\, public@​khwilliamson.com wrote​:

On 12/05/2014 01​:41 PM\, Father Chrysostomos via RT wrote​:

On Fri Dec 05 12​:33​:28 2014\, public@​khwilliamson.com wrote​:

This is a bug report for perl from khw@​khw.(none)\, generated with the help of perlbug 1.40 running under perl 5.21.7.

----------------------------------------------------------------- I noticed that expressions that contain read-only variables such as $^V or $]\, etc don't seem to get constant-folded\, so for example

if($] \< 5.007) { FOO() } elsif ($] >= 5.007003) { BAR() } else { BAZ() }

should just have generated unconditional code that calls BAR()\, with everything else gone.

I was surprised to find this\, because I thought the optimizer handled such things\, and this seems like a blatant oversight.

$ perl -le 'local $]; $]=3; print $]' 3

That kind of thing can be useful for testing porpoises (and dolphins).

But if you do that\, your local $] isn't marked read-only\, so when a variable is read-only\, it could be constant-folded at compile time

But code already compiled will be bound to *] glob and see the localisation change.

Iā€™m not saying we shouldnā€™t necessarily optimise here; Iā€™m just afraid of the aftermath. After all\, simpler\, more ā€˜internalā€™ changes I make seem to break more CPAN modules than I would like.

--

Father Chrysostomos

p5pRT commented 9 years ago

From @demerphq

On 5 December 2014 at 21​:41\, Father Chrysostomos via RT \< perlbug-followup@​perl.org> wrote​:

On Fri Dec 05 12​:33​:28 2014\, public@​khwilliamson.com wrote​:

This is a bug report for perl from khw@​khw.(none)\, generated with the help of perlbug 1.40 running under perl 5.21.7.

----------------------------------------------------------------- I noticed that expressions that contain read-only variables such as $^V or $]\, etc don't seem to get constant-folded\, so for example

if($] \< 5.007) { FOO() } elsif ($] >= 5.007003) { BAR() } else { BAZ() }

should just have generated unconditional code that calls BAR()\, with everything else gone.

I was surprised to find this\, because I thought the optimizer handled such things\, and this seems like a blatant oversight.

$ perl -le 'local $]; $]=3; print $]' 3

Wow. I am shocked that works.

Yves

-- perl -Mre=debug -e "/just|another|perl|hacker/"

p5pRT commented 9 years ago

From @bulk88

On Fri Dec 05 14​:10​:18 2014\, sprout wrote​:

But code already compiled will be bound to *] glob and see the localisation change.

Iā€™m not saying we shouldnā€™t necessarily optimise here; Iā€™m just afraid of the aftermath. After all\, simpler\, more ā€˜internalā€™ changes I make seem to break more CPAN modules than I would like.

What if someone bites the bullet and uploads "Perl6.pm" to CPAN that just changes $^V and $] to 6 and nothing else? :D

We would break that code then.

More realistically\, "If you expect to change $^V and $] for testing please do so in a BEGIN block\, runtime changing is not sane." Or should $] be the "current version" as determined by "use v.5.**.0;" for the compiling scope?

-- bulk88 ~ bulk88 at hotmail.com

p5pRT commented 9 years ago

From @jkeenan

On Fri Dec 05 14​:10​:18 2014\, sprout wrote​:

On Fri Dec 05 12​:57​:57 2014\, public@​khwilliamson.com wrote​:

On 12/05/2014 01​:41 PM\, Father Chrysostomos via RT wrote​:

On Fri Dec 05 12​:33​:28 2014\, public@​khwilliamson.com wrote​:

This is a bug report for perl from khw@​khw.(none)\, generated with the help of perlbug 1.40 running under perl 5.21.7.

----------------------------------------------------------------- I noticed that expressions that contain read-only variables such as $^V or $]\, etc don't seem to get constant-folded\, so for example

if($] \< 5.007) { FOO() } elsif ($] >= 5.007003) { BAR() } else { BAZ() }

should just have generated unconditional code that calls BAR()\, with everything else gone.

I was surprised to find this\, because I thought the optimizer handled such things\, and this seems like a blatant oversight.

$ perl -le 'local $]; $]=3; print $]' 3

That kind of thing can be useful for testing porpoises (and dolphins).

But if you do that\, your local $] isn't marked read-only\, so when a variable is read-only\, it could be constant-folded at compile time

But code already compiled will be bound to *] glob and see the localisation change.

Iā€™m not saying we shouldnā€™t necessarily optimise here; Iā€™m just afraid of the aftermath. After all\, simpler\, more ā€˜internalā€™ changes I make seem to break more CPAN modules than I would like.

$] is not deprecated\, but its documentation implicitly discourages its use​:

##### $] See "$^V" for a more modern representation of the Perl version that allows accurate string comparisons. #####

Perhaps this is a case where we can let sleeping dogs lie.

Thank you very much. -- James E Keenan (jkeenan@​cpan.org)

p5pRT commented 9 years ago

From @rjbs

* James E Keenan via RT \perlbug\-followup@&#8203;perl\.org [2014-12-06T09​:29​:23]

$] is not deprecated\, but its documentation implicitly discourages its use​:

##### $] See "$^V" for a more modern representation of the Perl version that allows accurate string comparisons. #####

Perhaps this is a case where we can let sleeping dogs lie.

The same questions\, related to treating the version as an immutable constant\, apply to $^V.

-- rjbs

p5pRT commented 9 years ago

From @khwilliamson

On 12/06/2014 08​:37 AM\, Ricardo Signes wrote​:

* James E Keenan via RT \perlbug\-followup@&#8203;perl\.org [2014-12-06T09​:29​:23]

$] is not deprecated\, but its documentation implicitly discourages its use​:

##### $] See "$^V" for a more modern representation of the Perl version that allows accurate string comparisons. #####

Perhaps this is a case where we can let sleeping dogs lie.

The same questions\, related to treating the version as an immutable constant\, apply to $^V.

As an aside\, we will never be able to get rid of $]\, because $^V is not available in all versions of Perl. That means that modules that have to work on very old Perls and have to distinguish between those old versions are stuck with $]. Perhaps this should be spelled out in the pods. A module for which all versions before v5.6 (when $^V became available) are treated alike should use (! defined $^V || $^V lt foo)

p5pRT commented 9 years ago

From @mauke

Am 06.12.2014 um 18​:58 schrieb Karl Williamson​:

As an aside\, we will never be able to get rid of $]\, because $^V is not available in all versions of Perl. That means that modules that have to work on very old Perls and have to distinguish between those old versions are stuck with $]. Perhaps this should be spelled out in the pods. A module for which all versions before v5.6 (when $^V became available) are treated alike should use (! defined $^V || $^V lt foo)

I just wanted to add that this isn't necessary if your module uses 'warnings' or 'our'\, because those don't work pre-5.6 anyway.

-- Lukas Mai \plokinom@&#8203;gmail\.com

p5pRT commented 9 years ago

From @khwilliamson

On 12/06/2014 01​:15 PM\, Lukas Mai wrote​:

Am 06.12.2014 um 18​:58 schrieb Karl Williamson​:

As an aside\, we will never be able to get rid of $]\, because $^V is not available in all versions of Perl. That means that modules that have to work on very old Perls and have to distinguish between those old versions are stuck with $]. Perhaps this should be spelled out in the pods. A module for which all versions before v5.6 (when $^V became available) are treated alike should use (! defined $^V || $^V lt foo)

I just wanted to add that this isn't necessary if your module uses 'warnings' or 'our'\, because those don't work pre-5.6 anyway.

If I understand you correctly\, you're saying that if you use these features\, your code won't compile on pre-v5.6 anyway.

Also\, I believe I was wrong. Correct me if I was right. According to the docs\, v-strings were introduced in v5.6\, so any module that is supposed to work in earlier versions can't use them outside of an eval or else will get a syntax error. And that means $] is effectively needed for such modules.

p5pRT commented 9 years ago

From @khwilliamson

On 12/06/2014 04​:59 PM\, Karl Williamson wrote​:

On 12/06/2014 01​:15 PM\, Lukas Mai wrote​:

Am 06.12.2014 um 18​:58 schrieb Karl Williamson​:

As an aside\, we will never be able to get rid of $]\, because $^V is not available in all versions of Perl. That means that modules that have to work on very old Perls and have to distinguish between those old versions are stuck with $]. Perhaps this should be spelled out in the pods. A module for which all versions before v5.6 (when $^V became available) are treated alike should use (! defined $^V || $^V lt foo)

I just wanted to add that this isn't necessary if your module uses 'warnings' or 'our'\, because those don't work pre-5.6 anyway.

If I understand you correctly\, you're saying that if you use these features\, your code won't compile on pre-v5.6 anyway.

Also\, I believe I was wrong. Correct me if I was right. According to the docs\, v-strings were introduced in v5.6\, so any module that is supposed to work in earlier versions can't use them outside of an eval or else will get a syntax error. And that means $] is effectively needed for such modules.

I managed to get perlbrew to install v5.5.4\, and there is no syntax error unless under 'strict'

p5pRT commented 9 years ago

From @Leont

On Sat\, Dec 6\, 2014 at 3​:29 PM\, James E Keenan via RT \< perlbug-followup@​perl.org> wrote​:

$] is not deprecated\, but its documentation implicitly discourages its use​:

##### $] See "$^V" for a more modern representation of the Perl version that allows accurate string comparisons. #####

Perhaps this is a case where we can let sleeping dogs lie.

Quite franky\, I have much better experiences with using $] than with $^V. Not in the last place because the latter completely changed its behavior in 5.10.

Leon