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