summaryrefslogtreecommitdiff
path: root/opcode.h
Commit message (Collapse)AuthorAgeFilesLines
* Enable OPpTARGET_MY optimisation for cmp/<=>Father Chrysostomos2014-12-291-8/+8
| | | | | | | | | We can only do it for <=> under ‘use integer’. The non-integer <=> will push undef on to the stack. Enabling the optimisation for it would cause \($lexical = $x <=> "nan") to leave $lexical with its previous value and return a reference to &PL_sv_undef.
* [perl #123514] Make prototype() imply $_Father Chrysostomos2014-12-281-2/+2
| | | | | | | Previously it would read and replace the previous item on the stack: $ ./perl -le 'print "CORE::undef", prototype' ;\[$@%&*]
* op.c: Skip allocating entersub targ for Perl subFather Chrysostomos2014-12-211-1/+1
| | | | | | The target of entersub ops is only used by XSUBs to return things. Pure-Perl subs don’t use the target. (And if a pure-Perl sub is later replaced with an XS one, dXSTARG already has a workaround.)
* gelem and refassign can have OA_RETSCALARFather Chrysostomos2014-12-071-2/+2
| | | | | | | They only ever return scalars, but were not flagged that way. This change allows \*foo{THING} and \(\$x=\$y) to use srefgen, a faster version of refgen that handles only one item.
* Give require the OA_RETSCALAR flagFather Chrysostomos2014-12-071-1/+1
| | | | This way there is no need to call scalar() on the op separately.
* Add OP_MULTIDEREFDavid Mitchell2014-12-071-125/+137
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This op is an optimisation for any series of one or more array or hash lookups and dereferences, where the key/index is a simple constant or package/lexical variable. If the first-level lookup is of a simple array/hash variable or scalar ref, then that is included in the op too. So all of the following are replaced with a single op: $h{foo} $a[$i] $a[5][$k][$i] $r->{$k} local $a[0][$i] exists $a[$i]{$k} delete $h{foo} while these aren't: $a[0] already handled by OP_AELEMFAST $a[$x+1] not a simple index and these are partially replaced: (expr)->[0]{$k} the bit following (expr) is replaced $h{foo}[$x+1][0] the first and third lookups are each done with a multideref op, while the $x+1 expression and middle lookup are done by existing add, aelem etc ops. Up until now, aggregate dereferencing has been very heavyweight in ops; for example, $r->[0]{$x} is compiled as: gv[*r] s rv2sv sKM/DREFAV,1 rv2av[t2] sKR/1 const[IV 0] s aelem sKM/DREFHV,2 rv2hv sKR/1 gvsv[*x] s helem vK/2 When executing this, in addition to the actual calls to av_fetch() and hv_fetch(), there is a lot of overhead of pushing SVs on and off the stack, and calling lots of little pp() functions from the runops loop (each with its potential indirect branch miss). The multideref op avoids that by running all the code in a loop in a switch statement. It makes use of the new UNOP_AUX type to hold an array of typedef union { PADOFFSET pad_offset; SV *sv; IV iv; UV uv; } UNOP_AUX_item; In something like $a[7][$i]{foo}, the GVs or pad offsets for @a and $i are stored as items in the array, along with a pointer to a const SV holding 'foo', and the UV 7 is stored directly. Along with this, some UVs are used to store a sequence of actions (several actions are squeezed into a single UV). Then the main body of pp_multideref is a big while loop round a switch, which reads actions and values from the AUX array. The two big branches in the switch are ones that are affectively unrolled (/DREFAV, rv2av, aelem) and (/DREFHV, rv2hv, helem) triplets. The other branches are various entry points that handle retrieving the different types of initial value; for example 'my %h; $h{foo}' needs to get %h from the pad, while '(expr)->{foo}' needs to pop expr off the stack. Note that there is a slight complication with /DEREF; in the example above of $r->[0]{$x}, the aelem op is actually aelem sKM/DREFHV,2 which means that the aelem, after having retrieved a (possibly undef) value from the array, is responsible for autovivifying it into a hash, ready for the next op. Similarly, the rv2sv that retrieves $r from the typeglob is responsible for autovivifying it into an AV. This action of doing the next op's work for it complicates matters somewhat. Within pp_multideref, the autovivification action is instead included as the first step of the current action. In terms of benchmarking with Porting/bench.pl, a simple lexical $a[$i][$j] shows a reduction of approx 40% in numbers of instructions executed, while $r->[0][0][0] uses 54% fewer. The speed-up for hash accesses is relatively more modest, since the actual hash lookup (i.e. hv_fetch()) is more expensive than an array lookup. A lexical $h{foo} uses 10% fewer, while $r->{foo}{bar}{baz} uses 34% fewer instructions. Overall, bench.pl --tests='/expr::(array|hash)/' ... gives: PRE POST ------ ------ Ir 100.00 145.00 Dr 100.00 165.30 Dw 100.00 175.74 COND 100.00 132.02 IND 100.00 171.11 COND_m 100.00 127.65 IND_m 100.00 203.90 with cache misses unchanged at 100%. In general, the more lookups done, the bigger the proportionate saving.
* Speed up method calls like $o->Other::method() and $o->Other::SUPER::method().syber2014-12-021-1/+15
| | | | | | | | | | | | | | | It was done by adding new OP_METHOD_REDIR and OP_METHOD_REDIR_SUPER optypes. Class name to redirect is saved into METHOP as a shared hash string. Method name is changed (class name removed) an saved into op_meth_sv as a shared string hash. So there is no need now to scan for '::' and calculate class and method names at runtime (in gv_fetchmethod_*) and searching cache HV without precomputed hash. B::* modules are changed to support new op types. method_redir is now printed by Concise like (for threaded perl) $obj->AAA::meth 5 <.> method_redir[PACKAGE "AAA", PV "meth"] ->6
* speedup for SUPER::method() calls.syber2014-11-281-1/+8
| | | | | | | | | | | | | | | In ck_method: Scan for '/::. If found SUPER::, create OP_METHOD_SUPER op with precomputed hash value for method name. In B::*, added support for method_super In pp_hot.c, pp_method_*: S_method_common removed, code related to getting stash is moved to S_opmethod_stash, other code is moved to pp_method_* functions. As a result, SUPER::func() calls speeded up by 50%.
* rename [] from "anonymous list" to "anonymous array"Lukas Mai2014-11-111-1/+1
|
* Don’t allow OPpTARGET_MY with integer negationFather Chrysostomos2014-11-101-5/+5
| | | | | | | | | $ ./perl -Ilib -le 'use integer; my $a = "fake"; $a = -$a; print "[$a]"' [--] As of 1c2b3fd6f1, negation under ‘use integer’ can do string negation, which modifies the return value before reading the argument. So, like regular non-integer negation, it must forego this optimisation.
* Don’t allow OPpTARGET_MY on postdec/incFather Chrysostomos2014-11-091-14/+14
| | | | | | | | | | | | | | | | I was wrong in 9e319cc4f. postfix ++/-- writes to its return value before reading its argument. If we optimise away the scalar assignment in $a = $b++; (that’s what OPpTARGET_MY does), then $a gets written to before $b is read. If $a and $b are the same, we get the wrong answer. This bug has been present under ‘use integer’ since 5.6.0. I accidentally extended it to non-integer ++/-- in 9e319cc4f. (It’s not likely that someone will write $a = $b++, but it could hap- pen inadvertently in more complex code.)
* Shrink PL_op_private_bitdefsFather Chrysostomos2014-11-081-673/+393
| | | | | | | | | | | It doesn’t matter whether things in this table are ordered by opcode, because the indices into it are stored in PL_op_private_bitdef_ix. If we have multiple ops with exactly the same private flags, we don’t need multiple entries in PL_op_private_bitdefs. One practical advantage is that patches are less likely to conflict, which will make rebasing easier. (I hope.)
* values and each are OA_DANGEROUSFather Chrysostomos2014-11-081-6/+6
| | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. values and each can both return scalars that are referenced elsewhere, causing list assignment to behave erratically if temporary copies are not made.
* kill is not OA_DANGEROUSFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. kill only ever returns a target unused elsewhere, so it does not necessitate temp copies in list assignment.
* exec is not OA_DANGEROUSFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. When exec fails, it only ever returns a target unused elsewhere, so it does not necessitate temp copies in list assignment.
* enterwrite is not OA_DANGEROUSFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. ‘write’ only ever returns a read-only true or false, so temp copies are not necessary for its sake.
* tied is OA_DANGEROUSFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. tied returns the same scalar that the tied variables uses to hold a reference to the object (so weaken(tied(...)) works). tie uses the very scalar that TIESCALAR (or TIEWHATEVER) returns and attaches it to the tied variable by magic. That returned scalar could be referenced elsewhere. That means ($a, $b) = ($c, tied $d) could have common vars on either side, if the tie constructor for $d happened to return $a or $b. (Normally it would have to be an XSUB or an lvalue sub for its return value not to have been copied.)
* Remove OA_DANGEROUS from exitFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. exit usually doesn’t return. When it fails, it returns a read-only undef, so we don’t need temp copies for its sake.
* Remove OA_DANGEROUS from loopctl-type opsFather Chrysostomos2014-11-081-5/+5
| | | | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. These operators never return, so they shouldn’t necessitate temp copies. (This could probably apply to dump, too, but I don’t fully under- stand dump.)
* Remove OA_DANGEROUS from dieFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. die never returns, so it shouldn’t necessitate temp copies.
* Remove OA_DANGEROUS from cond_exprFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. ?: always returns one of its arguments. Since aassign_common_vars, which does the danger check, also checks the kids of the cond_expr op, it is not necessary for cond_expr to be flagged this way.
* Remove OA_DANGEROUS from grep and mapFather Chrysostomos2014-11-081-4/+4
| | | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. grep returns its arguments, while map returns the results of its first expression. Since aassign_common_vars, which does the danger check, will also check the kids of the mapstart/grepstart ops, it is not nec- essary for grep and map themselves to be flagged this way.
* Remove OA_DANGEROUS from sortFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. pp_sort returns its arguments. aassign_common_vars will check its kid ops for danger as well, so it’s not necessary for sort itself to be flagged this way. This will allow cases like ($a,$b) = sort($c,$d) to forego the temp copy.
* Don’t copy VMS hints to cop->op_privateFather Chrysostomos2014-11-081-173/+169
| | | | | | Commit d5ec29879 in 2006 started storing all the hints in COPs. Some VMS-specific hints have nonetheless still been copied from PL_hints to cop->op_private, though that is no longer necessary.
* Remove OA_DANGEROUS from non-integer postdec/incFather Chrysostomos2014-11-081-4/+4
| | | | | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. While pp_postinc may return a lexical scalar, that only happens when the OPpTARGET_MY optimisation is happening; and aassign_common_vars in op.c checks specifically for that. Otherwise, it only returns a mortal or target, so it is not OA_DANGEROUS.
* Allow OPpTARGET_MY on non-integer postdec/incFather Chrysostomos2014-11-081-303/+303
| | | | | I don’t know why this was not done to begin with. The previous two commits fixed the only outstanding problems I am aware of.
* Remove OA_DANGEROUS from subst(cont)Father Chrysostomos2014-11-081-2/+2
| | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. pp_subst and pp_substcont only push new mortal scalars or read-only values on to the stack. Hence they are not OA_DANGEROUS.
* Remove OA_DANGEROUS from matchFather Chrysostomos2014-11-081-1/+1
| | | | | | | | | | | | | | OA_DANGEROUS indicates that temporary copies may need to be made in list assignment, to handle things like: ($a, $b) = ($b, $a); In other words, an op type is flagged with OA_DANGEROUS if its return values could occur elsewhere on the stack. pp_match pushes new mortals on to the stack in list context (or a read-only boolean; read-only values don’t matter), so they can’t occur elsewhere. Hence it is not OA_DANGEROUS.
* Allow OPpTARGET_MY optimisation for splitFather Chrysostomos2014-11-081-204/+204
| | | | | | | | | | | | | | | | Many operators have a special SV allocated in the pad which is used for return values (the target). If we make that pad offset point to a lexical variable, then we can optimise, say, $lexical = "$foo" into just "$foo", where $lexical is stringify’s ‘target’. And pp_stringify doesn’t need to know any better. We already do that for many ops. This is safe to extend to split. split only uses its target in this code at the end: GETTARGET; PUSHi(iters); so there is no danger of modifying its argument before reading it.
* Renumber op flags so TARGET_MY and OUR_INTRO differFather Chrysostomos2014-11-081-46/+46
| | | | | | | | | | | | | | | | | | | | | | I need split to be able to take both flags. Renumbering OUR_INTRO sets off a chain reaction requiring that various other flags be renum- bered. These are the affected ops: gvsv rv2sv rv2av rv2hv enteriter split rv2gv padsv aelem helem entersub padav padhv lvavref lvref refassign pushmark rv2cv ---------------------------------------------------------------------------------------------------------------------------------- 0 inargs 1 strct strct strct strct strct strct 2 slicw silcw reversed noinit targ slicw slicw elem elem targ 3 lvsub lvsub def lvsub lvsub lvsub amper lvsub lvsub iter iter amper 4 our our our our our our fake state defer defer dbg state state state state state state dbg 5-6 dref bool dref dref dref dref dref bool type type const(6) 7 intro intro intro intro intro implim intro intro intro intro intro intro intro intro intro intro intro nopar If we use 6 for OUR_INTRO and shift 5-6 down to 4-5, that frees up 4 (aka OPpTARGET_MY) for use on split. op.c:scalarvoid was testing the OPpOUR_INTRO flag on ops that don’t take it, so it needed adjustment.
* Allow OPpTARGET_MY optimisation for xFather Chrysostomos2014-11-071-289/+289
| | | | | | | | | | | | | Many operators have a special SV allocated in the pad which is used for return values (the target). If we make that pad offset point to a lexical variable, then we can optimise, say, $lexical = "$foo" into just "$foo", where $lexical is stringify’s ‘target’. And pp_stringify doesn’t need to know any better. We already do that for many ops. This can be extended to x. Despite what the comment in op_private says, list return values do not matter here, because the OPpTARGET_MY optimisation only happens when the operator is in scalar context. And the scalar code paths use TARG and push TARG on to the stack.
* Allow OPpTARGET_MY optimisation for vecFather Chrysostomos2014-11-071-237/+237
| | | | | | | | | | | | | Many operators have a special SV allocated in the pad which is used for return values (the target). If we make that pad offset point to a lexical variable, then we can optimise, say, $lexical = "$foo" into just "$foo", where $lexical is stringify’s ‘target’. And pp_stringify doesn’t need to know any better. We already do that for many ops. This can be extended to vec(). Despite what the comment in op_pri- vate says, lvalue usage does not matter here, because the OPpTARGET_MY optimisation only happens when the operator is in rvalue context. And the rvalue code paths use TARG and push TARG on to the stack.
* end the pp_mapstart trickeryJim Cromie2014-11-021-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Current codebase wires Perl_pp_mapstart to Perl_unimplemented_op (by regen/opcode.pl) [1], but then avoids runtime panics by Perl_ck_grep changing all OP_MAPSTART nodes to use PL_ppaddr[OP_GREPSTART] [2]. This is all too clever by half, so this patch undoes the trickery, and treats these 2 OPS like 93bad3fd5548 did for OP_AELEMFAST and \1_LEX. I cant glean a reason for this historical arrangement: Looking at regen/opcode.pl blamelog.. 65bca31a68 added Perl_unimplemented_op() used by 3 'unreachable' ops, and replaced a 'panic: mapstart' diag with a common one, so the trick goes further back. c78ff9799bf moved a minimal/DIEing pp_mapstart implementation to mathoms.c from pp_ctl.c. Perl_ck_grep also did the GREPSTART patching back then. f54cb97a39f did minor tweaks to a full pp_mapstart implementation. I couldnt find the commit between it and c78ff that changed pp_mapstart to a DIEing one, or I fat-fingered it, or I got distracted. looking at ck-grep(), the code doing [2] is from 22c35a8c23 in 1998. So anyway, I tried the following, it worked, it seems the historical reason is no longer relevant. [1] change regen/opcode.pl generated mapping -#define Perl_pp_mapstart Perl_unimplemented_op +#define Perl_pp_mapstart Perl_pp_grepstart this sets PL_ppaddr[OP_MAPSTART] = PL_ppaddr[OP_GREPSTART] during init, which makes the optype trickery in ck_grep[2] unneeded. [2] Drop re-type-ing of MAPSTARTs as GREPSTARTs by Perl_ck_grep(OP* o) Given 1, mapstart & grepstart share code, so just leave optype alone.
* fix typo in regen/opcode.plDavid Mitchell2014-10-201-1/+1
|
* Use srefgen for anoncodeFather Chrysostomos2014-10-181-1/+1
| | | | | | | | srefgen is faster than refgen, since it doesn’t have to loop through the arguments (there is only one) and there is no pushmark to execute. OA_RETSCALAR causes scalar context to be applied to anoncode ops, but it always returns one item anyway, so that causes no problems.
* [perl #122965] aelemfast in list assignmentFather Chrysostomos2014-10-131-1/+1
| | | | | | | I accidentally broke ($_[0],$_[1])=($_[1],$_[0]) in be9de18, which was only supposed to be a refactoring. Since it now happens later in the compilation phase when optimisations like aelemfast have happened, the search for common vars needs to take aelemfast into account.
* Optimise "@_" to a single joinFather Chrysostomos2014-10-121-1/+1
| | | | instead of stringify(join(...)).
* Fold join to const or stringify where possibleFather Chrysostomos2014-10-121-1/+1
| | | | | | | | | | | | | | Due to the exigencies of the implementation, "$_->$*" ends up with a join op (join $", $$_), which is unnecessary. This gave me the idea of folding it where possible (instead of trying to tackle it in toke.c), which would also make explicit joins benefit, too. If the arguments are a simple scalar or constant followed by a single-item list, then the join can become a stringify, and the sepa- rator can simply disappear. Further (and this is unrelated to "$_->$*"), if all of join’s argu- ments are constant, the whole thing can be folded to a const op.
* Handle state vars correctly in ref assignmentFather Chrysostomos2014-10-111-7/+7
| | | | | Only \state(@_) was handling this correctly, as pp_lvavref calls pp_padav.
* Add OPpLVREF_ITER flagFather Chrysostomos2014-10-111-134/+136
| | | | | An lvalue reference used as an iterator variable will be implemented using an lvref op with this flag set.
* lvavref needs OPpLVAL_INTRO and OPpPAD_STATEFather Chrysostomos2014-10-111-2/+2
|
* Add lvavref op typeFather Chrysostomos2014-10-111-0/+8
| | | | | This will be used for slurpy array ref assignments. \(@a) = \(@b) will make @a share the same elements as @b.
* lvref is actually a baseop/unopFather Chrysostomos2014-10-111-1/+1
| | | | When used for pad vars, it is childless.
* Renumber OPpLVREF_TYPEFather Chrysostomos2014-10-101-13/+13
| | | | to avoid conflicting with OPpPAD_STATE.
* Add priv flags for the type of lvalue refFather Chrysostomos2014-10-101-167/+177
|
* lvrefslice gets OPpLVAL_INTROFather Chrysostomos2014-10-101-2/+3
|
* Add lvrefslice op typeFather Chrysostomos2014-10-101-0/+7
|
* Assignment to array elem refsFather Chrysostomos2014-10-101-161/+163
|
* List assignment to lexical scalar refsFather Chrysostomos2014-10-101-2/+2
| | | | \($x,$y)=... does not work yet, but \(my $x) and (\$x, \$y) do.
* Add lvref op typeFather Chrysostomos2014-10-101-0/+8
|