insutil.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 492 行 · 第 1/2 页

C
492
字号
                    if( conf->ins_range.first == ins ) {
                        conf->ins_range.first = pref;
                    }
                }
            }
        }

    /*   Set up the state for both instructions*/

        ins->head.state = INS_NEEDS_WORK;
        pref->head.state = INS_NEEDS_WORK;

    /*   Add live & conflict information for the new instruction*/

        UpdateLive( pref, ins );
    }
}


extern  void    PrefixIns( instruction *ins, instruction *pref ) {
/****************************************************************/

    PrefixInsRenum( ins, pref, TRUE );
}


extern  void    SuffixIns( instruction *ins, instruction *suff ) {
/****************************************************************/

/*   Link the new instruction into the instruction ring*/

    conflict_info       *info;
    conflict_node       *conf;

    suff->head.next = ins->head.next;
    suff->head.next->head.prev = suff;
    suff->head.prev = ins;
    ins->head.next = suff;
    suff->head.line_num = 0;
    _INS_NOT_BLOCK( suff );
    /*
     * A little dirty, but check of OP_BLOCK can be skipped - in this case
     * we'll just Renumber() everything from scratch.
     */
    /* _INS_NOT_BLOCK( ins ); */
    suff->id = ins->id;
    if( ins->head.opcode == OP_NOP ) {
        /* get rid of the little bugger so it doesn't mess up our optimizing */
        if( ins->flags.nop_flags & NOP_SOURCE_QUEUE ) {
            /* transfer the line_num info to the next instruction */
            suff->head.line_num = ins->head.line_num;
            ins = ins->head.prev;
            FreeIns( ins->head.next );
        }
    }
    if( ins->head.opcode != OP_BLOCK ) {
        suff->stk_entry = ins->stk_exit;
        suff->stk_exit = ins->stk_exit;
        // suff->s.stk_extra = ins->s.stk_extra;
        suff->sequence = ins->sequence;
    }
    RenumFrom( ins );
    if( HaveLiveInfo ) {

/*      move the first/last pointers of any relevant conflict nodes */

        if( ins->head.opcode != OP_BLOCK ) {
            MakeConflictInfo( ins, suff );
            for( info = ConflictInfo; info->conf != NULL; ++info ) {
                if( info->flags & CB_FOR_INS2 ) {
                    conf = info->conf;
                    if( !( info->flags & CB_FOR_INS1 ) ) {
                        if( conf->ins_range.first == ins ) {
                            conf->ins_range.first = suff;
                        }
                    }
                    if( conf->ins_range.last == ins ) {
                        conf->ins_range.last = suff;
                    }
                }
            }
        }

    /*   Set up the state for both instructions*/

        ins->head.state = INS_NEEDS_WORK;
        suff->head.state = INS_NEEDS_WORK;
        UpdateLive( ins, suff );
    }
}


static  block   *GetBlockPointer( block *blk, instruction *ins ) {
/****************************************************************/

    if( blk != NULL ) return( blk );
    while( ins->head.opcode != OP_BLOCK ) {
        ins = ins->head.next;
    }
    return( _BLOCK( ins ) );
}


extern  void    ReplIns( instruction *ins, instruction *new ) {
/*************************************************************/

    block               *blk;
    conflict_info       *info;
    conflict_node       *conf;


/*   Move conflict information to the new instruction*/

/*   Link the new instruction into the instruction ring*/
/*   (It will be removed by FreeIns() )*/

    new->head.next = ins->head.next;
    new->head.next->head.prev = new;
    new->head.prev = ins;
    ins->head.next = new;
    new->stk_entry = ins->stk_entry;
    new->stk_exit = ins->stk_exit;
    // new->s.stk_extra = ins->s.stk_extra;
    new->sequence = ins->sequence;

    _INS_NOT_BLOCK( new );
    _INS_NOT_BLOCK( ins );
    new->head.line_num = ins->head.line_num;
    new->id = ins->id;
    new->head.state = INS_NEEDS_WORK;
    blk = NULL;
    if( HaveLiveInfo ) {

/*  Copy the live analysis information from ins to new*/

        new->head.live.regs         = ins->head.live.regs;
        new->head.live.within_block = ins->head.live.within_block;
        new->head.live.out_of_block = ins->head.live.out_of_block;

/*      move the first/last pointers of any relevant conflict nodes */

/*
 * !!! BUG BUG !!!
 * Moving/changing egde of conflict with CONFLICT_ON_HOLD flag set
 * to non-conflicting instruction can cause famous bug 352. If new instruction
 * should be also replaced, codegen will not notice that it's a part of
 * any conflict and will not update egde. Event worse, if replaced instruction
 * is replaced again, this case will be completely missed by conflict manager.
 * At least, compiler can Zoiks now.
 *
 * This problem may also exist in other instruction modification functions.
 * It must be fixed in more correct way if somebody ever understand
 * how all this stuff works.
 */
        MakeConflictInfo( ins, new );
        for( info = ConflictInfo; info->conf != NULL; ++info ) {
            if( info->flags & CB_FOR_INS1 ) {
                conf = info->conf;
                if( conf->ins_range.first == ins ) {
                    conf->ins_range.first = new;
                }
                if( conf->ins_range.last == ins ) {
                    conf->ins_range.last = new;
                }
                if( info->flags & CB_FOR_INS2 ) continue;
                if( conf->ins_range.first == new ) {
                    blk = GetBlockPointer( blk, ins );
                    conf->ins_range.first = blk->ins.hd.prev;
                }
                if( conf->ins_range.last == new ) {
                    blk = GetBlockPointer( blk, ins );
                    conf->ins_range.last = blk->ins.hd.next; /* 89-08-16 */
                    if( blk->ins.hd.next == ins ) {
                        // oops - grasping for a straw and caught hold of
                        // ins (which is about to be deleted)
                        conf->ins_range.last = blk->ins.hd.next->head.next;
                    }
                }
            }
        }
    }

/*  Free up the old instruction */

    FreeIns( ins );

/*  if we wrecked a conflicts first or last pointer */

    if( blk != NULL ) { /* moved here 89-08-16 */
        UpdateLive( blk->ins.hd.next, blk->ins.hd.prev );
    }
}


extern  instruction_id  Renumber( void )
/**************************************/
{
    block               *blk;
    instruction         *ins;
    instruction_id      id;
    instruction_id      increment;
    unsigned_32         number_instrs;

    number_instrs = 0;
    blk = HeadBlock;
    while( blk != NULL ) {
        number_instrs += CountIns( blk );
        blk = blk->next_block;
    }
    if( number_instrs == 0 ) {
        increment = 1;
    } else if( number_instrs > MAX_INS_ID ) {
        _Zoiks( ZOIKS_069 );
        increment = 1;
    } else {
        increment = 10; // BBB - tired of stupid looking ins id's
    }
    id = 0;
    blk = HeadBlock;
    while( blk != NULL ) {
        ins = blk->ins.hd.next;
        while( ins->head.opcode != OP_BLOCK ) {
            ins->id = id;
            id += increment;
            ins = ins->head.next;
        }
        blk = blk->next_block;
    }
    return( id );
}


extern  void            ClearInsBits( instruction_flags mask ) {
/**************************************************************/

    block               *blk;
    instruction         *ins;

    mask = ~mask;
    for( blk = HeadBlock; blk != NULL; blk = blk->next_block ) {
        for( ins = blk->ins.hd.next; ins->head.opcode != OP_BLOCK; ins = ins->head.next ) {
            ins->ins_flags &= mask;
        }
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?