B-C

 view release on metacpan or  search on metacpan

ByteLoader/ppport.h  view on Meta::CPAN

lex_stuff_pvn||5.011002|
lex_stuff_pvs||5.013005|
lex_stuff_pv||5.013006|
lex_stuff_sv||5.011002|
lex_unstuff||5.011002|
listkids|||
list|||
load_module_nocontext|||vn
load_module|5.006000||pv
localize|||
looks_like_bool|||
looks_like_number|||
lop|||
mPUSHi|5.009002||p
mPUSHn|5.009002||p
mPUSHp|5.009002||p
mPUSHs|5.010001||p
mPUSHu|5.009002||p
mXPUSHi|5.009002||p
mXPUSHn|5.009002||p
mXPUSHp|5.009002||p
mXPUSHs|5.010001||p

Changes  view on Meta::CPAN

	Save now empty bodyless subs if they exist, for signal handlers,
	  prototypes declarations and cvrefs (#251, #159, #235, #246, #270, #271, #275, #279)
	Fix PVMG PV overwriting the RV, overload sub (#273)
	* CC (1.14): Skip saving non-existing methods analog to B::C 1.43_06 (CC test 50)
	* perlcc (2.17): Accept -A for -DALLOW_PERL_OPTIONS
	* t/testc.sh: Accept -A for -DALLOW_PERL_OPTIONS

1.43	2014-01-15 rurban
	new 5.16, and partial 5.18, 5.20 and windows support.
	Many more fixes and testcases.
	Bytecode is still broken on 5.18, esp non-threaded. 5.20 looks pretty good though.

	* C: Fix -u<module> without file extension.
	With hek do not drop FAKE, only for const pv.
	Fixed $$ ($PID) to be dynamic, issue 108. Thanks to flexvault for reporting this.
	Fixed double precision to 16 digits. The nbody shootout test passes now.
	Fixed refcounts of *ENV, issue 111.
	Fixed wrong boot_ arg for the xs version check with --staticxs
	Better fix for overwriting of @ARGV <O3, test c_argv:1 and c_allow_opts.t:1
	Fixed refinition warnings of XS CONSTSUB. Ignore them as they are
	  loaded later.

README  view on Meta::CPAN

(2) To compile foo.pl with the CC backend (which generates
actual optimised C code for the execution path of your perl
program), use

    perl -MO=CC,-ofoo.c foo.pl

and proceed just as with the C backend. You should almost
certainly use an option such as -O2 with the subsequent
cc_harness invocation so that your C compiler uses
optimisation. The C code generated by the Perl compiler's CC
backend looks ugly to humans but is easily optimised by C
compilers.

To make the most of this optimizing compiler backend, you need to tell
the compiler when you're using int or double variables so that it can
optimise appropriately. The old deprecated way do that was by naming
lexical variables ending in "_i" for ints, "_d" for doubles, "_ir" for
int "register" variables or "_dr" for double "register"
variables. Here "register" is a promise that you won't pass a
reference to the variable into a sub which then modifies the variable.
The new way is to declare those lexicals with "my int" and "my

README.alpha  view on Meta::CPAN

number of known problems. See the XSUB section lower down for information
about compiling programs which use XSUBs.

(2) To compile foo.pl with the CC backend (which generates actual
optimised C code for the execution path of your perl program), use
    perl -MO=CC,-ofoo.c foo.pl

and proceed just as with the C backend. You should almost certainly
use an option such as -O2 with the subsequent cc_harness invocation
so that your C compiler uses optimisation. The C code generated by
the Perl compiler's CC backend looks ugly to humans but is easily
optimised by C compilers.

To make the most of this compiler backend, you need to tell the
compiler when you're using int or double variables so that it can
optimise appropriately (although this part of the compiler is the most
buggy). You currently do that by naming lexical variables ending in
"_i" for ints, "_d" for doubles, "_ir" for int "register" variables or
"_dr" for double "register" variables. Here "register" is a promise
that you won't pass a reference to the variable into a sub which then
modifies the variable. The compiler ought to catch attempts to use

lib/B/C.pm  view on Meta::CPAN

    }
    elsif (!$include_package{$package}) {
      delete_unsaved_hashINC($package) if can_delete($package);
      warn "Cached $package is already deleted\n" if $debug{pkg};
    } else {
      warn "Cached $package is cached\n" if $debug{pkg};
    }
    return $include_package{$package};
  }

  # Now see if current package looks like an OO class. This is probably too strong.
  if (!$all_bc_deps{$package}) {
    foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE)) {
      # 5.10 introduced version and Regexp::DESTROY, which we dont want automatically.
      # XXX TODO This logic here is wrong and unstable. Fixes lead to more failures.
      # The walker deserves a rewrite.
      if ( UNIVERSAL::can( $package, $m ) and $package !~ /^(B::C|version|Regexp|utf8|SelectSaver)$/ ) {
        next if $package eq 'utf8' and $m eq 'DESTROY'; # utf8::DESTROY is empty
        # we load Errno by ourself to avoid double Config warnings [perl #]
        # and we have special logic to detect and include it
        next if $package =~ /^(Errno|Tie::Hash::NamedCapture)$/ and $m eq 'TIEHASH';

lib/B/CC.pm  view on Meta::CPAN

  # constant could be in the pad (under useithreads)
  if ($$sv) {
    $obj = $constobj{$$sv};
    if ( !defined($obj) ) {
      $obj = $constobj{$$sv} = B::Stackobj::Const->new($sv);
    }
  }
  else {
    $obj = $pad[ $op->targ ];
  }
  # XXX looks like method_named has only const as prev op
  if ($op->next
      and $op->next->can('name')
      and $op->next->name eq 'method_named'
     ) {
    $package_pv = svop_or_padop_pv($op);
    debug "save package_pv \"$package_pv\" for method_name\n" if $debug{op};
  }
  push( @stack, $obj );
  return $op->next;
}

lib/B/Disassembler.pm  view on Meta::CPAN

  print_insn print_insn_bare

=head1 print_insn

Callback function for disassemble_fh, which gets three arguments from
the disassembler.  insn (a string), arg (a string or number or undef)
and the comment (an optional string).

This supports the new behaviour in F<scripts/disassemble>.  It prints
each insn and optional argument with some additional comments, which
looks similar to B::Assembler with option -S (commented source).

=head1 print_insn_bare

This is the same as the old behaviour of scripts/disassemble.  It
prints each insn and optional argument without any comments. Line per
line.

=head1 get_header

Returns the .plc header as array of

lib/B/Stackobj.pm  view on Meta::CPAN

}

#
# Caller needs to ensure that set_int, set_double,
# set_numeric and set_sv are only invoked on legal lvalues.
#
sub set_int {
  my ( $obj, $expr, $unsigned ) = @_;
  my $sval;
  # bullshit detector for non numeric expr, expr 'lnv0 + rnv0'
  if ($expr =~ /[ a-dfzA-DF-Z]/) { # looks not like number
    $sval = $expr;
  } else {
    $sval = B::C::ivx($expr);
    $sval = $expr if $sval eq '0' and $expr;
  }

  runtime("$obj->{iv} = $sval;");
  $obj->{flags} &= ~( VALID_SV | VALID_NUM );
  $obj->{flags} |= VALID_INT | SAVE_INT;
  $obj->{flags} |= VALID_UNSIGNED if $unsigned;
}

sub set_double {
  my ( $obj, $expr ) = @_;
  my $sval;
  if ($expr =~ /^-?(Inf|NaN)$/i) {
    $sval = B::C::nvx($expr);
    $sval = $expr if $sval eq '0' and $expr;
  # bullshit detector for non numeric expr, expr 'lnv0 + rnv0'
  } elsif ($expr =~ /[ a-dfzA-DF-Z]/) { # looks not like number
    $sval = $expr;
  } else {
    $sval = B::C::nvx($expr);
    $sval = $expr if $sval eq '0' and $expr;
  }

  runtime("$obj->{nv} = $sval;");
  $obj->{flags} &= ~( VALID_SV | VALID_INT );
  $obj->{flags} |= VALID_NUM | SAVE_NUM;
}

perloptree.pod  view on Meta::CPAN

op-next pointers to give the execution order for that op
tree. op-sibling pointers are rarely unneeded after that.

Walkers can run in "basic" or "exec" order.  "basic" is useful
for the memory layout, it contains the history, "exec" is more
useful to understand the logic and program flow.  The
L</B::Bytecode> section has an extensive example about the order.

=head1 OP Structure and Inheritance

The basic C<struct op> looks basically like 

  C<{ OP* op_next, OP* op_sibling, OP* op_ppaddr, ..., int op_flags, int op_private } OP;> 

See L</BASEOP> below.

Each op is defined in size, arguments, return values, class and
more in the F<opcode.pl> table. (See L</"OP Class Declarations in
opcode.pl"> below.)

The class of an OP determines its size and the number of

ramblings/blogs-optimizing-2.md  view on Meta::CPAN

    # This does not, in fact, consume N*4 bytes of memory
    for (1..$n){
      advance(0.01);
    }

    printf ("%.9f\n", energy());


A lot of arithmetic, only three functions, advance is called 50,000 times, the others only once.

The generated C code for some inlined arithmetic looks like:

`$ grep -A50 pp_sub_energy nbody.perl.c`


    static
    CCPP(pp_sub_energy)
    {
        double rnv0, lnv0, d1_e, d2_i, d3_dx, d4_dy, d5_dz, d6_distance, d11_tmp, d13_tmp,
               d15_tmp, d16_tmp, d18_tmp, d19_tmp, d20_tmp, d22_tmp, d31_tmp, d32_tmp, d33_tmp,
               d34_tmp, d35_tmp, d37_tmp, d38_tmp;

ramblings/blogs-optimizing-3.md  view on Meta::CPAN


With N=50,000,000 we got **14m12.653s** uncompiled and **7m11.3597s**
compiled. Close to jruby, even if the array accesses still goes
through the `av_fetch` function, magic is checked and undefined indices
are autovivified.


Generalization
--------------

The above macro-code code looks pretty unreadable, similar to lisp
macros, with its mix of quoted and unquoted variables.  The compiler
needs to detect unrollable loop code which will lead to more
constants and AELEMFAST ops. And we better define a helper function
for easier generation of such unrolled loops.

    # unquote local vars
    sub qv {
      my ($s, $env) = @_;
      # expand our local loop vars
      $s =~ s/(\$\w+?)\b/exists($env->{$1})?$env->{$1}:$1/sge;

ramblings/blogs-optimizing-3.md  view on Meta::CPAN

          $dz = $zs[$i] - $zs[$j];
          $distance = sqrt($dx * $dx + $dy * $dy + $dz * $dz);
          $e -= ($mass[$i] * $mass[$j]) / $distance;', $env);
        }
      }
      $energy .= '
      return $e;
    }';
    eval $energy; die if $@;

This looks now much better and leads in a BEGIN block to only neglectible
run-time penalty.
Full code here: [nbody.perl-2a.perl](https://github.com/rurban/shootout/commit/c35bb85ed84941157eb01b7ca844d3b4472e0df3)

I also tried a generic `unroll_loop()` function, but it was a bit too
unstable finding the end of the loop blocks on the source level, and
`qv()` looked good enough. The compiler can use the optree to find the
optimization.


Types and autovivification

ramblings/blogs-optimizing-4.md  view on Meta::CPAN

We can easily test this out by NOP'ing these code sections and see the costs.

With **4m53.073s**, without **4m23.265s**. 30 seconds or ~10% faster. This is now in the typical
range of p5p micro-optimizations and not considered high-priority for now.

Let's rather check out more stack optimizations.

I added a new [B::Stackobj::Aelem](https://github.com/rurban/perl-compiler/commit/edda0c5ca8cd8fd072e425977dd3a1f80d34857c) object to B::Stackobj to track aelemfast accesses
to array indices, and do the PUSH/POP optimizations on them.

The generated code now looks like:

      lab_116f270:
    	TAINT_NOT;
    	sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;
    	FREETMPS;
    	rnv0 = d9_mag; lnv0 = SvNV(AvARRAY((AV*)PL_curpad[25])[1]);	/* multiply */
    	d3_mm2 = lnv0 * rnv0;
      lab_116be90:
    	TAINT_NOT;
    	sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;

ramblings/flip-flop  view on Meta::CPAN

    else
	return NORMAL;
}

pp_range is a LOGOP.
In list context, it just returns op_next.
In scalar context it checks the truth of targ and returns
op_other if true, op_next if false.

flip is an UNOP.
It "looks after" its child which is always a pp_range LOGOP.
In list context, it just returns the child's op_other.
In scalar context, there are three possible outcomes:
  (1) set child's targ to 1, our targ to 1 and return op_next.
  (2) set child's targ to 1, our targ to 0, sp-- and return child's op_other.
  (3) Blank targ and  TOPs and return op_next.
Case 1 happens for a "..." with a matching lineno... or true TOPs.
Case 2 happens for a ".." with a matching lineno... or true TOPs.
Case 3 happens for a non-matching lineno or false TOPs.

               $a = lhs..rhs;

ramblings/yapc_bratislava08.pod  view on Meta::CPAN

     newBINOP(OP_MULTIPLY, flags, 
         newSVREF($b), 
         newSVREF($c)
     )
  )

Two BINOP's for ADD and MULTIPLY take two args (BINOP), and of
those two args are the op for a SVREF (pointer to the SV for $a,
$b and $c) and the OP_MULTIPLY.

This parse-tree is recursive and looks like nested LISP code.

The internal compiler (not B::C) runs in three passes over the
perl code. The various passes contain also a "peephole"
optimizer, which optimizes this recursive op tree and in the end
it is ensured that we can linearly run through the tree by simply
stepping through the C<op_next> pointers and with lists through
the C<op_sibling> pointers.

The Walker:

ramblings/yapc_bratislava08.pod  view on Meta::CPAN

native code (JIT), perl6 or PIR, but maybe also to java, LISP,
scheme, and compile this then to fast native and optimized code.

Other possible advanced ways are:

1. B<PPI>, the perl source level parser together with a source
filter, which could be used for source level macro trickery.

2. B<MAD>, compiles the optree externally to XML or YAML, and
offline tools can convert these XML to other formats, such as
perl6 code.  Advantage: This looks awful, but is easily debuggable.

3. undump() and unexec

Some cool B modules are L<B::Concise>, L<B::Deparse>, L<B::Lint>,
L<B::Generate>.  

And as advanced modules L<Devel::TypeCheck>, L<optimize>, 
L<optimizer>, L<types>.
These are the building blocks for a statically optimized 
compiler (as B::CC), in contrast to the current slow, 

script/buildcc.PL  view on Meta::CPAN

#! perl

use Config;
use File::Basename qw(&basename &dirname);
use File::Spec;
use Cwd;

# List explicitly here the variables you want Configure to
# generate.  Metaconfig only looks for shell variables, so you
# have to mention them as if they were shell variables, not
# %Config entries.  Thus you write
#  $startperl
# to ensure Configure will look for $Config{startperl}.
# Wanted:  $archlibexp

# This forces PL files to create target in same directory as PL file.
# This is so that make depend always knows where to find PL derivatives.
$origdir = cwd;
chdir dirname($0);

script/perlcc.PL  view on Meta::CPAN

#! perl

use Config;
use File::Basename qw(&basename &dirname);
use File::Spec;
use Cwd;

# List explicitly here the variables you want Configure to
# generate.  Metaconfig only looks for shell variables, so you
# have to mention them as if they were shell variables, not
# %Config entries.  Thus you write
#  $startperl
# to ensure Configure will look for $Config{startperl}.
# Wanted:  $archlibexp

# This forces PL files to create target in same directory as PL file.
# This is so that make depend always knows where to find PL derivatives.
my $origdir = cwd;
my $dir = dirname($0);

t/asmdata.t  view on Meta::CPAN

  } else {
    ok(1,  "   empty PUT for $opname" );
    ok(1,  "   skip valid PUT name check" );
  }
  ok( !ref $data->[2], "   GET method for $opname"  );
  my $getname = $data->[2];
  my $ok;
  if ($getname =~ /^GET_(.*)$/) {
    $ok = $valid_type{$1};
  }
  ok( $ok,             "   GET method $getname looks good"  );
  is( $insn_name[$data->[0]], $opname,    '@insn_name maps correctly' );

}

# I'm going to assume that op types will all be named /OP$/.
# Just 5.22 added a UNOP_AUX
if ($] >= 5.021007) {
  is( grep(/OP$/, @optype), scalar(@optype) - 1,  '@optype is almost all /OP$/' );
} else {
  is( grep(/OP$/, @optype), @optype,  '@optype is all /OP$/' );



( run in 1.011 second using v1.01-cache-2.11-cpan-64827b87656 )