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 + -
显示快捷键?