Changeset 312 in svn for trunk/optimizer.c


Ignore:
Timestamp:
2006-12-09T17:28:25+01:00 (8 years ago)
Author:
Xuefer
Message:

optimizer: finished building of basic blocks

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/optimizer.c

    r308 r312  
    1 #if 1
     1#if 0
    22#define DEBUG
    33#endif
     
    2929    bbid_t     jmpout_op2;
    3030    bbid_t     jmpout_ext;
    31     bbid_t     follow;
     31    bbid_t     fall;
    3232} bb_t;
    3333/* }}} */
     
    102102}
    103103/* }}} */
    104 static int op_get_jmpout(bb_t *bb, zend_op *opcodes, zend_op *opline) /* {{{ */
    105 {
    106     /* break=have follow */
     104static int op_get_jmpout(int *jmpout_op1, int *jmpout_op2, int *jmpout_ext, zend_bool *fall, zend_op *opline) /* {{{ */
     105{
     106    /* break=will fall */
    107107    switch (opline->opcode) {
    108108    case ZEND_RETURN:
    109109    case ZEND_EXIT:
    110         break;
     110        return SUCCESS; /* no fall */
    111111
    112112    case ZEND_JMP:
    113         bb->jmpout_op1 = opline->op1.u.opline_num;
    114         return SUCCESS; /* no follow */
     113        *jmpout_op1 = opline->op1.u.opline_num;
     114        return SUCCESS; /* no fall */
    115115
    116116    case ZEND_JMPZNZ:
    117         bb->jmpout_ext = opline->extended_value;
    118         bb->jmpout_op2 = opline->op2.u.opline_num;
     117        *jmpout_ext = opline->extended_value;
     118        *jmpout_op2 = opline->op2.u.opline_num;
    119119        break;
    120120
     
    131131#endif     
    132132    case ZEND_FE_FETCH:
    133         bb->jmpout_op2 = opline->op2.u.opline_num;
     133        *jmpout_op2 = opline->op2.u.opline_num;
    134134        break;
    135135
     
    138138    }
    139139
     140    *fall = 1;
    140141    return SUCCESS;
    141142}
     
    153154    bb->jmpout_op2 = BBID_INVALID;
    154155    bb->jmpout_ext = BBID_INVALID;
    155     bb->follow     = BBID_INVALID;
     156    bb->fall       = BBID_INVALID;
    156157
    157158    if (opcodes) {
     
    178179}
    179180/* }}} */
     181#ifdef DEBUG
     182static void bb_print(bb_t *bb, zend_op *opcodes) /* {{{ */
     183{
     184    fprintf(stderr,
     185            "%3d %3d %3d"
     186            " %c%c"
     187            " %3d %3d %3d %3d\r\n"
     188            , bb->id, bb->count, bb->opcodes - opcodes
     189            , bb->used ? 'U' : ' ', bb->alloc ? 'A' : ' '
     190            , bb->jmpout_op1, bb->jmpout_op2, bb->jmpout_ext, bb->fall
     191            );
     192}
     193/* }}} */
     194#endif
     195
    180196#define bbs_get(bbs, n) xc_stack_get(bbs, n)
    181197static void bbs_destroy(bbs_t *bbs) /* {{{ */
     
    188204}
    189205/* }}} */
     206#ifdef DEBUG
     207static void bbs_print(bbs_t *bbs, zend_op *opcodes) /* {{{ */
     208{
     209    int i;
     210    for (i = 0; i < xc_stack_count(bbs); i ++) {
     211        bb_print(bbs_get(bbs, i), opcodes);
     212    }
     213}
     214/* }}} */
     215#endif
    190216#define bbs_init(bbs) xc_stack_init_ex(bbs, 16)
    191217static bb_t *bbs_add_bb(bbs_t *bbs, bb_t *bb) /* {{{ */
     
    204230{
    205231    int i, prev;
    206     bb_t bb, *pbb;
    207     zend_bool *markjmpins  = do_alloca(count);
    208     zend_bool *markjmpouts = do_alloca(count);
    209 
    210     memset(markjmpins,  0, sizeof(zend_bool));
    211     memset(markjmpouts, 0, sizeof(zend_bool));
     232    bb_t *pbb;
     233    bbid_t id;
     234    int jmpout_op1, jmpout_op2, jmpout_ext;
     235    zend_bool fall;
     236    bbid_t *bbids          = do_alloca(count * sizeof(bbid_t));
     237    zend_bool *markjmpins  = do_alloca(count * sizeof(zend_bool));
     238    zend_bool *markjmpouts = do_alloca(count * sizeof(zend_bool));
     239
     240    /* {{{ mark jmpin/jumpout */
     241    memset(markjmpins,  0, count * sizeof(zend_bool));
     242    memset(markjmpouts, 0, count * sizeof(zend_bool));
    212243
    213244    for (i = 0; i < count; i ++) {
    214         /* BBID_INVALID=invalidate line
    215          * bb.jmpout_op1 bb.jmpout_op2 bb.jmpout_ext bb.follow means opline number here, not basicblock id
    216          */
    217         bb.jmpout_op1 = bb.jmpout_op2 = BBID_INVALID;
    218         bb.jmpout_ext = bb.follow     = BBID_INVALID;
    219         if (op_get_jmpout(&bb, opcodes, &opcodes[i]) == SUCCESS) {
     245        jmpout_op1 = jmpout_op2 = jmpout_ext = -1;
     246        fall = 0;
     247        if (op_get_jmpout(&jmpout_op1, &jmpout_op2, &jmpout_ext, &fall, &opcodes[i]) == SUCCESS) {
    220248            markjmpouts[i] = 1;
    221249
    222             if (bb.jmpout_op1 != BBID_INVALID) {
    223                 markjmpins[bb.jmpout_op1] = 1;
    224             }
    225             if (bb.jmpout_op2 != BBID_INVALID) {
    226                 markjmpins[bb.jmpout_op2] = 1;
    227             }
    228             if (bb.jmpout_ext != BBID_INVALID) {
    229                 markjmpins[bb.jmpout_ext] = 1;
    230             }
    231 
    232             if (i < count && bb.follow != BBID_INVALID) {
    233                 markjmpins[i + 1] = 1;
    234             }
    235         }
     250            if (jmpout_op1 != -1) {
     251                markjmpins[jmpout_op1] = 1;
     252            }
     253            if (jmpout_op2 != -1) {
     254                markjmpins[jmpout_op2] = 1;
     255            }
     256            if (jmpout_ext != -1) {
     257                markjmpins[jmpout_ext] = 1;
     258            }
     259        }
     260    }
     261    /* }}} */
     262    /* {{{ fill opcodes with newly allocated id */
     263    for (i = 0; i < count; i ++) {
     264        bbids[i] = BBID_INVALID;
    236265    }
    237266
    238267    prev = 0;
     268    id = 0;
    239269    for (i = 1; i < count; i ++) {
    240         if (markjmpins[i]) {
    241             pbb = bbs_new_bb_ex(bbs, opcodes + prev, i - prev);
    242             op_get_jmpout(pbb, opcodes, &opcodes[prev]);
     270        if (markjmpins[i] || markjmpouts[i - 1]) {
     271            for (; prev < i; prev ++) {
     272                bbids[prev] = id;
     273            }
     274            id ++;
    243275            prev = i;
    244276        }
    245277    }
    246278
    247     if (prev != count - 1) {
    248         pbb = bbs_new_bb_ex(bbs, opcodes + prev, count - prev);
    249     }
    250 
     279    if (prev < count) {
     280        for (; prev < i; prev ++) {
     281            bbids[prev] = id;
     282        }
     283    }
     284    /* }}} */
     285    /* {{{ create basic blocks */
     286    prev = 0;
     287    id = 0;
     288    for (i = 1; i < count; i ++) {
     289        if (id == bbids[i]) {
     290            continue;
     291        }
     292        id = bbids[i];
     293
     294        pbb = bbs_new_bb_ex(bbs, opcodes + prev, i - prev);
     295        jmpout_op1 = jmpout_op2 = jmpout_ext = -1;
     296        fall = 0;
     297        if (op_get_jmpout(&jmpout_op1, &jmpout_op2, &jmpout_ext, &fall, &opcodes[prev]) == SUCCESS) {
     298            if (jmpout_op1 != -1) {
     299                pbb->jmpout_op1 = bbids[jmpout_op1];
     300                assert(pbb->jmpout_op1 != BBID_INVALID);
     301            }
     302            if (jmpout_op2 != -1) {
     303                pbb->jmpout_op2 = bbids[jmpout_op2];
     304                assert(pbb->jmpout_op2 != BBID_INVALID);
     305            }
     306            if (jmpout_ext != -1) {
     307                pbb->jmpout_ext = bbids[jmpout_ext];
     308                assert(pbb->jmpout_ext != BBID_INVALID);
     309            }
     310            if (fall && i + 1 < count) {
     311                pbb->fall = bbids[i + 1];
     312                assert(pbb->fall != BBID_INVALID);
     313            }
     314        }
     315        prev = i + 1;
     316    }
     317    assert(prev == count);
     318    /* }}} */
     319
     320    free_alloca(bbids);
     321    free_alloca(markjmpins);
     322    free_alloca(markjmpouts);
    251323    return SUCCESS;
    252324}
     
    265337    xc_undo_pass_two(op_array TSRMLS_CC);
    266338#ifdef DEBUG
     339#   if 0
    267340    TRACE("optimize file: %s", op_array->filename);
    268341    xc_dprint_zend_op_array(op_array, 0 TSRMLS_CC);
    269 #endif
    270 
    271     if (op_array_convert_switch(op_array)) {
     342#   endif
     343#endif
     344
     345    if (op_array_convert_switch(op_array) == SUCCESS) {
    272346        bbs_init(&bbs);
    273         if (bbs_build_from(&bbs, op_array->opcodes, op_array->last)) {
     347        if (bbs_build_from(&bbs, op_array->opcodes, op_array->last) == SUCCESS) {
     348#ifdef DEBUG
     349            bbs_print(&bbs, op_array->opcodes);
     350#endif
    274351        }
    275352        bbs_destroy(&bbs);
     
    277354
    278355#ifdef DEBUG
     356#   if 0
    279357    TRACE("%s", "after compiles");
    280358    xc_dprint_zend_op_array(op_array, 0 TSRMLS_CC);
     359#   endif
    281360#endif
    282361    xc_redo_pass_two(op_array TSRMLS_CC);
Note: See TracChangeset for help on using the changeset viewer.