cdopt.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,978 行 · 第 1/4 页
C
1,978 行
/****************************************************************************
*
* 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 "cgfront.h"
#include "cdopt.h"
#include "cgswitch.h"
#include "errdefns.h"
#include "fnovload.h"
#include "ring.h"
#include "vstk.h"
#include "initdefs.h"
#include "pcheader.h"
#include "rtngen.h"
#include "context.h"
#include "stats.h"
#ifndef NDEBUG
#include "pragdefn.h"
#endif
#define TIS_DEFS /* types in input stack */ \
TIS_DEF( DT_INPUT ) /* - dtor, unprocessed */ \
, TIS_DEF( DT_STR ) /* - dtor, stretching */ \
, TIS_DEF( DT_NO_OPT ) /* - dtor, no optimization */ \
, TIS_DEF( DT_OPT ) /* - dtor, optimized ok */
#define CDOPT_DEFS /* types of optimization */ \
CDO_DEF( CDOPT_DTOR ) /* - dtor */ \
, CDO_DEF( CDOPT_CTOR ) /* - default ctor */ \
, CDO_DEF( CDOPT_OPREQ ) /* - operator = */
typedef enum { // CDOPT_TYPE -- type of optimization
#define CDO_DEF(a) a
CDOPT_DEFS
#undef CDO_DEF
, MAX_CDOPT_TYPE
} CDOPT_TYPE;
typedef enum { // TIS -- types in input stack
#define DT_DEF(a) a
DT_DEFS
#undef DT_DEF
, MAX_TIS_TYPE
} TIS;
struct cdopt_cache // CDOPT_CACHE -- cache from CLASSINFO
{ CD_DESCR* cdopt_ctor; // - NULL or descriptor for default ctor
CD_DESCR* cdopt_dtor; // - NULL or descriptor for dctor
CD_DESCR* cdopt_opeq; // - NULL or descriptor for operator =
};
typedef struct memb_vfuns MEMB_VFUNS;
typedef struct cl_elem CL_ELEM;
typedef struct acc_fun ACC_FUN;
struct acc_fun // ACC_SYM -- function accessed directly
{ ACC_FUN* next; // - next symbol
SYMBOL fun; // - function accessed
};
struct cd_descr // CD_DESCR -- ctor/dtor description
{ CD_DESCR* next; // - next in cache ring
const MEMB_VFUNS* mfuns; // - member functions
TYPE orig_type; // - originating class type
CL_ELEM* elements; // - significant elements
ACC_FUN* accessed; // - functions accessed
CDOPT_TYPE opt; // - type of optimization
unsigned err_occurred:1; // - TRUE ==> error detected during lookup
unsigned has_vbt :1; // - TRUE ==> has virtual base table
unsigned has_vft :1; // - TRUE ==> has virtual function table
unsigned has_acc :1; // - TRUE ==> has functions accessed
unsigned chk_acc :1; // - TRUE ==> accesses have been checked
PAD_UNSIGNED
};
struct cl_elem // CL_ELEM -- significant class element
{ CL_ELEM* next; // - next in ring
TYPE cltype; // - class/array type
SYMBOL cdtor; // - CTOR,DTOR,OP=
SYMBOL sym; // - symbol, when data element
CD_DESCR* descr; // - description of class for element
target_offset_t offset; // - offset
TOB otype; // - type of object
unsigned elim_intermed:1;// - intermediate function can be eliminated
unsigned cannot_define:1;// - function could not be defined
unsigned must_call:1; // - item must be ctored,dtored,assigned
PAD_UNSIGNED
};
typedef struct stkin STKIN;
struct stkin // STKIN -- stack (input) entry
{ CD_DESCR* info; // - information for class being expanded
CL_ELEM* elem; // - element being expanded
};
typedef struct // CDOPT_DEFN : defines CDOPT type
{ MEMB_VFUNS const* vfuns; // - virtual functions
CDOPT_TYPE otype; // - type of CDOPT
unsigned :0; // alignment
} CDOPT_DEFN;
typedef struct // CL_EXPAND -- expansion information
{ CD_DESCR* info; // - class description
STKIN* source; // - source item
} CL_EXPAND;
struct memb_vfuns // VFT for CD_DESCR
{ boolean (*basePushable) // - base class pushable ?
( BASE_CLASS* ); // - - base class
boolean (*membPushable) // - member pushable ?
( SYMBOL ); // - - symbol for member
SYMBOL (*find) // - find symbol for type
( CL_ELEM* ); // - - type
boolean (*optimizable) // - optimizable function ?
( CL_ELEM* ); // - - class entry
boolean (*include) // - include function after expansion ?
( CL_ELEM* ); // - - class entry
SYMBOL (*array_cdtor) // - get array cdtor
( SYMBOL ); // - - array member symbol
void (*schedule_acc_chk) // - schedule access check
( TYPE ); // - - type for function
SYMBOL (*array_acc) // - get symbol for array access
( TYPE ); // - - array symbol
#ifdef XTRA_RPT
void (*rpt_desc) // - report: descriptor defined
( void );
void (*elem_proc) // - report: element processed
( void );
void (*elem_kept) // - report: element kept
( void );
#endif
};
typedef struct // CL_ITER: iteration info. per class
{ CD_DESCR *info; // - class information
CL_ELEM *elem; // - current element
TOB comp_otype; // - TOB for component being expanded
} CL_ITER;
struct cdopt_iter // CDOPT_ITER: iterator for traversals
{ CD_DESCR *info; // - original class information
VSTK_CTL stack; // - stack of elements
BASE_CLASS *vbase; // - NULL or virtual base
target_offset_t off_comp; // - offset of component being expanded
target_offset_t off_elem; // - offset of element (exact)
target_offset_t off_vbase; // - offset of virtual base
TITER orig_otype; // - object type of original component
unsigned gened_comp :1; // - TRUE ==> gen'ed component element
unsigned at_end :1; // - TRUE ==> processing TITER_NONE at end
PAD_UNSIGNED
};
static carve_t carveCD_DESCR; // carving control: descriptors
static carve_t carveCL_ELEM; // carving control: elements
static carve_t carveCDOPT_ITER; // carving control: iterators
static carve_t carveACC_FUN; // carving control: functions accessed
static carve_t carveCDOPT_CACHE; // carving control: caching
static CDOPT_CACHE allDescriptors; // all allocated descriptors
static VSTK_CTL stackSTKIN; // stack of elements
ExtraRptCtr( ctr_ctor_desc ); // # ctor descriptors
ExtraRptCtr( ctr_ctor_elem ); // # ctor elements processed
ExtraRptCtr( ctr_ctor_kept ); // # ctor elements kept
ExtraRptCtr( ctr_dtor_desc ); // # dtor descriptors
ExtraRptCtr( ctr_dtor_elem ); // # dtor elements processed
ExtraRptCtr( ctr_dtor_kept ); // # dtor elements kept
ExtraRptCtr( ctr_opeq_desc ); // # opeq descriptors
ExtraRptCtr( ctr_opeq_elem ); // # opeq elements processed
ExtraRptCtr( ctr_opeq_kept ); // # opeq elements kept
ExtraRptCtr( ctr_caches ); // # caches
#ifndef NDEBUG
#include <stdio.h>
#include "dbg.h"
#include "toggle.h"
static char* tob_names[] = {
#define TOB_DEF(a) # a
TOB_DEFS
#undef TOB_DEF
};
static char* cdopt_names[] = {
#define CDO_DEF(a) # a
CDOPT_DEFS
#undef CDO_DEF
};
static char* tis_names[] = {
#define TIS_DEF(a) # a
TIS_DEFS
#undef TIS_DEF
};
static char* titer_names[] = {
#define TITER_DEF(a) # a
TITER_DEFS
#undef TITER_DEF
};
char* __fmt_TOB( TOB tob ) // FORMAT TOB
{
return ( tob >= MAX_TOB_DEF ) ? "*** BAD TOB ***" : tob_names[ tob ];
}
char* __fmt_CDOPT_TYPE( CDOPT_TYPE cdot )
{
return ( cdot >= MAX_CDOPT_TYPE )
? "*** BAD CDOPT ***"
: cdopt_names[ cdot ];
}
char* __fmt_TIS( TIS tis )
{
return ( tis >= MAX_TIS_TYPE ) ? "*** BAD TIS ***" : tis_names[ tis ];
}
char* __fmt_TITER( TITER val )
{
return ( val >= MAX_TITER_DEF )
? "*** BAD TITER ***"
: titer_names[ val ];
}
void DumpCdoptIter( // DUMP ITERATOR
CDOPT_ITER* iter, // - iterator
const char* text1, // - and some text
const char* text2 ) // - and some text
{
if( PragDbgToggle.cdopt ) {
printf( "CDOPT_ITER[%x] info(%x) orig_otype(%s) %s %s\n"
" offsets: comp(%x) elem(%x) vbase(%x) gened_comp(%x) at_end(%x)\n"
, iter
, iter->info
, __fmt_TITER( iter->orig_otype )
, text1
, text2
, iter->off_comp
, iter->off_elem
, iter->vbase
, iter->gened_comp
, iter->at_end
);
}
}
void DumpCdoptClElem( // DUMP A CLASS ELEMENT
CL_ELEM* elem ) // - the element
{
if( elem != NULL ) {
printf( " CL_ELEM[%x]: next(%x) type(%x) offset(%x) type(%s)\n"
" descr(%x) cdtor(%s) sym(%s)\n"
" elim_intermed(%d) cannot_define(%d) must_call(%d)\n"
, elem
, elem->next
, elem->cltype
, elem->offset
, __fmt_TOB( elem->otype )
, elem->descr
, DbgSymNameFull( elem->cdtor )
, DbgSymNameFull( elem->sym )
, elem->elim_intermed
, elem->cannot_define
, elem->must_call
);
}
}
void DumpCdoptInfo( // DUMP CD_DESCR
CD_DESCR *info ) // - control information
{
CL_ELEM* elem; // - current element
ACC_FUN* af; // - current function access
if( PragDbgToggle.cdopt ) {
printf( "CD_DESCR[%x]: type(%x) opt(%s) elements(%x)\n"
" accessed(%x) vft(%d) vbt(%d)\n"
, info
, info->orig_type
, __fmt_CDOPT_TYPE( info->opt )
, info->elements
, info->accessed
, info->has_vft
, info->has_vbt );
DumpFullType( info->orig_type );
RingIterBeg( info->elements, elem ) {
DumpCdoptClElem( elem );
} RingIterEnd( elem )
RingIterBeg( info->accessed, af ) {
printf( " Accessed: %s\n", DbgSymNameFull( af->fun ) );
} RingIterEnd( af )
}
}
void DumpCdoptIn( // DUMP INPUT STACK ENTRY
STKIN *inp, // - input stack
const char* text ) // - descriptive text
{
if( PragDbgToggle.cdopt ) {
printf( "STKIN[%x]: info(%x) elem(%x) %s\n"
, inp
, inp->info
, inp->elem
, text );
DumpCdoptClElem( inp->elem );
}
}
void DumpClIter( // DUMP STACK ENTRY
CL_ITER* exp, // - stack entry
const char* text ) // - and some text
{
if( PragDbgToggle.cdopt ) {
printf( "CL_ITER[%x]: info(%x) elem(%x) comp_otype(%s) %s\n"
, exp
, exp->info
, exp->elem
, __fmt_TOB( exp->comp_otype )
, text
);
DumpCdoptClElem( exp->elem );
}
}
static void dumpRing( // DUMP A RING
CD_DESCR* cache ) // - ring to be dumped
{
CD_DESCR* dump; // - current descriptor
RingIterBeg( cache, dump ) {
DumpCdoptInfo( dump );
} RingIterEnd( dump )
}
void DumpCdoptCaches( // DUMP CDOPT CACHES
void )
{
int saved = PragDbgToggle.cdopt;
PragDbgToggle.cdopt = 1;
dumpRing( allDescriptors.cdopt_ctor );
dumpRing( allDescriptors.cdopt_dtor );
dumpRing( allDescriptors.cdopt_opeq );
PragDbgToggle.cdopt = saved;
}
#else
#define DumpCdoptInfo(a)
#define DumpCdoptIter(a,b,c)
#define DumpCdoptClElem(a)
#define DumpCdoptIn(a,b)
#define DumpClIter(a,b)
#endif
//--------------------------------------------------------------------
// ACC_FUN support
//--------------------------------------------------------------------
static void addAccFun( // ADD A FUNCTION ACCESS
CD_DESCR* descr, // - descriptor
SYMBOL fun ) // - the function
{
ACC_FUN* curr; // - current access
ACC_FUN* af; // - access for function
if( fun != NULL ) {
if( ArrayType( fun->sym_type ) != NULL ) {
fun = (*descr->mfuns->array_acc)
( ArrayBaseType( fun->sym_type ) );
}
}
if( fun != NULL ) {
af = NULL;
RingIterBeg( descr->accessed, curr ) {
if( fun == curr->fun ) {
af = curr;
break;
}
} RingIterEnd( curr )
if( af == NULL ) {
af = RingCarveAlloc( carveACC_FUN, &descr->accessed );
af->fun = fun;
descr->has_acc = TRUE;
}
}
}
void CDoptNoAccFun( // INDICATE FUNCTIONS ACCESSED FOR CLASS
CD_DESCR* descr ) // - descriptor for a class
{
descr->chk_acc = TRUE;
}
void CDoptChkAccFun( // CHECK FUNCTIONS ACCESS FOR CLASS
CD_DESCR* descr ) // - descriptor for a class
{
SCOPE old; // - old scope
ACC_FUN* af; // - accessed function
char* name; // - name of function
SEARCH_RESULT* result; // - search result for function
if( ! descr->chk_acc ) {
descr->chk_acc = TRUE;
if( NULL != descr->accessed ) {
old = GetCurrScope();
SetCurrScope(TypeScope( descr->orig_type ));
RingIterBeg( descr->accessed, af ) {
name = af->fun->name->name;
result = ScopeFindBaseMember( SymScope( af->fun ), name );
ScopeCheckSymbol( result, af->fun );
ScopeFreeResult( result );
} RingIterEnd( af )
SetCurrScope(old);
}
}
}
static void cdoptChkAccFunGen( // CHECK ACCESS FOR CLASS FUNCTION
SYMBOL fun, // - the class function
CD_DESCR* descr ) // - descriptor for a class
{
CtxFunction( fun );
CDoptChkAccFun( descr );
}
//--------------------------------------------------------------------
// Traversals
//--------------------------------------------------------------------
static
CL_ELEM* activeElement // GET ACTIVE ELEMENT
( CDOPT_ITER *iter ) // - iterator
{
CL_ITER* exp; // - expansion information
CL_ELEM* elem; // - class information
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?