B::CC - Perl compiler's optimized C translation backend
perl -MO=CC[,OPTIONS] foo.pl
This compiler backend takes Perl source and generates C source code corresponding to the flow of your program with unrolled ops and optimised stack handling and lexicals variable types. In other words, this backend is somewhat a "real" compiler in the sense that many people think about compilers. Note however that, currently, it is a very poor compiler in that although it generates (mostly, or at least sometimes) correct code, it performs relatively few optimisations. This will change as the compiler and the types develops. The result is that running an executable compiled with this backend may start up more quickly than running the original Perl program (a feature shared by the C compiler backend--see B::C) and may also execute slightly faster. This is by no means a good optimising compiler--yet.
If there are any non-option arguments, they are taken to be names of objects to be saved (probably doesn't work properly yet). Without extra arguments, it saves the main program.
Output to filename instead of STDOUT
Check and abort.
Compiles and prints only warnings, but does not emit C code.
Verbose compilation (prints a few compilation stages).
Force end of options
Force apparently unused subs from package Packname to be compiled. This allows programs to use eval "foo()" even when sub foo is never seen to be used at compile time. The down side is that any subs which really are never used also have code generated. This option is necessary, for example, if you have a signal handler foo which you initialise with $SIG{BAR} = "foo"
. A better fix, though, is just to change it to $SIG{BAR} = \&foo
. You can have multiple -u options. The compiler tries to figure out which packages may possibly have subs in which need compiling but the current version doesn't do it very well. In particular, it is confused by nested packages (i.e. of the form A::B
) where package A
does not contain any subs.
Ignore all subs from Package to be compiled.
Certain packages might not be needed at run-time, even if the pessimistic walker detects it.
Instead of generating source for a runnable executable, generate source for an XSUB module. The boot_Modulename function (which DynaLoader can look for) does the appropriate initialisation and runs the main part of the Perl source that is being compiled.
Provide a different init name for additional objects added via cmdline.
With a DEBUGGING perl compile-time errors for range and flip without compile-time context are only warnings. With -strict
these warnings are fatal, otherwise only run-time errors occur.
Optimisation level (n = 0, 1, 2). -O means -O1.
The following B::C optimisations are applied automatically:
optimize_warn_sv save_data_fh av-init2|av_init save_sig destruct pv_copy_on_grow
-O1 sets -ffreetmps-each-bblock.
-O2 adds -ffreetmps-each-loop, -faelem
and -fno-destruct from B::C.
The following options must be set explicitly:
B<-fno-taint> or B<-fomit-taint>,
B<-fslow-signals>,
B<-no-autovivify>,
B<-fno-magic>.
OPTIM
Force optimisations on or off one at a time. Unknown optimizations are passed down to B::C.
Delays FREETMPS from the end of each statement to the end of the each basic block.
Enabled with -O1.
Delays FREETMPS from the end of each statement to the end of the group of basic blocks forming a loop. At most one of the freetmps-each-* options can be used.
Enabled with -O2.
Enable array element access optimizations, allowing unchecked fast access under certain circumstances.
Enabled with -O2 and not-threaded perls only.
Do not inline calls to certain small pp ops.
Most of the inlinable ops were already inlined. Turns off inlining for some new ops.
AUTOMATICALLY inlined:
pp_null pp_stub pp_unstack pp_and pp_andassign pp_or pp_orassign pp_cond_expr pp_padsv pp_const pp_nextstate pp_dbstate pp_rv2gv pp_sort pp_gv pp_gvsv pp_aelemfast pp_ncmp pp_add pp_subtract pp_multiply pp_divide pp_modulo pp_left_shift pp_right_shift pp_i_add pp_i_subtract pp_i_multiply pp_i_divide pp_i_modulo pp_eq pp_ne pp_lt pp_gt pp_le pp_ge pp_i_eq pp_i_ne pp_i_lt pp_i_gt pp_i_le pp_i_ge pp_scmp pp_slt pp_sgt pp_sle pp_sge pp_seq pp_sne pp_sassign pp_preinc pp_pushmark pp_list pp_entersub pp_formline pp_goto pp_enterwrite pp_leavesub pp_leavewrite pp_entergiven pp_leavegiven pp_entereval pp_dofile pp_require pp_entertry pp_leavetry pp_grepstart pp_mapstart pp_grepwhile pp_mapwhile pp_return pp_range pp_flip pp_flop pp_enterloop pp_enteriter pp_leaveloop pp_next pp_redo pp_last pp_subst pp_substcont
DONE with -finline-ops:
pp_enter pp_reset pp_regcreset pp_stringify
TODO with -finline-ops:
pp_anoncode pp_wantarray pp_srefgen pp_refgen pp_ref pp_trans pp_schop pp_chop pp_schomp pp_chomp pp_not pp_sprintf pp_anonlist pp_shift pp_once pp_lock pp_rcatline pp_close pp_time pp_alarm pp_av2arylen: no lvalue, pp_length: no magic
Omits generating code for handling perl's tainting mechanism.
Add PERL_ASYNC_CHECK after every op as in the old Perl runloop before 5.13.
perl "Safe signals" check the state of incoming signals after every op. See http://perldoc.perl.org/perlipc.html#Deferred-Signals-(Safe-Signals) We trade safety for more speed and delay the execution of non-IO signals (IO signals are already handled in PerlIO) from after every single Perl op to the same ops as used in 5.14.
Only with -fslow-signals we get the old slow and safe behaviour.
With the default -fname-magic
we infer the SCALAR type for specially named locals vars and most ops use C vars then, not the perl vars. Arithmetic and comparison is inlined. Scalar magic is bypassed.
With -fno-name-magic
do not infer a local variable type from its name:
B<_i> suffix for int, B<_d> for double/num, B<_ir> for register int
See the experimental -ftype-attr
type attributes. Currently supported are int and num only. See </load_pad>.
Experimentally support type attributes for int and num, SCALAR only so far. For most ops new C vars are used then, not the fat perl vars. Very awkward to use until the basic type classes are supported from within core or use types.
Enabled with -O2. See TYPES and </load_pad>.
Do not vivify array and soon also hash elements when accessing them. Beware: Vivified elements default to undef, unvivified elements are invalid.
This is the same as the pragma "no autovivification" and allows very fast array accesses, 4-6 times faster, without the overhead of autovivification.
Assume certain data being optimized is never tied or is holding other magic. This mainly holds for arrays being optimized, but in the future hashes also.
Debug options (concatenated or separate flags like perl -D
). Verbose debugging options are crucial, because the interactive debugger Od adds a lot of ballast to the resulting code.
Writes debugging output to STDERR just as it's about to write to the program's runtime (otherwise writes debugging info as comments in its C output).
Outputs each OP as it's compiled
Outputs the contents of the stack at each OP. Values are B::Stackobj objects.
Outputs the contents of the loop context stack, the @cxstack.
Outputs the contents of the shadow stack at each OP.
Outputs the contents of the shadow pad of lexicals as it's loaded for each sub or the main program.
Outputs the name of each fake PP function in the queue as it's about to process it.
Output the filename and line number of each original line of Perl code as it's processed (pp_nextstate
).
Outputs timing information of compilation stages.
Add Flags info to the code.
Creates a new ccpp optree.
Initialised by saveoptree_callback in B::C, replaces B::C::walk_and_save_optree. Called by every CV::save
if ROOT. blocksort also creates its block closure with cc_queue.
The compiler tracks state of lexical variables in @pad to generate optimised code. But multiple execution paths lead to the entry point of a basic block. The state of the first execution path is saved and all other execution paths are restored to the state of the first one.
Missing flags are regenerated by loading values.
Added flags must are removed; otherwise the compiler would be too optimistic, hence generating code which doesn't match state of the other execution paths.
Load pad takes (the elements of) a PADLIST as arguments and loads up @pad with Stackobj-derived objects which represent those lexicals.
If/when perl itself can generate type information (my int $foo; my $foo : int)
then we'll take advantage of that here. Until then, we'll use the "-fno-name-magic" in -fname-magic hack to tell the compiler when we want a lexical to be a particular type or to be a register.
We not only mark named labels in C as such - with prefix "label_".
We also have to mark each known (back jumps) and yet unknown branch targets (forward jumps) for compile-time generated branch points, with the "lab_" prefix.
perl -MO=CC,-O2,-ofoo.c foo.pl
perl cc_harness -o foo foo.c
Note that cc_harness
lives in the B
subdirectory of your perl library directory. The utility called perlcc
may also be used to help make use of this compiler.
# create a shared XS module
perl -MO=CC,-mFoo,-oFoo.c Foo.pm
perl cc_harness -shared -c -o Foo.so Foo.c
# side-effects just for the types and attributes
perl -MB::CC -e'my int $i:unsigned; ...'
Implemented type classes are int and num. Planned is str also. Implemented are only SCALAR types yet. Typed arrays and hashes and perfect hashes need coretypes, types and proper const
support first.
Deprecated are inferred types via the names of locals, with '_i', '_d' suffix and an optional 'r' suffix for register allocation.
C<my ($i_i, $j_ir, $num_d);>
Planned type attributes are int, num, str, unsigned, ro / const.
The attributes are perl attributes, and int|num|str
are either compiler classes or hints for more allowed types.
C<my int $i :num;> declares a NV with SVf_IOK. Same as C<my $i:int:double;>
C<my int $i;> declares an IV. Same as C<my $i:int;>
C<my int $i :str;> declares a PVIV. Same as C<my $i:int:string;>
C<my int @array :unsigned = (0..4);> will be used as c var in faster arithmetic and cmp.
With :const or :ro even more.
C<my str %hash :const
= (foo => 'foo', bar => 'bar');> declare string values,
generate as read-only perfect hash.
:unsigned is valid for int only and declares an UV.
:register denotes optionally a short and hot life-time.
:temporary are usually generated internally, nameless lexicals. They are more aggressivly destroyed and ignored.
:ro or :const throw a compile-time error on write access and may optimize the internal structure of the variable. We don't need to write back the variable to perl (lexical write_back).
STATUS
OK (classes only):
my int $i;
my num $d;
NOT YET OK (attributes):
my int $i :register;
my $i :int;
my $const :int:const;
my $uv :int:unsigned;
ISSUES
This does not work with pure perl, unless you use B::CC
or use types
or implement the classes and attribute type stubs in your code, sub Mypkg::MODIFY_SCALAR_ATTRIBUTES {}
and sub Mypkg::FETCH_SCALAR_ATTRIBUTES {}
. (TODO: empty should be enough to be detected by the compiler.)
Compiled code pulls in the magic MODIFY_SCALAR_ATTRIBUTES and FETCH_SCALAR_ATTRIBUTES functions, even if they are used at compile time only.
Using attributes adds an import block to your code.
Up until 5.20 only our variable attributes are checked at compile-time, my variables attributes at run-time only, which is too late for the compiler. Perl attributes need to be fixed for types hints by adding CHECK_SCALAR_ATTRIBUTES
.
FUTURE
We should be able to support types on ARRAY and HASH. For arrays also sizes to omit bounds-checking.
my int @array; # array of ints, faster magic-less access esp. in inlined arithmetic and cmp.
my str @array : const = qw(foo bar); # compile-time error on write. no lexical write_back
my int $hash = {"1" => 1, "2" => 2}; # int values, type-checked on write my
str %hash1 : const = (foo => 'bar'); # string keys only => maybe gperf
# compile-time error on write
Typed hash keys are always strings, as array keys are always int. Only the values are typed.
We should be also able to add type attributes for functions and methods, i.e. for argument and return types. See types and http://blogs.perl.org/users/rurban/2011/02/use-types.html
Plenty. Current status: experimental.
These aren't really bugs but they are constructs which are heavily tied to perl's compile-and-go implementation and with which this compiler backend cannot cope.
Standard perl calculates the target of "next", "last", and "redo" at run-time. The compiler calculates the targets at compile-time. For example, the program
sub skip_on_odd { next NUMBER if $_[0] % 2 }
NUMBER: for ($i = 0; $i < 5; $i++) {
skip_on_odd($i);
print $i;
}
produces the output
024
with standard perl but calculates with the compiler the goto label_NUMBER wrong, producing 01234.
The context (scalar or array) of the ".." operator determines whether it behaves as a range or a flip/flop. Standard perl delays until runtime the decision of which context it is in but the compiler needs to know the context at compile-time. For example,
@a = (4,6,1,0,0,1);
sub range { (shift @a)..(shift @a) }
print range();
while (@a) { print scalar(range()) }
generates the output
456123E0
with standard Perl but gives a run-time warning with compiled Perl.
If the option -strict is used it gives a compile-time error.
Compiled Perl programs use native C arithmetic much more frequently than standard perl. Operations on large numbers or on boundary cases may produce different behaviour. In doubt B::CC code behaves more like with use integer
.
Features of standard perl such as $[
which have been deprecated in standard perl since Perl5 was released have not been implemented in the optimizing compiler.
Malcolm Beattie MICB at cpan.org
(1996-1998, retired), Vishal Bhatia <vishal at deja.com> I(1999), Gurusamy Sarathy <gsar at cpan.org> I(1998-2001), Reini Urban perl-compiler at googlegroups.com
I(2008-now), Heinz Knutzen heinz.knutzen at gmx.de
I(2010) Will Braswell wbraswell at hush.com
I(2012)