pike.git / src / peep.in

version» Context lines:

pike.git/src/peep.in:1: - // - // $Id: peep.in,v 1.43 2000/12/01 03:19:01 hubbe Exp $ - // + // This file is part of Pike. For copyright information see COPYRIGHT. + // Pike is distributed under GPL, LGPL and MPL. See the file COPYING + // for more information.      NOP :   POP_N_ELEMS (0) :   POP_N_ELEMS POP_VALUE : POP_N_ELEMS ($1a + 1)   POP_VALUE POP_VALUE : POP_N_ELEMS (2)   POP_VALUE POP_N_ELEMS : POP_N_ELEMS ($2a + 1)   POP_N_ELEMS POP_N_ELEMS : POP_N_ELEMS ($1a + $2a)   POP_N_ELEMS(1) : POP_VALUE -  + POP_VALUE POP_TO_MARK : POP_TO_MARK + POP_N_ELEMS POP_TO_MARK : POP_TO_MARK      MARK MARK: MARK2 -  + MARK POP_MARK: + MARK2 POP_MARK: MARK + MARK POP_TO_MARK: + MARK2 POP_TO_MARK: MARK    -  + SWAP SWAP: + DUP POP_VALUE: + DUP POP_N_ELEMS [$2a > 0]: POP_N_ELEMS($2a-1) + // The opcode list is clearer without this. + //SYNCH_MARK POP_SYNCH_MARK: +    ASSIGN_GLOBAL POP_VALUE : ASSIGN_GLOBAL_AND_POP($1a)   ASSIGN_LOCAL POP_VALUE : ASSIGN_LOCAL_AND_POP($1a) - CALL_LFUN POP_VALUE : CALL_LFUN_AND_POP($1a) - APPLY POP_VALUE : APPLY_AND_POP($1a) - MARK APPLY : MARK_APPLY($2a) - MARK_APPLY POP_VALUE : MARK_APPLY_POP($1a) + RECUR POP_VALUE : RECUR_AND_POP($1a) +  + // Negation and complement of constants.   NUMBER(0) : CONST0   NUMBER(1) : CONST1   NUMBER(-1) : CONST_1 -  + NEG_NUMBER(1) : CONST_1   NUMBER (0x7fffffff) : BIGNUM   CONST0 NEGATE : CONST0   CONST1 NEGATE : CONST_1   CONST_1 NEGATE : CONST1   NUMBER NEGATE : NEG_NUMBER($1a) - NUMBER [$1a < 0 && (-$1a)>0] : NEG_NUMBER (-$1a) +    NEG_NUMBER NEGATE : NUMBER ($1a) -  + NUMBER [ $1a < 0 && !INT32_NEG_OVERFLOW($1a) ] : NEG_NUMBER (-$1a) + NEG_NUMBER [ $1a <= 0 && !INT32_NEG_OVERFLOW($1a) ] : NUMBER (-$1a)   NEGATE NEGATE :   COMPL COMPL :   NEGATE CONST_1 ADD_INTS : COMPL   NEGATE CONST1 SUBTRACT : COMPL -  + NUMBER ASSIGN_LOCAL NEGATE: NUMBER($1a) ASSIGN_LOCAL_AND_POP($2a) NEG_NUMBER($1a) + NEG_NUMBER ASSIGN_LOCAL NEGATE: NEG_NUMBER($1a) ASSIGN_LOCAL_AND_POP($2a) NUMBER($1a) + CONST1 ASSIGN_LOCAL NEGATE: CONST1 ASSIGN_LOCAL_AND_POP($2a) CONST_1 + CONST_1 ASSIGN_LOCAL NEGATE: CONST_1 ASSIGN_LOCAL_AND_POP($2a) CONST1 +    CONST0 ASSIGN_LOCAL_AND_POP : CLEAR_LOCAL($2a) -  + CONST0 ASSIGN_LOCAL: CLEAR_LOCAL($2a) CONST0      LOCAL_2_LOCAL [$1a == $1b] : -  + GLOBAL ASSIGN_GLOBAL_AND_POP($1a) :    -  + // Generated by for( int i=0; i<local; i++ ) where i is not used in + // the loop. + ASSIGN_LOCAL_NUMBER_AND_POP LOCAL($1a) : ASSIGN_LOCAL_NUMBER_AND_POP($1a,$1b) NUMBER($1b) + ASSIGN_GLOBAL_NUMBER_AND_POP GLOBAL($1a) : ASSIGN_GLOBAL_NUMBER_AND_POP($1a,$1b) NUMBER($1b) + NUMBER COMPL: NUMBER(~$1a) + ASSIGN_LOCAL_NUMBER_AND_POP LOCAL_LVALUE LOCAL($1a) : ASSIGN_LOCAL_NUMBER_AND_POP($1a,$1b) LOCAL_LVALUE($2a) NUMBER($1b) + ASSIGN_GLOBAL_NUMBER_AND_POP GLOBAL_LVALUE GLOBAL($1a) : ASSIGN_GLOBAL_NUMBER_AND_POP($1a,$1b) GLOBAL_LVALUE($2a) NUMBER($1b) + ASSIGN_LOCAL_NUMBER_AND_POP GLOBAL_LVALUE LOCAL($1a) : ASSIGN_LOCAL_NUMBER_AND_POP($1a,$1b) GLOBAL_LVALUE($2a) NUMBER($1b) +  + // Ok, this is ridiculously specific, but it is generated by for(..) + // when the variable is not used, like above, but for globals: + ASSIGN_GLOBAL_NUMBER_AND_POP[$1b > -0x80000000L] GLOBAL_LVALUE($1a) DEC: ASSIGN_GLOBAL_NUMBER_AND_POP($1a, $1b - 1) NUMBER($1b - 1) +  + ASSIGN_GLOBAL_NUMBER_AND_POP[$1b < 0x7fffffff] GLOBAL_LVALUE($1a) INC: ASSIGN_GLOBAL_NUMBER_AND_POP($1a, $1b + 1) NUMBER($1b + 1) +  + ASSIGN_GLOBAL_NUMBER_AND_POP[$1b > -0x80000000L] GLOBAL_LVALUE($1a) DEC_AND_POP: ASSIGN_GLOBAL_NUMBER_AND_POP($1a, $1b - 1) + ASSIGN_GLOBAL_NUMBER_AND_POP[$1b < 0x7fffffff] GLOBAL_LVALUE($1a) INC_AND_POP: ASSIGN_GLOBAL_NUMBER_AND_POP($1a, $1b + 1) +  + LOCAL_LVALUE LOCAL ADD_TO_AND_POP : ADD_LOCALS_AND_POP($1a,$2a) + LOCAL_LVALUE NUMBER ADD_TO_AND_POP: ADD_LOCAL_INT_AND_POP($1a,$2a) + LOCAL_LVALUE CONST_1 ADD_TO_AND_POP: ADD_LOCAL_INT_AND_POP($1a,-1) + LOCAL_LVALUE CONST1 ADD_TO_AND_POP: ADD_LOCAL_INT_AND_POP($1a,1) + LOCAL_LVALUE CONST0 ADD_TO_AND_POP: +  + LOCAL_LVALUE LTOSVAL ADD_INT ASSIGN: ADD_LOCAL_INT($1a,$3a) + LOCAL_LVALUE LTOSVAL ADD_NEG_INT ASSIGN: ADD_LOCAL_INT($1a,-$3a) +  + NUMBER ASSIGN_LOCAL_AND_POP : ASSIGN_LOCAL_NUMBER_AND_POP($2a,$1a) + CONST0 ASSIGN_LOCAL_AND_POP : CLEAR_LOCAL($2a) + CONST1 ASSIGN_LOCAL_AND_POP : ASSIGN_LOCAL_NUMBER_AND_POP($2a,1) + CONST_1 ASSIGN_LOCAL_AND_POP : ASSIGN_LOCAL_NUMBER_AND_POP($2a,-1) +  + NUMBER ASSIGN_GLOBAL_AND_POP : ASSIGN_GLOBAL_NUMBER_AND_POP($2a,$1a) + CONST0 ASSIGN_GLOBAL_AND_POP : ASSIGN_GLOBAL_NUMBER_AND_POP($2a,0) + CONST1 ASSIGN_GLOBAL_AND_POP : ASSIGN_GLOBAL_NUMBER_AND_POP($2a,1) + CONST_1 ASSIGN_GLOBAL_AND_POP : ASSIGN_GLOBAL_NUMBER_AND_POP($2a,-1) +    // Remove clearing of locals from the beginning of functions - START_FUNCTION LABEL(0) CLEAR_LOCAL : LABEL(0) - START_FUNCTION LABEL(0) CLEAR_2_LOCAL : LABEL(0) - START_FUNCTION LABEL(0) CLEAR_4_LOCAL : LABEL(0) + // But don't remove clearing of arguments! + BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) + BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_2_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) + BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_4_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0)    - START_FUNCTION CLEAR_LOCAL : - START_FUNCTION CLEAR_2_LOCAL : - START_FUNCTION CLEAR_4_LOCAL : + BYTE ENTRY START_FUNCTION CLEAR_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION + BYTE ENTRY START_FUNCTION CLEAR_2_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION + BYTE ENTRY START_FUNCTION CLEAR_4_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION    - CLEAR_LOCAL NUMBER(0) ASSIGN_LOCAL_AND_POP ($1a) : CLEAR_LOCAL($1a) - CLEAR_LOCAL NUMBER(0) ASSIGN_LOCAL_AND_POP ($1a+1) : CLEAR_2_LOCAL($1a) + CLEAR_LOCAL CLEAR_LOCAL($1a) : CLEAR_LOCAL($1a) + CLEAR_LOCAL CLEAR_LOCAL($1a+1) : CLEAR_2_LOCAL($1a)   CLEAR_2_LOCAL CLEAR_2_LOCAL($1a+2) : CLEAR_4_LOCAL($1a)    -  + // Attempt to make the above trigger more often. + CLEAR_LOCAL CLEAR_2_LOCAL($1a+1) : CLEAR_2_LOCAL($1a) CLEAR_LOCAL($2a+1) + CLEAR_LOCAL CLEAR_4_LOCAL($1a+1) : CLEAR_4_LOCAL($1a) CLEAR_LOCAL($2a+3) + CLEAR_2_LOCAL CLEAR_4_LOCAL($1a+2) : CLEAR_4_LOCAL($1a) CLEAR_2_LOCAL($2a+2) +  + // Attempt to de-interleave clearing of locals. + CONST0 CLEAR_LOCAL : CLEAR_LOCAL($2a) CONST0 + CONST1 CLEAR_LOCAL : CLEAR_LOCAL($2a) CONST1 + CONST_1 CLEAR_LOCAL : CLEAR_LOCAL($2a) CONST_1 + NUMBER CLEAR_LOCAL : CLEAR_LOCAL($2a) NUMBER($1a) + NEG_NUMBER CLEAR_LOCAL : CLEAR_LOCAL($2a) NEG_NUMBER($1a) + CONSTANT CLEAR_LOCAL : CLEAR_LOCAL($2a) CONSTANT($1a) +  +    // CONST_1 MULTIPLY : NEGATE   // CONST0 MULTIPLY : POP_VALUE CONST0   // CONST1 MULTIPLY : - // NUMBER MULTIPLY [count_bits($1a)==1]: NUMBER(my_log2($1a)) LSH + // NUMBER MULTIPLY [!($1a & ($1a - 1))]: NUMBER(my_log2($1a)) LSH      // CONST_1 DIVIDE : NEGATE   // CONST1 DIVIDE : - // NUMBER DIVIDE [count_bits($1a)==1]: NUMBER(my_log2($1a)) RSH + // NUMBER DIVIDE [!($1a & ($1a - 1))]: NUMBER(my_log2($1a)) RSH      CONST0 SUBTRACT:   CONST0 XOR:   CONST_1 XOR: COMPL   CONST0 RETURN: RETURN_0   CONST1 RETURN: RETURN_1 -  + CONST0 VOLATILE_RETURN: RETURN_0 + CONST1 VOLATILE_RETURN: RETURN_1   INC POP_VALUE: INC_AND_POP   POST_INC POP_VALUE: INC_AND_POP   DEC POP_VALUE: DEC_AND_POP   POST_DEC POP_VALUE: DEC_AND_POP   NOT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_ZERO($2a)   NOT BRANCH_WHEN_ZERO: BRANCH_WHEN_NON_ZERO($2a)      POP_VALUE RETURN_0: RETURN_0   POP_N_ELEMS RETURN_0: RETURN_0   POP_VALUE RETURN_1: RETURN_1   POP_N_ELEMS RETURN_1: RETURN_1    - NOTREACHED !LABEL : NOTREACHED - BRANCH !LABEL : BRANCH($1a) - RETURN !LABEL : RETURN - RETURN_0 !LABEL : RETURN_0 - RETURN_1 !LABEL : RETURN_1 - RETURN_LOCAL !LABEL : RETURN_LOCAL($1a) - APPLY_AND_RETURN !LABEL : APPLY_AND_RETURN($1a) - CALL_FUNCTION_AND_RETURN !LABEL : CALL_FUNCTION_AND_RETURN($1a) - CALL_LFUN_AND_RETURN !LABEL : CALL_LFUN_AND_RETURN($1a) + // F_SYNCH_MARK and F_POP_SYNCH_MARK is output only with -d3 and + // higher. We keep them solely for balancing the asm debug output. + #define DeadCodeEndCond(op) \ +  [op != F_LABEL && op != F_SYNCH_MARK && op != F_POP_SYNCH_MARK && op != F_ENTRY] + BRANCH ? DeadCodeEndCond($2o) : BRANCH($1a) + RETURN ? DeadCodeEndCond($2o) : RETURN + VOLATILE_RETURN ? DeadCodeEndCond($2o) : VOLATILE_RETURN + RETURN_0 ? DeadCodeEndCond($2o) : RETURN_0 + RETURN_1 ? DeadCodeEndCond($2o) : RETURN_1 + RETURN_LOCAL ? DeadCodeEndCond($2o) : RETURN_LOCAL($1a)    -  + // Get rid of extra catch-levels. + // Note that the corresponding exit catch is killed + // by dead code elimination. + CATCH ESCAPE_CATCH: +    LOCAL_LVALUE INC : INC_LOCAL ($1a)   LOCAL_LVALUE POST_INC : POST_INC_LOCAL ($1a)   LOCAL_LVALUE INC_AND_POP : INC_LOCAL_AND_POP ($1a)   INC_LOCAL POP_VALUE : INC_LOCAL_AND_POP ($1a)   POST_INC_LOCAL POP_VALUE : INC_LOCAL_AND_POP ($1a)      LOCAL_LVALUE DEC : DEC_LOCAL ($1a)   LOCAL_LVALUE POST_DEC : POST_DEC_LOCAL ($1a)   LOCAL_LVALUE DEC_AND_POP : DEC_LOCAL_AND_POP ($1a)   DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP ($1a)   POST_DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP ($1a)    - ASSIGN_LOCAL_AND_POP LOCAL ($1a) RETURN: ASSIGN_LOCAL($1a) RETURN - ASSIGN_LOCAL_AND_POP LOCAL ($1a) RETURN [!(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED)]: RETURN + ASSIGN_GLOBAL_AND_POP GLOBAL_LVALUE($1a) INC_AND_POP : ADD_INT(1) ASSIGN_GLOBAL_AND_POP($1a) + ASSIGN_GLOBAL_AND_POP GLOBAL_LVALUE($1a) DEC_AND_POP : ADD_NEG_INT(1) ASSIGN_GLOBAL_AND_POP($1a) + GLOBAL_LVALUE INC_AND_POP GLOBAL($1a) : GLOBAL_LVALUE($1a) INC + GLOBAL_LVALUE DEC_AND_POP GLOBAL($1a) : GLOBAL_LVALUE($1a) DEC    -  + ASSIGN_LOCAL RETURN [!(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED)]: RETURN + ASSIGN_LOCAL VOLATILE_RETURN [!(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED)]: VOLATILE_RETURN +    ASSIGN_LOCAL BRANCH_WHEN_ZERO LOCAL($1a) RETURN LABEL($2a): ASSIGN_LOCAL($1a) RETURN_IF_TRUE LABEL($2a) -  + ASSIGN_LOCAL BRANCH_WHEN_ZERO LOCAL($1a) VOLATILE_RETURN LABEL($2a): ASSIGN_LOCAL($1a) RETURN_IF_TRUE LABEL($2a)      ASSIGN_LOCAL BRANCH_WHEN_ZERO LOCAL($1a) RETURN LABEL($2a) [!(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED)] : RETURN_IF_TRUE ASSIGN_LOCAL($1a) LABEL($2a) -  + ASSIGN_LOCAL BRANCH_WHEN_ZERO LOCAL($1a) VOLATILE_RETURN LABEL($2a) [!(Pike_compiler->compiler_frame->lexical_scope & SCOPE_SCOPED)] : RETURN_IF_TRUE ASSIGN_LOCAL($1a) LABEL($2a)      ASSIGN_GLOBAL BRANCH_WHEN_ZERO GLOBAL($1a) RETURN LABEL($2a): ASSIGN_GLOBAL($1a) RETURN_IF_TRUE LABEL($2a) -  + ASSIGN_GLOBAL BRANCH_WHEN_ZERO GLOBAL($1a) VOLATILE_RETURN LABEL($2a): ASSIGN_GLOBAL($1a) RETURN_IF_TRUE LABEL($2a)         GLOBAL_LVALUE INC_AND_POP GLOBAL($1a): GLOBAL_LVALUE($1a) INC   GLOBAL_LVALUE DEC_AND_POP GLOBAL($1a): GLOBAL_LVALUE($1a) DEC      CONST1 BRANCH_WHEN_ZERO:   CONST0 BRANCH_WHEN_ZERO: BRANCH($2a)   CONST1 BRANCH_WHEN_NON_ZERO: BRANCH($2a)   CONST0 BRANCH_WHEN_NON_ZERO: -  + NUMBER [$1a] BRANCH_WHEN_ZERO: + NUMBER [$1a] BRANCH_WHEN_NON_ZERO: BRANCH($2a)      // These optimizations are now handled in optimize_eq   // CONST0 BRANCH_WHEN_EQ: BRANCH_WHEN_ZERO($2a)   // CONST0 BRANCH_WHEN_NE: BRANCH_WHEN_NON_ZERO($2a) -  + // + // This one is not safe.   // CONST0 EQ: NOT      EQ BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_EQ ($2a)   NE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_NE ($2a)   LT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_LT ($2a)   GT BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_GT ($2a)   LE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_LE ($2a)   GE BRANCH_WHEN_NON_ZERO: BRANCH_WHEN_GE ($2a)      EQ BRANCH_WHEN_ZERO: BRANCH_WHEN_NE ($2a)   NE BRANCH_WHEN_ZERO: BRANCH_WHEN_EQ ($2a) - LT BRANCH_WHEN_ZERO: BRANCH_WHEN_GE ($2a) - GT BRANCH_WHEN_ZERO: BRANCH_WHEN_LE ($2a) - LE BRANCH_WHEN_ZERO: BRANCH_WHEN_GT ($2a) - GE BRANCH_WHEN_ZERO: BRANCH_WHEN_LT ($2a) + // The following only work on total orders. We can't assume that. + // LT BRANCH_WHEN_ZERO: BRANCH_WHEN_GE ($2a) + // GT BRANCH_WHEN_ZERO: BRANCH_WHEN_LE ($2a) + // LE BRANCH_WHEN_ZERO: BRANCH_WHEN_GT ($2a) + // GE BRANCH_WHEN_ZERO: BRANCH_WHEN_LT ($2a)      EQ LOR: EQ_OR ($2a)   EQ LAND: EQ_AND ($2a)      EQ NOT: NE   NE NOT: EQ - LT NOT: GE - GT NOT: LE - LE NOT: GT - GE NOT: LT +     - LOCAL LOCAL [$3o != F_SIZEOF && $3o != F_INDEX ]: 2_LOCALS ($1a,$2a) - MARK LOCAL [ $3o != F_SIZEOF && $3o != F_INDEX ]: MARK_AND_LOCAL ($2a) + // The following only work on total orders. We can't assume that. + // + // LT NOT: GE + // GT NOT: LE + // LE NOT: GT + // GE NOT: LT +  + LOCAL LOCAL : 2_LOCALS ($1a,$2a) + MARK LOCAL : MARK_AND_LOCAL ($2a) + MARK GLOBAL: MARK_AND_GLOBAL ($2a)   MARK STRING : MARK_AND_STRING($2a) -  + MARK EXTERNAL : MARK_AND_EXTERNAL($2a,$2b) + MARK CONST0 : MARK_AND_CONST0 + MARK CONST1 : MARK_AND_CONST1   LOCAL SIZEOF: SIZEOF_LOCAL ($1a) -  + MARK_AND_LOCAL SIZEOF: MARK SIZEOF_LOCAL ($1a) + 2_LOCALS SIZEOF: LOCAL($1a) SIZEOF_LOCAL ($1b)   STRING INDEX: STRING_INDEX ($1a)   INDEX SWITCH: SWITCH_ON_INDEX($2a)   LOCAL SWITCH: SWITCH_ON_LOCAL($1a,$2a) -  + 2_LOCALS SWITCH: LOCAL($1a) SWITCH_ON_LOCAL($1b,$2a)      STRING CLEAR_STRING_SUBTYPE: STRING ($1a)   CONST0 CLEAR_STRING_SUBTYPE: CONST0   CONST1 CLEAR_STRING_SUBTYPE: CONST1   CONST_1 CLEAR_STRING_SUBTYPE: CONST_1   NUMBER CLEAR_STRING_SUBTYPE: NUMBER($1a)   NEG_NUMBER CLEAR_STRING_SUBTYPE: NEG_NUMBER($1a)      LOCAL INDEX: LOCAL_INDEX ($1a)   LOCAL CLEAR_STRING_SUBTYPE INDEX: LOCAL_INDEX ($1a) -  + MARK_AND_LOCAL INDEX: MARK LOCAL_INDEX ($1a) + MARK_AND_LOCAL CLEAR_STRING_SUBTYPE INDEX: MARK LOCAL_INDEX ($1a) + 2_LOCALS INDEX: LOCAL_LOCAL_INDEX($1b,$1a) + 2_LOCALS CLEAR_STRING_SUBTYPE INDEX: LOCAL_LOCAL_INDEX($1b,$1a)    - LOCAL LOCAL INDEX: LOCAL_LOCAL_INDEX($2a,$1a) - LOCAL LOCAL CLEAR_STRING_SUBTYPE INDEX: LOCAL_LOCAL_INDEX($2a,$1a) + 2_LOCALS [$1a == $1b]: LOCAL($1a) DUP + GLOBAL GLOBAL($1a): GLOBAL($1a) DUP      CONST0 INDEX: POS_INT_INDEX (0)   CONST_1 INDEX: NEG_INT_INDEX (1)   CONST1 INDEX: POS_INT_INDEX (1) -  + NUMBER INDEX: POS_INT_INDEX ($1a) + NEG_NUMBER INDEX: NEG_INT_INDEX ($1a) + POS_INT_INDEX [$1a < 0 && !INT32_NEG_OVERFLOW($1a) ]: NEG_INT_INDEX (-$1a) + NEG_INT_INDEX [$1a <= 0 && !INT32_NEG_OVERFLOW($1a) ]: POS_INT_INDEX (-$1a)    - NUMBER [$1a < 0 && ($1a != -$1a)] INDEX: NEG_INT_INDEX (-$1a) - NUMBER [$1a >= 0] INDEX: POS_INT_INDEX ($1a) - NEG_NUMBER [$1a >= 0] INDEX: NEG_INT_INDEX ($1a) - NEG_NUMBER [$1a < 0 && ($1a != -$1a)] INDEX: POS_INT_INDEX (-$1a) -  +    BRANCH_WHEN_ZERO BRANCH LABEL ($1a): BRANCH_WHEN_NON_ZERO($2a) LABEL($1a)   BRANCH_WHEN_NON_ZERO BRANCH LABEL ($1a): BRANCH_WHEN_ZERO($2a) LABEL($1a)      BRANCH_WHEN_EQ BRANCH LABEL ($1a) : BRANCH_WHEN_NE($2a) LABEL($1a)   BRANCH_WHEN_NE BRANCH LABEL ($1a) : BRANCH_WHEN_EQ($2a) LABEL($1a)    - BRANCH_WHEN_LT BRANCH LABEL ($1a) : BRANCH_WHEN_GE($2a) LABEL($1a) - BRANCH_WHEN_GE BRANCH LABEL ($1a) : BRANCH_WHEN_LT($2a) LABEL($1a) + // The following only work on total orders. We can't assume that. + // + // BRANCH_WHEN_LT BRANCH LABEL ($1a) : BRANCH_WHEN_GE($2a) LABEL($1a) + // BRANCH_WHEN_GE BRANCH LABEL ($1a) : BRANCH_WHEN_LT($2a) LABEL($1a) + // + // BRANCH_WHEN_LE BRANCH LABEL ($1a) : BRANCH_WHEN_GT($2a) LABEL($1a) + // BRANCH_WHEN_GT BRANCH LABEL ($1a) : BRANCH_WHEN_LE($2a) LABEL($1a)    - BRANCH_WHEN_LE BRANCH LABEL ($1a) : BRANCH_WHEN_GT($2a) LABEL($1a) - BRANCH_WHEN_GT BRANCH LABEL ($1a) : BRANCH_WHEN_LE($2a) LABEL($1a) +     -  +    CONST0 ADD_INTS: ADD_INT (0)   CONST1 ADD_INTS: ADD_INT (1)   CONST_1 ADD_INTS: ADD_NEG_INT (1)   NUMBER [$1a >= 0] ADD_INTS : ADD_INT ($1a) - NUMBER [$1a < 0 && ($1a != -$1a)] ADD_INTS : ADD_NEG_INT (-$1a) + NEG_NUMBER [$1a > 0] ADD_INTS : ADD_NEG_INT ($1a)      CONST0 ADD: ADD_INT (0)   CONST1 ADD: ADD_INT (1)   CONST_1 ADD: ADD_NEG_INT (1)   NUMBER [$1a >= 0] ADD : ADD_INT ($1a) - NUMBER [$1a < 0 && ($1a != -$1a) ] ADD : ADD_NEG_INT (-$1a) + NEG_NUMBER [$1a > 0] ADD : ADD_NEG_INT ($1a)    - CONST0 SUBTRACT: ADD_INT (0) - CONST1 SUBTRACT: ADD_NEG_INT (-1) + CONST1 SUBTRACT: ADD_NEG_INT (1)   CONST_1 SUBTRACT: ADD_INT (1)   NUMBER [$1a >= 0] SUBTRACT : ADD_NEG_INT ($1a) - NUMBER [$1a < 0 && ($1a != -$1a)] SUBTRACT : ADD_INT (-$1a) + NEG_NUMBER [$1a > 0] SUBTRACT : ADD_INT ($1a)    - LTOSVAL2 ADD ASSIGN_AND_POP : ADD_TO_AND_POP - LTOSVAL ADD ASSIGN_AND_POP : ADD_TO_AND_POP + // This set of optimizations is broken. Consider the case: + // STRING ADD_INT ADD_INT + // + // ADD_INT ADD_INT: ADD_INT ($1a+$2a) + // ADD_NEG_INT ADD_NEG_INT: ADD_NEG_INT ($1a+$2a) + // ADD_NEG_INT ADD_INT [$1a <= $2a]: ADD_INT ($2a-$1a) + // ADD_NEG_INT ADD_INT [$1a > $2a]: ADD_NEG_INT ($1a-$2a) + // ADD_INT ADD_NEG_INT [$2a <= $1a]: ADD_INT ($1a-$2a) + // ADD_INT ADD_NEG_INT [$2a > $1a]: ADD_NEG_INT ($2a-$1a)    - LTOSVAL2 ADD_INTS ASSIGN_AND_POP : ADD_TO_AND_POP - LTOSVAL ADD_INTS ASSIGN_AND_POP : ADD_TO_AND_POP + // FIXME: BIGNUMS? + // + // NUMBER ADD_INT : NUMBER ($1a+$2a) + // NUMBER ADD_NEG_INT : NUMBER ($1a-$2a) + // CONST1 ADD_INT : NUMBER(1+$2a) + // CONST1 ADD_NEG_INT : NUMBER(1-$2a) + // CONST_1 ADD_INT : NUMBER($2a-1) + // CONST_1 ADD_NEG_INT : NUMBER(-(1+$2a))    - LTOSVAL2 ADD_FLOATS ASSIGN_AND_POP : ADD_TO_AND_POP - LTOSVAL ADD_FLOATS ASSIGN_AND_POP : ADD_TO_AND_POP + // FIXME: What about LTOSVAL_AND_FREE variants of the following three rules?    -  + LTOSVAL2_AND_FREE ADD ASSIGN : ADD_TO + LTOSVAL ADD ASSIGN : ADD_TO +  + LTOSVAL2_AND_FREE ADD_INTS ASSIGN : ADD_TO + LTOSVAL ADD_INTS ASSIGN : ADD_TO +  + LTOSVAL2_AND_FREE ADD_FLOATS ASSIGN : ADD_TO + LTOSVAL ADD_FLOATS ASSIGN : ADD_TO +  + LOCAL CONST1 ADD_TO : INC_LOCAL($1a) + LOCAL CONST_1 ADD_TO : DEC_LOCAL($1a) +  + ADD_TO POP_VALUE : ADD_TO_AND_POP + ASSIGN POP_VALUE : ASSIGN_AND_POP +    LOCAL CONST1 ADD_TO_AND_POP : INC_LOCAL_AND_POP($1a)   LOCAL CONST_1 ADD_TO_AND_POP : DEC_LOCAL_AND_POP($1a)    - APPLY [ !(debug_options & NO_TAILRECURSION) ] RETURN : APPLY_AND_RETURN($1a) - CALL_FUNCTION [ !(debug_options & NO_TAILRECURSION) ] RETURN : CALL_FUNCTION_AND_RETURN - CALL_LFUN [ !(debug_options & NO_TAILRECURSION) ] RETURN : CALL_LFUN_AND_RETURN($1a) + INC_LOCAL POP_VALUE : INC_LOCAL_AND_POP($1a) + DEC_LOCAL POP_VALUE : DEC_LOCAL_AND_POP($1a)    - LOCAL RETURN : RETURN_LOCAL($1a) + #ifdef EAT_STACK   APPLY ASSIGN_LOCAL_AND_POP : APPLY_ASSIGN_LOCAL_AND_POP($1a,$2a) - ASSIGN_LOCAL_AND_POP INC_LOCAL_AND_POP($1a) : ADD_INT(1) ASSIGN_LOCAL_AND_POP($1a) - ASSIGN_LOCAL_AND_POP DEC_LOCAL_AND_POP($1a) : ADD_NEG_INT(1) ASSIGN_LOCAL_AND_POP($1a) - NUMBER ADD_INT [ !INT_TYPE_ADD_OVERFLOW($1a, $2a) ] : NUMBER($1a+$2a) - NUMBER ADD_NEG_INT [ !INT_TYPE_SUB_OVERFLOW($1a, $2a) ]: NUMBER($1a-$2a) - NEG_NUMBER ADD_INT [ !INT_TYPE_ADD_OVERFLOW(-$1a, $2a) ]: NUMBER(-$1a+$2a) - NEG_NUMBER ADD_NEG_INT [ !INT_TYPE_SUB_OVERFLOW(-$1a, $2a) ]: NUMBER(-$1a-$2a) + #endif + ASSIGN_LOCAL_AND_POP INC_LOCAL($1a) : ADD_INT(1) ASSIGN_LOCAL($1a) + ASSIGN_LOCAL_AND_POP DEC_LOCAL($1a) : ADD_NEG_INT(1) ASSIGN_LOCAL($1a)    -  + LOCAL RETURN : RETURN_LOCAL($1a) + LOCAL VOLATILE_RETURN : RETURN_LOCAL($1a) +  + NUMBER ADD_INT [ !INT32_ADD_OVERFLOW($1a, $2a) ] : NUMBER($1a+$2a) + NUMBER ADD_NEG_INT [ !INT32_SUB_OVERFLOW($1a, $2a) ]: NUMBER($1a-$2a) + NEG_NUMBER ADD_INT [ !INT32_SUB_OVERFLOW($2a, $1a) ]: NUMBER($2a-$1a) + NEG_NUMBER ADD_NEG_INT [ !INT32_NEG_OVERFLOW($1a) && !INT32_SUB_OVERFLOW(-$1a, $2a) ]: NUMBER(-$1a-$2a) +  + CONST0 ADD_INT : NUMBER($2a) + CONST0 ADD_NEG_INT : NEG_NUMBER($2a) + CONST1 ADD_INT [ !INT32_ADD_OVERFLOW($2a, 1) ] : NUMBER($2a+1) + CONST1 ADD_NEG_INT [ !INT32_SUB_OVERFLOW($2a, 1) ] : NEG_NUMBER($2a-1) + CONST_1 ADD_INT [ !INT32_SUB_OVERFLOW($2a, 1) ] : NUMBER($2a-1) + CONST_1 ADD_NEG_INT [ !INT32_ADD_OVERFLOW($2a, 1) && ($2a+1) > 0] : NEG_NUMBER($2a+1) + CONST0 LOCAL ADD_INTS : LOCAL($2a) + CONST0 LOCAL NEGATE ADD_INTS : LOCAL($2a) NEGATE + CONST0 GLOBAL ADD_INTS : GLOBAL($2a) + CONST0 GLOBAL NEGATE ADD_INTS : GLOBAL($2a) NEGATE +  + LOCAL ADD_INT LOCAL($1a) : LOCAL($1a) DUP ADD_INT($2a) SWAP + GLOBAL ADD_INT GLOBAL($1a) : GLOBAL($1a) DUP ADD_INT($2a) SWAP + LOCAL ADD_NEG_INT LOCAL($1a) : LOCAL($1a) DUP ADD_NEG_INT($2a) SWAP + GLOBAL ADD_NEG_INT GLOBAL($1a) : GLOBAL($1a) DUP ADD_NEG_INT($2a) SWAP +    LOCAL BRANCH_WHEN_NON_ZERO : BRANCH_IF_LOCAL($1a) POINTER($2a)   LOCAL BRANCH_WHEN_ZERO : BRANCH_IF_NOT_LOCAL($1a) POINTER($2a)    -  + // quick_branch_when[_non]_zero _knows_ that the + // value on the stack is an integer. + GT BRANCH_WHEN_ZERO : GT QUICK_BRANCH_WHEN_ZERO($2a) + GE BRANCH_WHEN_ZERO : GE QUICK_BRANCH_WHEN_ZERO($2a) + LT BRANCH_WHEN_ZERO : LT QUICK_BRANCH_WHEN_ZERO($2a) + LE BRANCH_WHEN_ZERO : LE QUICK_BRANCH_WHEN_ZERO($2a) +  + GT BRANCH_WHEN_NON_ZERO : GT QUICK_BRANCH_WHEN_NON_ZERO($2a) + GE BRANCH_WHEN_NON_ZERO : GE QUICK_BRANCH_WHEN_NON_ZERO($2a) + LT BRANCH_WHEN_NON_ZERO : LT QUICK_BRANCH_WHEN_NON_ZERO($2a) + LE BRANCH_WHEN_NON_ZERO : LE QUICK_BRANCH_WHEN_NON_ZERO($2a) +  + // It is not really neccessary to set up a frame for these cases. + // Deluxe version: Also avoid the argument/local clearing, asm-level + // register pushing etc. + // + // These are functions returning a constant, and doing nothing else. + MARK_AT(0) POP_TO_MARK INIT_FRAME RETURN_0 : RETURN_0 + MARK_AT(0) POP_TO_MARK INIT_FRAME UNDEFINED RETURN : UNDEFINED RETURN + MARK_AT(0) POP_TO_MARK INIT_FRAME RETURN_1 : RETURN_1 + MARK_AT(0) POP_TO_MARK INIT_FRAME NUMBER RETURN : NUMBER($4a) RETURN + MARK_AT(0) POP_TO_MARK INIT_FRAME STRING RETURN : STRING($4a) RETURN + MARK_AT(0) POP_TO_MARK INIT_FRAME CONSTANT RETURN : CONSTANT($4a) RETURN + MARK_AT(0) POP_TO_MARK INIT_FRAME NEG_NUMBER RETURN : NEG_NUMBER($4a) RETURN +    // Branches that jump to the next instruction   // Basic branches   BRANCH LABEL($1a) : LABEL($1a) - BRANCH_WHEN_ZERO LABEL($1a) : LABEL($1a) - BRANCH_WHEN_NON_ZERO LABEL($1a) : LABEL($1a) - BRANCH_WHEN_EQ LABEL($1a) : LABEL($1a) - BRANCH_WHEN_NE LABEL($1a) : LABEL($1a) - BRANCH_WHEN_LT LABEL($1a) : LABEL($1a) - BRANCH_WHEN_LE LABEL($1a) : LABEL($1a) - BRANCH_WHEN_GT LABEL($1a) : LABEL($1a) - BRANCH_WHEN_GE LABEL($1a) : LABEL($1a) + BRANCH_WHEN_ZERO LABEL($1a) : POP_VALUE LABEL($1a) + BRANCH_WHEN_NON_ZERO LABEL($1a) : POP_VALUE LABEL($1a) + BRANCH_WHEN_EQ LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a) + BRANCH_WHEN_NE LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a) + BRANCH_WHEN_LT LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a) + BRANCH_WHEN_LE LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a) + BRANCH_WHEN_GT LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a) + BRANCH_WHEN_GE LABEL($1a) : POP_VALUE POP_VALUE LABEL($1a)   // These variants use a POINTER   BRANCH_IF_NOT_LOCAL_ARROW POINTER LABEL ($2a) : LABEL($2a)   BRANCH_IF_LOCAL POINTER LABEL($2a) : LABEL($2a)   BRANCH_IF_NOT_LOCAL POINTER LABEL($2a) : LABEL($2a)      #define OPT_INCDEC(X) \   X##_LOCAL_AND_POP LOCAL ($1a) : X##_LOCAL ($1a) ; \   X##_LOCAL_AND_POP LOCAL LOCAL ($1a) : LOCAL($2a) X##_LOCAL ($1a) ; \   X##_LOCAL_AND_POP GLOBAL LOCAL ($1a) : GLOBAL($2a) X##_LOCAL ($1a) ;      OPT_INCDEC(INC)   OPT_INCDEC(DEC)      ASSIGN_LOCAL_AND_POP LOCAL($1a) : ASSIGN_LOCAL($1a)   ASSIGN_GLOBAL_AND_POP GLOBAL($1a) : ASSIGN_GLOBAL($1a) -  + CLEAR_LOCAL LOCAL($1a) : CLEAR_LOCAL($1a) CONST0 + #ifdef EAT_STACK   APPLY_ASSIGN_LOCAL_AND_POP LOCAL ($1b) : APPLY_ASSIGN_LOCAL($1a,$1b) -  + #endif    - DEC_LOCAL_AND_POP MARK_AND_LOCAL ($1a) : MARK DEC_LOCAL ($1a) - INC_LOCAL_AND_POP MARK_AND_LOCAL ($1a) : MARK INC_LOCAL ($1a) - ASSIGN_GLOBAL_AND_POP MARK GLOBAL($1a) : MARK_X(1) ASSIGN_GLOBAL($1a) - ASSIGN_LOCAL_AND_POP MARK_AND_LOCAL($1a) : MARK_X(1) ASSIGN_LOCAL($1a) + DEC_LOCAL_AND_POP MARK_AND_LOCAL ($1a) : DEC_LOCAL ($1a) MARK_X(1) + INC_LOCAL_AND_POP MARK_AND_LOCAL ($1a) : INC_LOCAL ($1a) MARK_X(1) + ASSIGN_GLOBAL_AND_POP MARK GLOBAL($1a) : ASSIGN_GLOBAL($1a) MARK_X(1) + ASSIGN_LOCAL_AND_POP MARK_AND_LOCAL($1a) : ASSIGN_LOCAL($1a) MARK_X(1) + ASSIGN_LOCAL_AND_POP NUMBER LOCAL($1a) : ASSIGN_LOCAL($1a) NUMBER($2a) SWAP + ASSIGN_LOCAL_AND_POP STRING LOCAL($1a) : ASSIGN_LOCAL($1a) STRING($2a) SWAP + ASSIGN_LOCAL_AND_POP MARK_AND_STRING LOCAL($1a) : ASSIGN_LOCAL($1a) STRING($2a) SWAP MARK_X(2) +  + #ifdef EAT_STACK   APPLY_ASSIGN_LOCAL_AND_POP MARK_AND_LOCAL ($1b) : APPLY_ASSIGN_LOCAL($1a,$1b) MARK_X(1) -  + #endif      ASSIGN_LOCAL ASSIGN_LOCAL($1a) : ASSIGN_LOCAL($1a)    -  + #if 0 + // The following set of rules attempt to push the mark toward the apply. + // The idea is to push it the entire way, to be able to have an apply + // opcode that contains the stack depth, and thus doesn't need the mark + // stack. +  + // MARK rules + MARK LOCAL : LOCAL($2a) MARK_X(1) + MARK STRING : STRING($2a) MARK_X(1) + MARK NUMBER : NUMBER($2a) MARK_X(1) + MARK CONST0 : CONST0 MARK_X(1) + MARK CONST1 : CONST1 MARK_X(1) + MARK CONST_1 : CONST_1 MARK_X(1) + MARK NEG_NUMBER : NEG_NUMBER($2a) MARK_X(1) + MARK GLOBAL : GLOBAL($2a) MARK_X(1) + MARK MARK_APPLY : MARK_APPLY($2a) MARK_X(1) + MARK CONSTANT : CONSTANT($2a) MARK_X(1) + //MARK FLOAT : FLOAT($2a) MARK_X(1) + MARK LFUN : LFUN($2a) MARK_X(1) + MARK LTOSVAL : LTOSVAL MARK_X(1) + MARK LOCAL_LVALUE : LOCAL_LVALUE($2a) MARK_X(2) + MARK 2_LOCALS : 2_LOCALS($2a,$2b) MARK_X(2) + MARK NEGATE : NEGATE MARK +    // MARK_X rules   MARK_X(0) : MARK -  + MARK_X LOCAL : LOCAL($2a) MARK_X($1a+1) + MARK_X STRING : STRING($2a) MARK_X($1a+1) + MARK_X NUMBER : NUMBER($2a) MARK_X($1a+1) + MARK_X CONST0 : CONST0 MARK_X($1a+1) + MARK_X CONST1 : CONST1 MARK_X($1a+1) + MARK_X CONST_1 : CONST_1 MARK_X($1a+1) + MARK_X NEG_NUMBER : NEG_NUMBER($2a) MARK_X($1a+1) + MARK_X GLOBAL : GLOBAL($2a) MARK_X($1a+1) + MARK_X MARK_APPLY : MARK_APPLY($2a) MARK_X($1a+1) + MARK_X CONSTANT : CONSTANT($2a) MARK_X($1a+1) + //MARK_X FLOAT : FLOAT($2a) MARK_X($1a+1) + MARK_X LFUN : LFUN($2a) MARK_X($1a+1) + MARK_X LTOSVAL : LTOSVAL MARK_X($1a+1) + MARK_X LOCAL_LVALUE : LOCAL_LVALUE($2a) MARK_X($1a+2) + MARK_X 2_LOCALS : 2_LOCALS($2a,$2b) MARK_X($1a+2) + MARK_X NEGATE : NEGATE MARK_X($1a) +  + #else /* !0 */ +  + // MARK_X rules + MARK_X(0) : MARK   LOCAL MARK_X [$2a>0] : MARK_X($2a-1) LOCAL($1a)   STRING MARK_X [$2a>0] : MARK_X($2a-1) STRING($1a)   NUMBER MARK_X [$2a>0] : MARK_X($2a-1) NUMBER($1a)   CONST0 MARK_X [$2a>0] : MARK_X($2a-1) CONST0   CONST1 MARK_X [$2a>0] : MARK_X($2a-1) CONST1   CONST_1 MARK_X [$2a>0] : MARK_X($2a-1) CONST_1   NEG_NUMBER MARK_X [$2a>0] : MARK_X($2a-1) NEG_NUMBER($1a)   GLOBAL MARK_X [$2a>0] : MARK_X($2a-1) GLOBAL($1a)   MARK_APPLY MARK_X [$2a>0] : MARK_X($2a-1) MARK_APPLY($1a)   CONSTANT MARK_X [$2a>0] : MARK_X($2a-1) CONSTANT($1a) - FLOAT MARK_X [$2a>0] : MARK_X($2a-1) FLOAT($1a) + //FLOAT MARK_X [$2a>0] : MARK_X($2a-1) FLOAT($1a)   LFUN MARK_X [$2a>0] : MARK_X($2a-1) LFUN($1a)   LTOSVAL MARK_X [$2a>0] : MARK_X($2a-1) LTOSVAL   LOCAL_LVALUE MARK_X [$2a>1] : MARK_X($2a-2) LOCAL_LVALUE($1a)   2_LOCALS MARK_X [$2a>0] : LOCAL($1a) MARK_X($2a-1) LOCAL($1b) -  + SWAP MARK_X : MARK_X($2a) SWAP + DUP MARK_X [$2a>0] : MARK_X($2a-1) DUP    -  + CONST_1 ASSIGN_LOCAL MARK_X [$3a>0] : MARK_X($3a-1) CONST_1 ASSIGN_LOCAL($2a) + CONST1 ASSIGN_LOCAL MARK_X [$3a>0] : MARK_X($3a-1) CONST1 ASSIGN_LOCAL($2a) + NUMBER ASSIGN_LOCAL MARK_X [$3a>0] : MARK_X($3a-1) NUMBER($1a) ASSIGN_LOCAL($2a) + NEG_NUMBER ASSIGN_LOCAL MARK_X [$3a>0] : MARK_X($3a-1) NEG_NUMBER($1a) ASSIGN_LOCAL($2a) +  + #endif /* 0 */ +  + MARK_X [$1a>0] POP_VALUE : POP_VALUE MARK_X($1a-1) + MARK_X POP_N_ELEMS [$1a >= $2a] : POP_N_ELEMS($2a) MARK_X($1a-$2a) +    #define BasicBranch2(Branch,Oper,Pre,Post,Variable) \    Variable Branch Pre Variable ($1a) : Variable ($1a) Oper ($2a) Post ; \    ASSIGN_##Variable Branch Pre Variable ($1a) : ASSIGN_##Variable($1a) Oper ($2a) Post ;      #define BasicBranch1(Branch,Oper,Pre,Post) \    BasicBranch2(Branch,Oper,Pre,Post,LOCAL) \    BasicBranch2(Branch,Oper,Pre,Post,GLOBAL)      #define BasicBranch0(Branch,Oper) \    BasicBranch1(Branch,Oper,MARK,MARK_X(1)) \
pike.git/src/peep.in:327:   SIZEOF CONST1 BRANCH_WHEN_LT : SIZEOF BRANCH_WHEN_ZERO ($3a)   SIZEOF_LOCAL CONST1 BRANCH_WHEN_LT : SIZEOF_LOCAL($1a) BRANCH_WHEN_ZERO ($3a)   SIZEOF CONST0 BRANCH_WHEN_LE : SIZEOF BRANCH_WHEN_ZERO ($3a)   SIZEOF_LOCAL CONST0 BRANCH_WHEN_LE : SIZEOF_LOCAL($1a) BRANCH_WHEN_ZERO ($3a)      CLEAR_LOCAL DEC_LOCAL_AND_POP($1a) : CONST_1 ASSIGN_LOCAL_AND_POP($1a)   CLEAR_LOCAL INC_LOCAL_AND_POP($1a) : CONST1 ASSIGN_LOCAL_AND_POP($1a)      NUMBER POP_VALUE :   STRING POP_VALUE : - FLOAT POP_VALUE : + //FLOAT POP_VALUE :   CONSTANT POP_VALUE :   LOCAL POP_VALUE :   IDENTIFIER POP_VALUE :   TRAMPOLINE POP_VALUE :    -  + RECUR RETURN [check_tailrecursion()] : TAIL_RECUR ($1a)    - RECUR RETURN: TAIL_RECUR ($1a) -  +    // This doesn't really work   // MARK TAIL_RECUR : BRANCH ($1a)      ASSIGN_LOCAL BRANCH_WHEN_ZERO 2_LOCALS(,$1a) BRANCH_WHEN_EQ : ASSIGN_LOCAL($1a) BRANCH_AND_POP_WHEN_ZERO($2a) LOCAL($3a) BRANCH_WHEN_EQ($4a)   ASSIGN_LOCAL BRANCH_WHEN_ZERO 2_LOCALS(,$1a) BRANCH_WHEN_NE : ASSIGN_LOCAL($1a) BRANCH_AND_POP_WHEN_ZERO($2a) LOCAL($3a) BRANCH_WHEN_NE($4a)      /* This will facilitate other optimizations I hope */   CLEAR_LOCAL MARK LOCAL [ $1a != $3a ] : MARK LOCAL($3a) CLEAR_LOCAL($1a)      /* The result of this optimization could be reordered... */   CLEAR_LOCAL MARK LOCAL($1a) : MARK CLEAR_LOCAL($1a) CONST0 -  +  +  +  + #define LOW_MKCALLOPTS(A) \ + A POP_VALUE: A##_AND_POP($1a); \ + A [ check_tailrecursion() ] RETURN : A##_AND_RETURN($1a) ; \ + A##_AND_RETURN ? DeadCodeEndCond($2o) : A##_AND_RETURN($1a) ; +  + #define MKCALLOPTS(A) \ + MARK A: MARK_##A($2a) ; \ + LOW_MKCALLOPTS(A); \ + LOW_MKCALLOPTS(MARK_##A); +  +  + MKCALLOPTS(APPLY) + MKCALLOPTS(CALL_LFUN) + MKCALLOPTS(CALL_BUILTIN) + // MARK CALL_FUNCTION doesn't make any sense... + LOW_MKCALLOPTS(CALL_FUNCTION) +  + // MARK CALL_OTHER doesn't make any sense either... + LOW_MKCALLOPTS(CALL_OTHER) +  + CALL_BUILTIN1 POP_VALUE : CALL_BUILTIN1_AND_POP ($1a) +  + LTOSVAL_CALL_BUILTIN_AND_ASSIGN POP_VALUE : LTOSVAL_CALL_BUILTIN_AND_ASSIGN_POP($1a) +  + #define OPT_TYPEP(X,Y) \ +  CALL_BUILTIN1 [ Pike_compiler->new_program->constants[$1a].sval.u.efun->function == X ] BRANCH_WHEN_ZERO : BRANCH_IF_TYPE_IS_NOT(Y) POINTER($2a); +  + #if 1 + OPT_TYPEP(f_intp, T_INT) + OPT_TYPEP(f_stringp, T_STRING) + OPT_TYPEP(f_arrayp, T_ARRAY) + OPT_TYPEP(f_floatp, T_FLOAT) + OPT_TYPEP(f_mappingp, T_MAPPING) + OPT_TYPEP(f_multisetp, T_MULTISET) + #endif +  + // Move lvalues up on the stack. + #define MOVE_LVAL(L_G1, L_G2) \ +  NUMBER ASSIGN_##L_G1##_AND_POP L_G2##_LVALUE: L_G2##_LVALUE($3a) NUMBER($1a) ASSIGN_##L_G1##_AND_POP($2a); \ +  NEG_NUMBER ASSIGN_##L_G1##_AND_POP L_G2##_LVALUE: L_G2##_LVALUE($3a) NEG_NUMBER($1a) ASSIGN_##L_G1##_AND_POP($2a); \ +  CONST1 ASSIGN_##L_G1##_AND_POP L_G2##_LVALUE: L_G2##_LVALUE($3a) CONST1 ASSIGN_##L_G1##_AND_POP($2a); \ +  CONST_1 ASSIGN_##L_G1##_AND_POP L_G2##_LVALUE: L_G2##_LVALUE($3a) CONST_1 ASSIGN_##L_G1##_AND_POP($2a); +  + MOVE_LVAL(LOCAL,LOCAL) + MOVE_LVAL(GLOBAL,LOCAL) + MOVE_LVAL(LOCAL,GLOBAL) + MOVE_LVAL(GLOBAL,GLOBAL) +  + CLEAR_LOCAL LOCAL_LVALUE: LOCAL_LVALUE($2a) CLEAR_LOCAL($1a) + CLEAR_LOCAL GLOBAL_LVALUE: GLOBAL_LVALUE($2a) CLEAR_LOCAL($1a) + CONST0 ASSIGN_GLOBAL_AND_POP LOCAL_LVALUE: LOCAL_LVALUE($3a) CONST0 ASSIGN_GLOBAL_AND_POP($2a) + CONST0 ASSIGN_GLOBAL_AND_POP GLOBAL_LVALUE: GLOBAL_LVALUE($3a) CONST0 ASSIGN_GLOBAL_AND_POP($2a) +  + GLOBAL_LVALUE CONST0 ASSIGN_GLOBAL_AND_POP($1a) INC_AND_POP : CONST1 ASSIGN_GLOBAL_AND_POP($1a) + GLOBAL_LVALUE CONST0 ASSIGN_GLOBAL_AND_POP($1a) DEC_AND_POP : CONST_1 ASSIGN_GLOBAL_AND_POP($1a) + GLOBAL_LVALUE CONST_1 ASSIGN_GLOBAL_AND_POP($1a) INC_AND_POP : CONST0 ASSIGN_GLOBAL_AND_POP($1a) + GLOBAL_LVALUE CONST1 ASSIGN_GLOBAL_AND_POP($1a) DEC_AND_POP : CONST0 ASSIGN_GLOBAL_AND_POP($1a) + GLOBAL_LVALUE NUMBER ASSIGN_GLOBAL_AND_POP($1a) INC_AND_POP : NUMBER($2a) ADD_INT(1) ASSIGN_GLOBAL_AND_POP($1a) + GLOBAL_LVALUE NUMBER ASSIGN_GLOBAL_AND_POP($1a) DEC_AND_POP : NUMBER($2a) ADD_NEG_INT(1) ASSIGN_GLOBAL_AND_POP($1a) + GLOBAL_LVALUE NEG_NUMBER ASSIGN_GLOBAL_AND_POP($1a) INC_AND_POP : NEG_NUMBER($2a) ADD_INT(1) ASSIGN_GLOBAL_AND_POP($1a) + GLOBAL_LVALUE NEG_NUMBER ASSIGN_GLOBAL_AND_POP($1a) DEC_AND_POP : NEG_NUMBER($2a) ADD_NEG_INT(1) ASSIGN_GLOBAL_AND_POP($1a) +  + // Move marks to where they're relevant. + MARK CLEAR_LOCAL: CLEAR_LOCAL($2a) MARK + MARK ASSIGN_LOCAL_NUMBER_AND_POP: ASSIGN_LOCAL_NUMBER_AND_POP($2a,$2b) MARK + MARK ASSIGN_GLOBAL_NUMBER_AND_POP: ASSIGN_GLOBAL_NUMBER_AND_POP($2a,$2b) MARK + MARK NEG_NUMBER ASSIGN_LOCAL_AND_POP: NEG_NUMBER($2a) ASSIGN_LOCAL_AND_POP($3a) MARK + MARK NEG_NUMBER ASSIGN_GLOBAL_AND_POP: NEG_NUMBER($2a) ASSIGN_GLOBAL_AND_POP($3a) MARK + MARK_AND_CONST1 ASSIGN_LOCAL_AND_POP: CONST1 ASSIGN_LOCAL_AND_POP($3a) MARK + MARK_AND_CONST1 ASSIGN_GLOBAL_AND_POP: CONST1 ASSIGN_GLOBAL_AND_POP($3a) MARK + MARK CONST_1 ASSIGN_LOCAL_AND_POP: CONST_1 ASSIGN_LOCAL_AND_POP($3a) MARK + MARK CONST_1 ASSIGN_GLOBAL_AND_POP: CONST_1 ASSIGN_GLOBAL_AND_POP($3a) MARK +  + CONST_1 COMPL : CONST0 + CONST_1 ASSIGN_LOCAL COMPL : CONST_1 ASSIGN_LOCAL_AND_POP($2a) CONST0 + CONST_1 ASSIGN_GLOBAL COMPL : CONST_1 ASSIGN_GLOBAL_AND_POP($2a) CONST0 +  + CONST0 COMPL : CONST_1 + CONST0 ASSIGN_LOCAL COMPL : CLEAR_LOCAL($2a) CONST_1 + CONST0 ASSIGN_GLOBAL COMPL : CONST0 ASSIGN_GLOBAL_AND_POP($2a) CONST_1