blktrim.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 513 行 · 第 1/2 页
C
513 行
static bool Retarget( block *blk )
/************************************/
{
block_edge *edge;
block_edge *next;
block *target;
bool success;
success = TRUE; /* assume can get rid of block*/
target = blk->edge[ 0 ].destination;
edge = blk->input_edges;
blk->input_edges = NULL;
while( edge != NULL ) {
next = edge->next_source;
if( edge->source->class & ( SELECT | LABEL_RETURN ) ) {
success = FALSE; /* let the optimizer do it later on*/
edge->next_source = blk->input_edges;
blk->input_edges = edge;
} else {
edge->destination = target;
edge->next_source = target->input_edges;
target->input_edges = edge;
target->inputs++;
blk->inputs--;
}
edge = next;
}
if( success ) {
MoveHead( blk, target );
RemoveBlock( blk );
}
return( success );
}
static void JoinBlocks( block *jump, block *target )
/******************************************************/
{
block_edge *edge;
source_line_number line_num;
label_handle label;
instruction *nop;
/* To get here, 'target' is only entered from 'jump'*/
/* Thus, the only input edge to 'target' is from jump, and can be tossed*/
/* keep the label from jump in case it's referenced in a SELECT block*/
label = target->label;
target->label = jump->label;
if( jump->class & BIG_LABEL ) target->class |= BIG_LABEL;
jump->label = label;
line_num = target->ins.hd.line_num;
target->ins.hd.line_num = jump->ins.hd.line_num;
/* Move the inputs to 'jump' to be inputs to 'target'*/
target->inputs = jump->inputs;
edge = jump->input_edges;
target->input_edges = edge;
while( edge != NULL ) {
edge->destination = target; /* was 'jump' before*/
edge = edge->next_source;
}
/* Now join the instruction streams*/
nop = jump->ins.hd.prev;
if( nop->head.opcode == OP_NOP ) {
if( nop->flags.nop_flags & NOP_SOURCE_QUEUE ) {
/* this nop is only here to hold source info so we just
* attach the source info to the next instruction and
* nuke this nop so that it can't inhibit optimization */
if( target->ins.hd.next->head.line_num == 0 ) {
target->ins.hd.next->head.line_num = nop->head.line_num;
}
FreeIns( nop );
}
}
if( jump->ins.hd.next != (instruction *)&jump->ins ) {
if( line_num != 0 ) {
jump->ins.hd.prev->head.line_num = line_num;
}
jump->ins.hd.prev->head.next = target->ins.hd.next;
target->ins.hd.next->head.prev = jump->ins.hd.prev;
target->ins.hd.next = jump->ins.hd.next;
target->ins.hd.next->head.prev = (instruction *)&target->ins;
jump->ins.hd.next = (instruction *)&jump->ins;/* so RemoveBlock won't*/
jump->ins.hd.prev = (instruction *)&jump->ins;/* free the instr list*/
}
jump->inputs = 0;
jump->targets = 0;
MoveHead( jump, target );
RemoveBlock( jump );
}
static bool SameTarget( block *blk )
/**************************************/
{
instruction *ins;
block *targ1, *targ2;
targ1 = blk->edge[ 0 ].destination;
targ2 = blk->edge[ 1 ].destination;
if( targ1 != targ2 ) return( FALSE );
if( ( targ1->class | targ2->class ) & UNKNOWN_DESTINATION ) return( FALSE );
blk->class &= ~CONDITIONAL;
blk->class |= JUMP;
RemoveEdge( &blk->edge[1] );
ins = blk->ins.hd.prev;
while( !_OpIsCondition( ins->head.opcode ) ) {
ins = ins->head.prev;
}
FreeIns( ins );
return( TRUE );
}
static bool DoBlockTrim( void )
/*********************************/
{
block *blk;
block *next;
block *target;
instruction *ins;
bool change;
bool any_change = FALSE;
for( ;; ) {
change = FALSE;
MarkReachableBlocks();
blk = HeadBlock->next_block;
while( blk != NULL ) {
next = blk->next_block;
if( !( blk->class & ( UNKNOWN_DESTINATION | BLOCK_VISITED ) ) ) {
while( blk->input_edges != NULL ) {
RemoveInputEdge( blk->input_edges );
}
RemoveBlock( blk );
change = TRUE;
} else if( blk->class & CONDITIONAL ) {
change |= SameTarget( blk );
} else if( blk->class & JUMP ) {
target = blk->edge[ 0 ].destination;
if( target != blk && !(target->class & UNKNOWN_DESTINATION) ) {
ins = blk->ins.hd.next;
while( ins->head.opcode == OP_NOP ) {
if( ins->flags.nop_flags & (NOP_DBGINFO|NOP_DBGINFO_START) ) break;
ins = ins->head.next;
}
if( ins->head.opcode == OP_BLOCK ) { /* was an empty block*/
if( ( blk->class & BIG_LABEL ) == 0 ) {
change |= Retarget( blk );
}
} else if( target->inputs == 1
&& ( target->class & BIG_LABEL ) == 0
&& ( CountIns(blk)+CountIns(target) ) <= INS_PER_BLOCK
) {
if( !( blk->class & ( RETURNED_TO | BIG_LABEL ) )
&& !( target->class & CALL_LABEL ) ) {
JoinBlocks( blk, target );
change = TRUE;
}
}
}
}
blk = next;
}
UnMarkBlocks();
if( change == FALSE ) break;
BlocksUnTrimmed = FALSE;
any_change = TRUE;
}
if( HeadBlock != NULL ) {
HeadBlock->id = 1;
blk = HeadBlock;
for( ;; ) {
next = blk->next_block;
if( next == NULL ) break;
next->id = blk->id + 1;
blk = next;
}
}
return( any_change );
}
extern void KillCondBlk( block *blk, instruction *ins, int dest )
/***************************************************************/
// Assume blk is a conditional with compare ins
// Make dest the destination and delete the unused edge
// Change blk to a JMP to dest edge
{
block_edge *edge;
block *dest_blk;
RemoveInputEdge( &blk->edge[ 0 ] );
RemoveInputEdge( &blk->edge[ 1 ] );
blk->class &= ~CONDITIONAL;
blk->class |= JUMP;
blk->targets = 1;
dest_blk = blk->edge[dest].destination;
edge = &blk->edge[0];
edge->flags = blk->edge[dest].flags;
edge->source = blk;
edge->destination = dest_blk;
edge->next_source = dest_blk->input_edges;
dest_blk->input_edges = edge;
dest_blk->inputs++;
FreeIns( ins );
}
extern bool DeadBlocks( void )
/********************************/
{
block *blk;
instruction *ins;
int dest;
bool change;
change = FALSE;
for( blk = HeadBlock; blk != NULL; blk = blk->next_block ) {
if( blk->class & CONDITIONAL ) {
ins = FindOneCond( blk );
if( ins == NULL ) continue;
if( ins->result != NULL ) continue;
dest = _TrueIndex( ins );
if( dest != _FalseIndex( ins ) ) continue;
KillCondBlk( blk, ins, dest );
change = TRUE;
}
}
if( change ) {
BlockTrim();
return( TRUE );
}
return( FALSE );
}
extern bool BlockTrim( void )
/*******************************/
{
bool change = FALSE;
if( ( CurrProc->state.attr & ROUTINE_WANTS_DEBUGGING ) == 0 ) {
change = DoBlockTrim();
Renumber();
}
return( change );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?