cgio.c

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

C
817
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "plusplus.h"
#include "errdefns.h"
#include "cgio.h"
#include "memmgr.h"
#include "ring.h"
#include "cgiobuff.h"
#include "carve.h"
#include "initdefs.h"
#include "stringl.h"
#include "conpool.h"
#include "pcheader.h"
#include "icodes.h"
#include "ioptypes.h"
#include "stats.h"
#include "module.h"

static CGFILE *cg_file_ring;    // ring of virtual files (live)
static CGFILE *cg_thunk_ring;   // ring of virtual thunks (live)
static CGFILE *cg_file_removed; // ring of virtual files (removed)
static carve_t carveCGFILE;
static carve_t carveCGFILE_GEN;

ExtraRptCtr( cgio_write_ins );
ExtraRptCtr( cgio_write_nul );
ExtraRptCtr( cgio_files );
ExtraRptCtr( cgio_locates_front );      // front end
ExtraRptCtr( cgio_comps_front );
ExtraRptCtr( cgio_locates_callgr );     // call graph
ExtraRptCtr( cgio_comps_callgr );
ExtraRptCtr( cgio_locates );            // back end
ExtraRptCtr( cgio_comps );
ExtraRptCtr( cgio_locates_thunk );


#ifndef NDEBUG

    #include "dbg.h"
    #include "pragdefn.h"

    static void _dump( CGFILE* cgfile, const char* prefix )
    {
        if( PragDbgToggle.callgraph ) {
            printf( "Cgio: %x %s - %s\n"
                  , cgfile
                  , prefix
                  , DbgSymNameFull( cgfile->symbol ) );
        }
    }

    static void _dumpRing( CGFILE* ring, char const * msg )
    {
        if( NULL != ring ) {
            CGFILE* curr;
            printf( "\n%s\n", msg );
            RingIterBeg( ring, curr ) {
                printf( "\nCGFILE[%x] %s\n"
                        "     first[%x] offset[%x] buffer[%x] cursor[%x]"
                        " cond_flags(%d)\n"
                        "     delayed(%d) refed(%d) stgen(%d)"
                        " oe_inl(%d) state_table(%d) once_inl(%d)\n"
                        "     done(%d) thunk(%d) thunk_gen(%d) not_inline(%d)"
                        " calls_inline(%d) can_throw(%d)\n"
                        "     stab_gen(%d) ctor_test(%d) write_to_pch(%d)\n"
                      , curr
                      , DbgSymNameFull( curr->symbol )
                      , curr->first
                      , curr->offset
                      , curr->buffer
                      , curr->cursor
                      , curr->cond_flags
                      , curr->delayed
                      , curr->refed
                      , curr->stgen
                      , curr->oe_inl
                      , curr->state_table
                      , curr->once_inl
                      , curr->done
                      , curr->thunk
                      , curr->thunk_gen
                      , curr->not_inline
                      , curr->calls_inline
                      , curr->can_throw
                      , curr->stab_gen
                      , curr->ctor_test
                      , curr->write_to_pch
                      );
            } RingIterEnd( curr )
        }
    }

    void CgFileDump( void )
    {
        _dumpRing( cg_file_ring, "Live Virtual Files" );
        _dumpRing( cg_thunk_ring, "Live Virtual Thunks" );
        _dumpRing( cg_file_removed, "Removed Virtual Files" );
    }

#else

    #define _dump(a,b)

#endif


static void cgioInit(           // INITIALIZE FOR CG-IO
    INITFINI* defn )
{
    defn = defn;
    cg_file_ring = NULL;
    cg_thunk_ring = NULL;
    cg_file_removed = NULL;
    CgioBuffInit();
    carveCGFILE = CarveCreate( sizeof( CGFILE ), 64 );
    carveCGFILE_GEN = CarveCreate( sizeof( CGFILE_GEN ), 32 );
    ExtraRptRegisterCtr( &cgio_files, "intermediate code files" );
    ExtraRptRegisterCtr( &cgio_locates_front
                       , "IC file locates (front-end)" );
    ExtraRptRegisterCtr( &cgio_comps_front
                       , "IC file locate comparisons (front-end)" );
    ExtraRptRegisterAvg( &cgio_comps_front
                       , &cgio_locates_front
                       , "average # comparisons per IC file locate (front-end)" );
    ExtraRptRegisterCtr( &cgio_locates_callgr
                       , "IC file locates (call-graph)" );
    ExtraRptRegisterCtr( &cgio_comps_callgr
                       , "IC file locate comparisons (call-graph)" );
    ExtraRptRegisterAvg( &cgio_comps_callgr
                       , &cgio_locates_callgr
                       , "average # comparisons per IC file locate (call-graph)" );
    ExtraRptRegisterCtr( &cgio_locates
                       , "IC file locates (back-end)" );
    ExtraRptRegisterCtr( &cgio_comps
                       , "IC file locate comparisons (back-end)" );
    ExtraRptRegisterAvg( &cgio_comps
                       , &cgio_locates
                       , "average # comparisons per IC file locate (back-end)" );
    ExtraRptRegisterCtr( &cgio_locates_thunk
                       , "IC file locates (back-end) thunks" );
    ExtraRptRegisterCtr( &cgio_write_ins, "# ICs written" );
    ExtraRptRegisterCtr( &cgio_write_nul, "# ICs written with NUL operands" );
}


static void cgioFini(           // FINALIZE FOR CG-IO
    INITFINI* defn )
{
    defn = defn;
    CgioBuffFini();
    CarveDestroy( carveCGFILE );
    CarveDestroy( carveCGFILE_GEN );
}


INITDEFN( cgio, cgioInit, cgioFini )


static CGFILE* lookupFile(      // DO A FILE LOOKUP FOR A SYMBOL, RING
    SYMBOL sym,                 // - symbol
    CGFILE* ring )              // - ring of symbols
{
    CGFILE *curr;               // - current CGFILE

    RingIterBeg( ring, curr ) {
        ExtraRptIncrementCtr( cgio_comps );
        if( sym == curr->symbol ) {
            return curr;
        }
    } RingIterEnd( curr );
    return NULL;
}

#ifndef NDEBUG


void DbgCgioEndFront(           // CALLED AT END OF FRONT END
    void )
{
    cgio_comps_front = cgio_comps;
    cgio_locates_front = cgio_locates;
    cgio_comps = 0;
    cgio_locates = 0;
}


void DbgCgioEndCallGr(          // CALLED AT END OF CALL-GRAPH PROCESSING
    void )
{
    cgio_comps_callgr = cgio_comps;
    cgio_locates_callgr = cgio_locates;
    cgio_comps = 0;
    cgio_locates = 0;
}


#endif


static CGFILE *initCGFILE(      // INITIALIZE A CG VIRTUAL FILE
    CGFILE *file_element,       // - allocated file element
    SYMBOL symbol )             // - controlling symbol-table entry
{
    CGIOBUFF *buff_element;     // - buffer element
    CGFILE_GEN *gen;            // - data while being generated

    buff_element = CgioBuffWrOpen();
    file_element->symbol = symbol;
    file_element->buffer = buff_element;
    file_element->offset = buff_element->free_offset;
    file_element->cursor = (CGINTER*) (buff_element->data + buff_element->free_offset);
    file_element->first = buff_element->disk_addr;
    file_element->delayed = FALSE;
    file_element->refed = FALSE;
    file_element->stgen = FALSE;
    file_element->oe_inl = FALSE;
    file_element->once_inl = FALSE;
    file_element->done = FALSE;
    file_element->thunk = FALSE;
    file_element->thunk_gen = FALSE;
    file_element->not_inline = FALSE;
    file_element->calls_inline = FALSE;
    file_element->can_throw = FALSE;
    file_element->stab_gen = FALSE;
    file_element->ctor_test = FALSE;
    file_element->write_to_pch = FALSE;
    file_element->state_table = 0;
    file_element->defined.src_file = NULL;
    file_element->defined.line = 0;
    file_element->defined.column = 0;
    file_element->cond_flags = 0;
    file_element->opt_retn_val = FALSE;
    file_element->opt_retn_ref = FALSE;
    file_element->opt_retn = NULL;
    gen = CarveAlloc( carveCGFILE_GEN );
    file_element->gen = gen;
    gen->cs_label = 0;
    gen->cs_allocated = 0;
    gen->goto_label = 0;
    gen->emit_init_beg = FALSE;
    gen->emit_init_end = FALSE;
    gen->emit_line_no.src_file = NULL;
    gen->curr_type = NULL;
    gen->emit_type = NULL;
    gen->init_sym = NULL;
    return( file_element );
}

CGFILE *CgioCreateFile(         // CREATE A CG VIRTUAL FILE
    SYMBOL symbol )             // - controlling symbol-table entry
{
    CGFILE *new_cgfile;

    ExtraRptIncrementCtr( cgio_files );
    new_cgfile = RingCarveAlloc( carveCGFILE, &cg_file_ring );
    return( initCGFILE( new_cgfile, symbol ) );
}


void CgioWriteIC(               // WRITE IC RECORD TO VIRTUAL FILE
    CGFILE *ctl,                // - control for the file
    CGINTER *ins )              // - instruction
{
#ifndef NDEBUG
    ExtraRptIncrementCtr( cgio_write_ins );
    if( ICOpTypes[ ins->opcode ] == ICOT_NUL ) {
        ExtraRptIncrementCtr( cgio_write_nul );
    }
#endif
    ctl->buffer = CgioBuffWriteIC( ctl->buffer, ins );
}


static void freeGenData(        // FREE GENERATION DATA
    CGFILE *ctl )               // - control for file
{
    CarveFree( carveCGFILE_GEN, ctl->gen );
    ctl->gen = NULL;
}


static boolean saveGenData(     // TEST IF GENERATION DATA REQ'D AFTER CLOSE
    CGFILE *ctl )               // - control for file
{
    SYMBOL func;                // - symbol for file

    func = ctl->symbol;
    return func == NULL
        || func == BRINF_SYMBOL
        || func->id == SC_DEFAULT;
}


void CgioCloseOutputFile(       // CLOSE VIRTUAL FILE AFTER OUTPUT PHASE
    CGFILE *ctl )               // - control for file
{
    CgioBuffWrClose( ctl->buffer );
    ctl->done = TRUE;
    ctl->buffer = NULL;
    if( ! saveGenData( ctl ) ) {
        freeGenData( ctl );
    }
}


void CgioOpenInput(             // OPEN VIRTUAL FILE FOR INPUT
    CGFILE *ctl )               // - control for file
{
    ctl->buffer = CgioBuffRdOpen( ctl->first );
    ctl->cursor = (CGINTER*) (( ctl->buffer->data + ctl->offset ) - sizeof( CGINTER ));
}


CGINTER *CgioSeek(              // SEEK TO POSITION IN VIRTUAL FILE
    CGFILE *ctl,                // - control for the file
    CGFILE_INS *posn )          // - position to seek to
{
    DbgAssert( ctl->cursor != NULL );
    ctl->buffer = CgioBuffSeek( ctl->buffer, posn, &ctl->cursor );
    return ctl->cursor;
}


CGINTER *CgioReadIC(            // READ IC RECORD (LOCATE MODE)
    CGFILE *ctl )               // - control for the file
{
    DbgAssert( ctl->cursor != NULL );
    ctl->buffer = CgioBuffReadIC( ctl->buffer, &ctl->cursor );
    return ctl->cursor;
}


CGINTER *CgioReadICUntilOpcode( // READ IC RECORD UNTIL OPCODE IS FOUND
    CGFILE *ctl,                // - control for the file
    unsigned opcode )           // - opcode to find
{
    DbgAssert( ctl->cursor != NULL );
    ctl->buffer = CgioBuffReadICUntilOpcode( ctl->buffer, &ctl->cursor, opcode );
    return ctl->cursor;
}


CGINTER *CgioReadICMask(        // READ IC RECORD UNTIL OPCODE IN SET IS FOUND
    CGFILE *ctl,                // - control for the file
    unsigned mask )             // - control mask for opcodes
{
    DbgAssert( ctl->cursor != NULL );
    ctl->buffer = CgioBuffReadICMask( ctl->buffer, &ctl->cursor, mask );
    return ctl->cursor;
}


CGINTER *CgioReadICMaskCount(   // READ IC RECORD UNTIL OPCODE IN SET IS FOUND
    CGFILE *ctl,                // - control for the file
    unsigned mask,              // - control mask for opcodes to return
    unsigned count_mask,        // - control mask for opcodes to count
    unsigned *count )           // - counter to update
{
    DbgAssert( ctl->cursor != NULL );
    ctl->buffer = CgioBuffReadICMaskCount( ctl->buffer, &ctl->cursor, mask, count_mask, count );
    return ctl->cursor;
}


void CgioCloseInputFile(        // CLOSE VIRTUAL FILE AFTER INPUT PHASE
    CGFILE *ctl )               // - control for file
{
    CgioBuffRdClose( ctl->buffer );
    ctl->buffer = NULL;
}


static boolean changeRing(      // CHANGE RING FOR A CGFILE IN cg_file_ring
    CGFILE** a_new,             // - addr[ new ring header ]
    CGFILE* element,            // - element
    CGFILE** a_old )            // - addr[ old ring header ]
{
    boolean retn;               // - TRUE ==> changed the ring
    CGFILE* prev;               // - preceding element

⌨️ 快捷键说明

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