varusage.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 486 行 · 第 1/2 页
C
486 行
if( HasTrueBase( op ) ) {
TransferOneMemBlockUsage( op->i.base );
}
} else if ( op->n.class == N_MEMORY ) {
TransferBlockUsage( op );
}
}
static void TransferMemBlockUsage( block *blk )
/**************************************************
Like TransferTempBlockUsage.
*/
{
instruction *ins;
int i;
ins = blk->ins.hd.next;
while( ins->head.opcode != OP_BLOCK ) {
i = ins->num_operands;
while( --i >= 0 ) {
TransferOneMemBlockUsage( ins->operands[ i ] );
}
if( ins->result != NULL ) {
TransferOneMemBlockUsage( ins->result );
}
ins = ins->head.next;
}
}
static void TransferOneTempFlag( name *t )
/****************************************/
{
name *alias;
var_usage usage;
if( t->n.class == N_TEMP ) {
t = DeAlias( t );
alias = t;
usage = EMPTY;
do {
usage |= alias->v.usage;
alias = alias->t.alias;
} while( alias != t );
alias = t;
do {
alias->v.usage |= usage;
alias = alias->t.alias;
} while( alias != t );
} else if( t->n.class == N_INDEXED ) {
TransferOneTempFlag( t->i.index );
if( HasTrueBase( t ) ) {
TransferOneTempFlag( t->i.base );
}
}
}
extern void TransferTempFlags( void )
/****************************************
Run through the program and for each variable reference, transfer
the usage flags from each variable to all of its aliases. (if we
use the address of T1, we're effectively using the address of T1+1
as well, etc). We could traverse Names[N_TEMP] but it could be much
longer than the block list.
*/
{
block *blk;
instruction *ins;
int i;
blk = HeadBlock;
while( blk != NULL ) {
ins = blk->ins.hd.next;
while( ins->head.opcode != OP_BLOCK ) {
i = ins->num_operands;
while( --i >= 0 ) {
TransferOneTempFlag( ins->operands[ i ] );
}
if( ins->result != NULL ) {
TransferOneTempFlag( ins->result );
}
ins = ins->head.next;
}
blk = blk->next_block;
}
blk = HeadBlock;
while( blk != NULL ) {
TransferTempBlockUsage( blk );
blk = blk->next_block;
}
}
static void TransferMemoryFlags( void )
/******************************************
If we use the address of FOOBAR, we're effectively using the address
of FOOBAR+1 as well
*/
{
name *m;
name *same_sym;
var_usage usage;
m = Names[ N_MEMORY ];
while( m != NULL ) {
m->m.memory_flags = MF_EMPTY;
m = m->n.next_name;
}
m = Names[ N_MEMORY ];
while( m != NULL ) {
if( ( m->m.memory_flags & MF_VISITED ) == 0 ) {
if( m->m.same_sym != NULL ) {
// union together mem flags from all symbols that
// are same and set all v.usage's to this union
usage = m->v.usage;
same_sym = m->m.same_sym;
while( same_sym != m ) {
usage |= same_sym->v.usage;
same_sym = same_sym->m.same_sym;
}
m->v.usage = usage;
same_sym = m->m.same_sym;
while( same_sym != m ) {
same_sym->v.usage |= usage;
same_sym = same_sym->m.same_sym;
same_sym->m.memory_flags |= MF_VISITED;
}
}
m->m.memory_flags |= MF_VISITED;
}
m = m->n.next_name;
}
}
static void SearchDefUse( void )
/***********************************
see FindReferences ^
*/
{
block *blk;
instruction *ins;
name *name;
int i;
bool touched_non_op;
blk = HeadBlock;
for( ;; ) {
touched_non_op = FALSE;
ins = blk->ins.hd.next;
while( ins->head.opcode != OP_BLOCK ) {
if( ( ins->head.opcode == OP_CALL
|| ins->head.opcode == OP_CALL_INDIRECT )
&& ( ( ins->flags.call_flags & CALL_READS_NO_MEMORY ) == 0
/*21-nov-90*/ || ( ins->flags.call_flags & CALL_WRITES_NO_MEMORY ) == 0 ) ) {
UseDefGlobals( blk );
touched_non_op = TRUE;
}
i = ins->num_operands;
while( -- i >= 0 ) {
name = ins->operands[ i ];
if( name->n.class == N_INDEXED ) {
Use( name->i.index, blk, EMPTY );
if( HasTrueBase( name ) ) {
Use( name->i.base, blk, USE_ADDRESS );
}
} else {
if( ins->head.opcode == OP_LA && i == 0 ) {
Use( name, blk, USE_ADDRESS );
} else {
Use( name, blk, EMPTY );
}
}
}
name = ins->result;
if( name != NULL ) {
if( name->n.class == N_INDEXED ) {
Use( name->i.index, blk, EMPTY );
if( HasTrueBase( name ) ) {
Use( name->i.base, blk, USE_ADDRESS );
}
} else if( name->n.class == N_MEMORY ) {
/* Any static data defined can be used in another block*/
name->v.usage |= USE_IN_ANOTHER_BLOCK;
Define( name, blk );
} else if( name->n.class == N_TEMP ) {
Define( name, blk );
}
}
ins = ins->head.next;
}
/* in/out/def/use ignored if BlockByBlock so don't worry about it */
if( touched_non_op && !BlockByBlock ) {
TransferAllMemBlockUsage();
} else {
TransferMemBlockUsage( blk );
}
TransferTempBlockUsage( blk );
blk = blk->next_block;
if( blk == NULL ) break;
}
TransferTempFlags();
TransferMemoryFlags();
}
extern void FindReferences( void )
/*************************************
Traverse the blocks an allocate a data_flow_def for each one if it
is needed. Then calculate which variables are USE_WITHIN_BLOCK,
USE_IN_OTHER_BLOCK, DEF_IN_BLOCK and turn on their bits in the
dataflo->def and dataflo->use sets. Note that USE_WITHIN_BLOCK
means that a variable is used before it is defined.
DEF_WITHIN_BLOCK means that the entire variable is redefined by the
block, so that no definitition of it in a previous block could flow
through this block and be used in a subsequent block. USE_IN_ANOTHER
block means that a variable is used in more than one block.
*/
{
block *curr;
curr = HeadBlock;
while( curr != NULL ) {
if( curr->dataflow == NULL ) {
_Alloc( curr->dataflow, sizeof( data_flow_def ) );
}
_GBitInit( curr->dataflow->def , EMPTY );
_GBitInit( curr->dataflow->use , EMPTY );
_GBitInit( curr->dataflow->in , EMPTY );
_GBitInit( curr->dataflow->out , EMPTY );
_GBitInit( curr->dataflow->call_exempt , EMPTY );
_GBitInit( curr->dataflow->need_load , EMPTY );
_GBitInit( curr->dataflow->need_store , EMPTY );
curr = curr->next_block;
}
SearchDefUse();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?