temps.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 714 行 · 第 1/2 页
C
714 行
while( scan != temp ) {
scan->t.location = temp->t.location;
scan->v.usage |= HAS_MEMORY;
scan = scan->t.alias;
}
}
static void NewLocation( name *temp, type_length size )
/*********************************************************/
{
SetTempLocation( temp, size );
temp->v.usage |= HAS_MEMORY;
PropLocal( temp );
}
static void AllocNewLocal( name *temp )
/*****************************************/
{
type_length size;
stack_entry *stack;
stack_temp *new_st_temp;
instruction *ins;
stack_temp st_temp;
bool any_references;
#if 0
// this is disabled because users can generate code which
// may be incorrect (most likely) but which we don't want
// to trigger this assert.
/* such as:
enum MonthEnum { InvalidMonth = 0, January, February, March };
long IntoDays() {
MonthEnum i = January;
for ( ; i <= 11; ((short&) i)++ ) ;
return 0;
} */
// run through the aliases making sure that none
// are larger than the master BBB - May 26, 1997
{
name *t;
for( t = temp->t.alias; t != temp; t = t->t.alias ) {
if( t->t.temp_flags & CG_INTRODUCED ) continue;
assert( t->n.size <= temp->n.size );
}
}
#endif
size = _RoundUp( temp->n.size, REG_SIZE ); /* align size*/
if( ( temp->v.usage & ( USE_IN_ANOTHER_BLOCK | USE_ADDRESS ) ) == EMPTY
&& temp->t.u.block_id != NO_BLOCK_ID ) {
CalcRange( &st_temp, temp );
if( st_temp.first != st_temp.last ) { /*% actually needed*/
stack = ReUsableStack( &st_temp, temp );
if( stack != NULL ) {
temp->t.location = stack->location;
_Alloc( new_st_temp, sizeof( stack_temp ) );
new_st_temp->first = st_temp.first;
new_st_temp->last = st_temp.last;
new_st_temp->others = stack->temp.others;
stack->temp.others = new_st_temp;
} else {
SetTempLocation( temp, size );
StackEntry( &st_temp, temp );
}
temp->v.usage |= HAS_MEMORY;
PropLocal( temp );
} else {
temp->v.usage &= ~NEEDS_MEMORY;
}
} else {
if( BlockByBlock || ( temp->v.usage & USE_ADDRESS ) != EMPTY ) {
NewLocation( temp, size );
return;
}
ins = FindOnlyIns( temp, &any_references );
if( ins == NULL || UsedByLA( ins, temp ) || SideEffect( ins ) ) {
if( any_references ) {
NewLocation( temp, size );
} else {
temp->v.usage &= ~NEEDS_MEMORY;
}
return;
}
DoNothing( ins );
temp->v.usage &= ~NEEDS_MEMORY;
}
}
static void MarkUsage( name *op )
/***********************************/
{
if( op->n.class == N_INDEXED ) {
if( op->i.index != NULL ) {
MarkUsage( op->i.index );
}
if( op->i.base != NULL && !( op->i.index_flags & X_FAKE_BASE ) ) {
MarkUsage( op->i.base );
}
} else if( op->n.class == N_TEMP ) {
op = DeAlias( op );
if( op->v.block_usage == USED_NEVER ) {
op->v.block_usage = USED_ONCE;
} else {
op->v.block_usage = USED_TWICE;
}
}
}
static void CalcNumberOfUses( void )
/**************************************/
{
name *temp;
block *blk;
instruction *ins;
int i;
for( temp = Names[ N_TEMP ]; temp != NULL; temp = temp->n.next_name ) {
if( temp->t.temp_flags & STACK_PARM ) {
temp->v.block_usage = USED_TWICE;
} else {
temp->v.block_usage = USED_NEVER;
}
}
blk = HeadBlock;
while( blk != NULL ) {
ins = blk->ins.hd.next;
while( ins->head.opcode != OP_BLOCK ) {
i = ins->num_operands;
while( --i >= 0 ) {
MarkUsage( ins->operands[i] );
}
if( ins->result != NULL ) {
MarkUsage( ins->result );
}
ins = ins->head.next;
}
blk = blk->next_block;
}
}
extern void AssignOtherLocals( void )
/***************************************/
{
name *temp;
name **owner;
name *rest;
if( LastTemp != NULL ) {
rest = LastTemp->n.next_name;
LastTemp->n.next_name = NULL;
}
Names[ N_TEMP ] = SortList( Names[ N_TEMP ], offsetof( name, n.next_name ),
TempAllocBefore );
if( LastTemp != NULL ) {
owner = &Names[ N_TEMP ];
while( *owner != NULL ) {
owner = &(*owner)->n.next_name;
}
*owner = rest;
}
if( !BlockByBlock ) {
CalcNumberOfUses();
}
for( temp = Names[ N_TEMP ]; temp != LastTemp; temp = temp->n.next_name ) {
if( !( temp->v.usage & NEEDS_MEMORY ) ) continue;
if( temp->v.usage & HAS_MEMORY ) continue;
if( temp->t.temp_flags & ALIAS ) continue;
AllocNewLocal( temp );
}
}
static void PropAParm( name *temp )
/*********************************/
{
name *base;
if( temp->n.class == N_INDEXED ) {
temp = temp->i.base;
if( temp == NULL ) return;
}
if( temp->n.class != N_TEMP ) return;
if( ( temp->v.usage & HAS_MEMORY ) != EMPTY ) return;
if( temp->t.location == NO_LOCATION ) return;
base = DeAlias( temp );
if( base != temp ) PropAParm( base );
temp->t.location += temp->v.offset - base->v.offset;
temp->v.usage |= HAS_MEMORY;
temp->t.temp_flags |= STACK_PARM;
}
extern void ParmPropagate( void )
/***********************************/
{
instruction *ins;
block *blk;
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 ) {
PropAParm( ins->operands[ i ] );
}
if( ins->result != NULL ) {
PropAParm( ins->result );
}
ins = ins->head.next;
}
blk = blk->next_block;
}
}
extern void AllocALocal( name *name )
/***************************************/
{
name = DeAlias( name );
if( ( name->v.usage & HAS_MEMORY ) == EMPTY ) {
name->v.block_usage = USED_ONCE;
AllocNewLocal( name );
}
}
static void AssgnATemp( name *temp, block_num curr_id )
/*****************************************************/
{
if( temp->n.class == N_INDEXED && temp->i.base != NULL ) {
temp = temp->i.base;
}
if( temp->n.class != N_TEMP ) return;
temp = DeAlias( temp );
if( temp->v.usage & HAS_MEMORY ) {
PropLocal( temp );
return;
}
if( ( temp->v.usage & NEEDS_MEMORY ) == EMPTY ) return;
if( ( curr_id == NO_BLOCK_ID )
|| ( temp->t.u.block_id == curr_id )
|| ( temp->t.u.block_id == NO_BLOCK_ID ) ) {
AllocALocal( temp );
}
}
extern void FiniStackMap( void )
/**********************************/
{
stack_entry *junk1;
stack_temp *junk2;
name *temp;
for( temp = Names[ N_TEMP ]; temp != NULL; temp = temp->n.next_name ) {
if( ( temp->t.temp_flags & ALIAS ) != EMPTY ) continue;
if( ( temp->v.usage & USE_ADDRESS ) == EMPTY ) continue;
if( ( temp->v.usage & HAS_MEMORY ) != EMPTY ) continue;
AllocNewLocal( temp );
}
while( StackMap != NULL ) {
junk1 = StackMap;
StackMap = StackMap->link;
while( junk1->temp.others != NULL ) {
junk2 = junk1->temp.others;
junk1->temp.others = junk1->temp.others->others;
_Free( junk2, sizeof( stack_temp ) );
}
_Free( junk1, sizeof( stack_entry ) );
}
TellTempLocs();
}
extern void AssgnMoreTemps( block_num curr_id )
/*************************************************/
/* run the block list. It's faster if we're using /od */
{
instruction *ins;
block *blk;
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 ) {
AssgnATemp( ins->operands[ i ], curr_id );
}
if( ins->result != NULL ) {
AssgnATemp( ins->result, curr_id );
}
ins = ins->head.next;
}
blk = blk->next_block;
}
if( curr_id == NO_BLOCK_ID ) {
FiniStackMap();
InitStackMap();
} else {
ReInitStackMap();
}
}
extern void CountTempRefs( void )
/*******************************************/
{
block *blk;
instruction *ins;
int i;
name *temp;
for( temp = Names[ N_TEMP ]; temp != NULL; temp = temp->n.next_name ) {
temp->t.u.ref_count = 0;
}
blk = HeadBlock;
while( blk != NULL ) {
ins = blk->ins.hd.next;
while( ins->head.opcode != OP_BLOCK ) {
i = ins->num_operands;
while( --i >= 0 ) {
if( ins->operands[ i ]->n.class == N_TEMP ) {
ins->operands[ i ]->t.u.ref_count++;
}
}
if( ins->result != NULL ) {
if( ins->result->n.class == N_TEMP ) {
ins->result->t.u.ref_count++;
}
}
ins = ins->head.next;
}
blk = blk->next_block;
}
}
extern void AssignTemps( void )
/*********************************/
/* Parameters on stack have already been assigned locations*/
{
TransferTempFlags(); /* make sure whole structure goes in mem*/
ParmPropagate(); /* assign temps which may use parm memory*/
PushLocals(); /* assign locals which may be pushed */
AssignOtherLocals(); /* assign memory to all other locals*/
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?