Skip to content

defined operator not constant folded #16266

@p5pRT

Description

@p5pRT

Migrated from rt.perl.org#132480 (status was 'new')

Searchable as RT132480$

Activity

p5pRT

p5pRT commented on Nov 21, 2017

@p5pRT
Author

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)

self-assigned this
on Jun 1, 2025
richardleach

richardleach commented on Jun 1, 2025

@richardleach
Contributor

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?

richardleach

richardleach commented on Jun 1, 2025

@richardleach
Contributor

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
richardleach

richardleach commented on Jun 1, 2025

@richardleach
Contributor

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @toddr@xenu@richardleach@p5pRT

    Issue actions

      defined operator not constant folded · Issue #16266 · Perl/perl5