perl5
perl5 copied to clipboard
defined operator not constant folded
From @bulk88
The defined operator on a constant should be folded, it isn't. The 9 is folded, but it stops at the defined operator.
use strict;
use B::Concise;
use constant (PARENT_STATION => 9);
my %stop_id_translate;
sub import_stop_times {
my $record = shift;
return defined(PARENT_STATION) && exists
$stop_id_translate{$record->[3]}
? $stop_id_translate{$record->[3]}
: $record->[3];
}
my $walker = B::Concise::compile('-exec','import_stop_times',
\&import_stop_times); # 1
$walker->();
main::import_stop_times:
1 <;> nextstate(main 175 t.pl:7) v:*,&,x*,x&,x$,$
2 <0> shift s*
3 <0> padsv[$record:175,176] sRM*/LVINTRO
4 <2> sassign vKS/2
5 <;> nextstate(main 176 t.pl:9) v:*,&,x*,x&,x$,$
6 <$> const[IV 9] s*/FOLD
7 <1> defined sK/1
8 <|> and(other->9) sK/1
9 <0> padhv[%stop_id_translate:FAKE:] sR
a <+> multideref($record->[3]) sK/STRICT
b <1> exists sK/1
c <|> cond_expr(other->d) K/1
d <0> padhv[%stop_id_translate:FAKE:] sR
e <+> multideref($record->[3]) sK/STRICT
f <2> helem sK/2
goto g
h <+> multideref($record->[3]) sK/STRICT
g <1> leavesub[1 ref] K/REFC,1
If I do a different expression
use strict;
use B::Concise;
use constant (PARENT_STATION => 9);
my %stop_id_translate;
sub import_stop_times {
my $record = shift;
return PARENT_STATION == 0 && exists $stop_id_translate{$record->[3]}
? $stop_id_translate{$record->[3]}
: $record->[3];
}
my $walker = B::Concise::compile('-exec','import_stop_times',
\&import_stop_times); # 1
$walker->();
main::import_stop_times:
1 <;> nextstate(main 175 t.pl:7) v:*,&,x*,x&,x$,$
2 <0> shift s*
3 <0> padsv[$record:175,176] sRM*/LVINTRO
4 <2> sassign vKS/2
5 <;> nextstate(main 176 t.pl:9) v:*,&,x*,x&,x$,$
6 <+> multideref($record->[3]) sK/STRICT
7 <1> leavesub[1 ref] K/REFC,1
The correct branch is correctly removed. Another example
use strict;
use B::Concise;
use constant (PARENT_STATION => 9);
my %stop_id_translate;
sub import_stop_times {
my $record = shift;
return PARENT_STATION == 9 && exists $stop_id_translate{$record->[3]}
? $stop_id_translate{$record->[3]}
: $record->[3];
}
my $walker = B::Concise::compile('-exec','import_stop_times',
\&import_stop_times); # 1
$walker->();
main::import_stop_times:
1 <;> nextstate(main 175 t.pl:7) v:*,&,x*,x&,x$,$
2 <0> shift s*
3 <0> padsv[$record:175,176] sRM*/LVINTRO
4 <2> sassign vKS/2
5 <;> nextstate(main 176 t.pl:9) v:*,&,x*,x&,x$,$
6 <0> padhv[%stop_id_translate:FAKE:] sR
7 <+> multideref($record->[3]) sK/STRICT
8 <1> exists sK/1,FOLD
9 <|> cond_expr(other->a) K/1
a <0> padhv[%stop_id_translate:FAKE:] sR
b <+> multideref($record->[3]) sK/STRICT
c <2> helem sK/2
goto d
e <+> multideref($record->[3]) sK/STRICT
d <1> leavesub[1 ref] K/REFC,1
Perl Info
Flags:
category=core
severity=low
Site configuration information for perl 5.22.1:
Configured by strawberry-perl at Mon Dec 14 09:30:58 2015.
Summary of my perl5 (revision 5 version 22 subversion 1) configuration:
Platform:
osname=MSWin32, osvers=6.3, archname=MSWin32-x86-multi-thread-64int
uname='Win32 strawberry-perl 5.22.1.1 #1 Mon Dec 14 09:28:33 2015 i386'
config_args='undef'
hint=recommended, useposix=true, d_sigaction=undef
useithreads=define, usemultiplicity=define
use64bitint=define, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='gcc', ccflags =' -s -O2 -DWIN32 -DPERL_TEXTMODE_SCRIPTS
-DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -fwrapv -fno-strict-aliasing
-mms-bitfields',
optimize='-s -O2',
cppflags='-DWIN32'
ccversion='', gccversion='4.9.2', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678,
doublekind=3
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12,
longdblkind=3
ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='long
long', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='g++', ldflags ='-s -L"C:\sperl\perl\lib\CORE" -L"C:\sperl\c\lib"'
libpth=C:\sperl\c\lib C:\sperl\c\i686-w64-mingw32\lib
C:\sperl\c\lib\gcc\i686-w64-mingw32\4.9.2
libs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr
-lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
perllibs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool
-lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid
-lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
libc=, so=dll, useshrplib=true, libperl=libperl522.a
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_win32.xs, dlext=xs.dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-mdll -s -L"C:\sperl\perl\lib\CORE"
-L"C:\sperl\c\lib"'
@INC for perl 5.22.1:
C:/sperl/perl/site/lib/MSWin32-x86-multi-thread-64int
C:/sperl/perl/site/lib
C:/sperl/perl/vendor/lib
C:/sperl/perl/lib
.
Environment for perl 5.22.1:
HOME (unset)
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=C:\sperl\c\bin;C:\sperl\perl\site\bin;C:\sperl\perl\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32\wbem;
PERL_BADLANG (unset)
PERL_JSON_BACKEND=Cpanel::JSON::XS
PERL_YAML_BACKEND=YAML
SHELL (unset)
The defined operator isn't marked as foldable in regen/opcodes. Not sure why - because it would break something, or trying to avoid spending compile time on something that probably isn't going to be foldable very often?
After a quick test run, setting defined to be foldable does cause failures, but I haven't looked into them yet.
porting/checkcfgvar.t (Wstat: 0 Tests: 14 Failed: 7)
Failed tests: 2, 4, 6, 8, 10, 12, 14
porting/exec-bit.t (Wstat: 0 Tests: 141 Failed: 1)
Failed test: 141
setting defined to be foldable does cause failures
Ran on the wrong branch. There are actually no test failures and folding does work.
./perl -MO=Concise -Ilib -e 'use constant ONE => "bibble"; if (defined(ONE)) { print "boop" }'
6 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter v ->2
2 <;> nextstate(main 186 -e:1) v:{ ->3
- <@> scope vK/FOLD ->6
- <;> ex-nextstate(main 188 -e:1) v ->3
5 <@> print vK ->6
3 <0> pushmark s ->4
4 <$> const[PV "boop"] s ->5
-e syntax OK
And on the original example:
main::import_stop_times:
1 <;> nextstate(main 178 88test.pl:7) v:*,&,x*,x&,x$,$
2 <0> shift s*
3 <1> padsv_store[$record:178,179] vKS/LVINTRO
4 <;> nextstate(main 179 88test.pl:10) v:*,&,x*,x&,x$,$
5 <0> padhv[%stop_id_translate:FAKE:] sR
6 <+> multideref($record->[3]) sK/STRICT
7 <1> exists sK/1,FOLD
8 <|> cond_expr(other->9) K/1
9 <0> padhv[%stop_id_translate:FAKE:] sR
a <+> multideref($record->[3]) sK/STRICT
b <2> helem sK/2
goto c
d <+> multideref($record->[3]) sK/STRICT
c <1> leavesub[1 ref] K/REFC,1