makeblk.c

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

C
605
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Block creation and destruction functions.
*
****************************************************************************/


#include "standard.h"
#include "cgdefs.h"
#include "model.h"
#include "coderep.h"
#include "procdef.h"
#include "sysmacro.h"
#include "opcodes.h"
#include "addrname.h"
#include "cgaux.h"
#include "zoiks.h"
#include "feprotos.h"
#include <string.h>

extern  void            CGFree(pointer);
extern  void            FreeIns(instruction*);
extern  void            TellBeginExecutions(void);
extern  void            FreeNames(void);
extern  int             AskDisplaySize(int);
extern  void            ReInitNames(void);
extern  label_handle    AskForNewLabel(void);
extern  type_class_def  CallState(aux_handle,type_def*,call_state*);
extern  name    *       AllocMemory(pointer,type_length,cg_class,type_class_def);
extern  type_class_def  TypeClass(type_def*);
extern  sym_handle      AskForLblSym(label_handle);
extern  byte    *       Copy(void*,void*,uint);
extern  void            NamesCrossBlocks(void);
extern  void            RemoveInputEdge(block_edge*);
extern  pointer         SafeRecurse( pointer (* rtn)(), pointer arg );
extern  void            SaveToTargProc(void);
extern  void            RestoreFromTargProc(void);
extern  void            InitTargProc(void);
extern  instruction*    MakeNop(void);


extern    bool                  BlocksUnTrimmed;
extern    block                 *HeadBlock;
extern    block                 *BlockList;
extern    int                   InsId;
extern    type_length           MaxStack;
extern    source_line_number    SrcLine;
extern    name                  *Names[];
extern    name                  *LastTemp;
extern    name                  *DummyIndex;
extern    bool                  BlockByBlock;
extern    bool                  HaveCurrBlock;

proc_def              *CurrProc;
block                 *CurrBlock;


extern  block   *MakeBlock( label_handle label, block_num edges )
/***************************************************************/
{
    block       *blk;
    block_edge  *edge;
    block_num   i;

    _Alloc( blk, sizeof( block ) + (edges-1)*sizeof( block_edge ) );
    blk->next_block = NULL;
    blk->prev_block = NULL;
    blk->label = label;
    blk->class = EMPTY;
    blk->ins.hd.next = (instruction *)&blk->ins;
    blk->ins.hd.prev = (instruction *)&blk->ins;
    blk->ins.hd.opcode = OP_BLOCK;
    HW_CAsgn( blk->ins.hd.live.regs, HW_EMPTY );
    _LBitInit( blk->ins.hd.live.within_block, EMPTY );
    _GBitInit( blk->ins.hd.live.out_of_block, EMPTY );
    blk->ins.blk = blk;
    blk->u.interval = NULL;
    blk->inputs = 0;
    blk->input_edges = NULL;
    blk->targets = 0;
    blk->dataflow = NULL;
    blk->cc = NULL;
    blk->loop_head = NULL;
    blk->unroll_count = 0;
    blk->stack_depth = 0;
    blk->depth = 0;
    _DBitInit( blk->dom.id, 0 );
    for( i = 0; i < edges; i++ ) {
        edge = &blk->edge[ i ];
        edge->source = blk;
    }
    return( blk );
}


extern  block   *NewBlock( label_handle label, bool label_dies )
/**************************************************************/
{
    block       *blk;

    blk = MakeBlock( label, 1 );
    if( label_dies ) {
        blk->edge[ 0 ].flags = BLOCK_LABEL_DIES;
    } else {
        blk->edge[ 0 ].flags = 0;
    }
    return( blk );
}


extern  void    FreeABlock( block * blk )
/***************************************/
{
    if( blk->targets <= 1 ) {
        _Free( blk, sizeof( block ) );
    } else {
        _Free( blk, sizeof( block ) + (blk->targets-1) * sizeof( block_edge ) );
    }
}


extern  void    FreeBlock( void )
/*******************************/
{
    while( CurrBlock->ins.hd.next != (instruction *)&CurrBlock->ins ) {
        FreeIns( CurrBlock->ins.hd.next );
    }
    if( CurrBlock->dataflow != NULL ) {
        _Free( CurrBlock->dataflow, sizeof( data_flow_def ) );
    }
    FreeABlock( CurrBlock );
}


extern  void    EnLink( label_handle label, bool label_dies )
/***********************************************************/
{
    block       *blk;

    blk = NewBlock( label, label_dies );
    blk->ins.hd.line_num = SrcLine;
    CurrBlock = blk;
    SrcLine = 0;
}

extern  void    AddIns( instruction *ins )
/****************************************/
{
    if( HaveCurrBlock == FALSE ) {
        EnLink( AskForNewLabel(), TRUE );
        HaveCurrBlock = TRUE;
    }
    ins->head.next = (instruction *)&CurrBlock->ins;
    ins->head.prev = CurrBlock->ins.hd.prev;
    CurrBlock->ins.hd.prev->head.next = ins;
    CurrBlock->ins.hd.prev = ins;
    ins->head.line_num = SrcLine;
    _INS_NOT_BLOCK( ins );
    ins->id = ++ InsId;
    SrcLine = 0;
}


extern  void    GenBlock( int class, int targets )
/************************************************/
{
    block       *new;
    block_edge  *edge;
    instruction *ins;

    NamesCrossBlocks();
    if( HeadBlock == NULL ) {
        HeadBlock = CurrBlock;
        CurrBlock->id = 1;
        CurrBlock->gen_id = 1;
    } else {
        BlockList->next_block = CurrBlock;
        CurrBlock->id = BlockList->id + 1;
        CurrBlock->gen_id = BlockList->gen_id + 1;
    }
    if( SrcLine != 0 ) {
        /* Add an instruction to carry the line number for the block ending
           opcode (the AddIns code puts in line number automatically). */
        ins = MakeNop();
        ins->flags.nop_flags |= NOP_SOURCE_QUEUE;
        AddIns( ins );
    }
    CurrBlock->prev_block = BlockList;
    BlockList = CurrBlock;
    CurrBlock->next_block = NULL;
    if( targets > 1 ) {
        _Alloc( new, sizeof( block ) + (targets-1) * sizeof( block_edge ) );
        Copy( CurrBlock, new, sizeof( block ) );
        if( CurrBlock->ins.hd.next == (instruction *)&CurrBlock->ins ) {
            new->ins.hd.next = (instruction *)&new->ins;
            new->ins.hd.prev = (instruction *)&new->ins;
        } else {
            new->ins.hd.next->head.prev = (instruction *)&new->ins;
            new->ins.hd.prev->head.next = (instruction *)&new->ins;
        }
        new->ins.blk = new;

        /*   Move all references to CurrBlock*/

        if( HeadBlock == CurrBlock ) {
            HeadBlock = new;
        }
        if( BlockList == CurrBlock ) {
            BlockList = new;
        }
        if( new->prev_block != NULL ) {
            new->prev_block->next_block = new;
        }
        if( new->next_block != NULL ) {
            new->next_block->prev_block = new;
        }
        edge = new->input_edges;
        while( edge != NULL ) {
            edge->destination = new;
            edge = edge->next_source;
        }
        _Free( CurrBlock, sizeof( block ) );
        CurrBlock = new;
    }
    CurrBlock->class &= BIG_LABEL;   /* the only one that sticks*/
    CurrBlock->class |= class;
    while( --targets >= 1 ) {
        CurrBlock->edge[ targets ].flags = 0;
    }
}


extern  block   *ReGenBlock( block *blk, label_handle lbl )
/*********************************************************/
{
    block       *new;
    block_edge  *edge;
    int         targets;

    targets = blk->targets + 1;
    _Alloc( new, sizeof( block ) + (targets-1) * sizeof( block_edge ) );
    Copy( blk, new, sizeof( block ) + ( targets - 2 ) * sizeof( block_edge ) );
    new->edge[ targets-1 ].destination = lbl;
    new->edge[ targets-1 ].flags = 0;
    new->targets = targets;

    /*   Move all references to blk*/

    if( blk->ins.hd.next == (instruction *)&blk->ins ) {
        new->ins.hd.next = (instruction *)&new->ins;
        new->ins.hd.prev = (instruction *)&new->ins;
    } else {
        blk->ins.hd.next->head.prev = (instruction *)&new->ins;
        blk->ins.hd.prev->head.next = (instruction *)&new->ins;
    }
    while( --targets >= 0 ) {
        new->edge[ targets ].source = new;
    }
    new->ins.blk = new;
    if( HeadBlock == blk ) {
        HeadBlock = new;
    }
    if( BlockList == blk ) {
        BlockList = new;
    }
    if( new->prev_block != NULL ) {
        new->prev_block->next_block = new;
    }
    if( new->next_block != NULL ) {
        new->next_block->prev_block = new;
    }
    edge = new->input_edges;
    while( edge != NULL ) {
        edge->destination = new;
        edge = edge->next_source;
    }
    FreeABlock( blk );
    return( new );
}

⌨️ 快捷键说明

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