blktrim.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 513 行 · 第 1/2 页
C
513 行
/****************************************************************************
*
* 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: Clean up basic blocks in a routine.
*
****************************************************************************/
#include "standard.h"
#include "coderep.h"
#include "opcodes.h"
#include "sysmacro.h"
#include "procdef.h"
extern block *HeadBlock;
extern block *BlockList;
extern bool BlocksUnTrimmed;
extern proc_def *CurrProc;
extern void TellScrapLabel( label_handle );
extern void FreeIns( instruction * );
extern void FreeABlock( block * );
extern instruction_id Renumber( void );
extern void RemoveEdge( block_edge * );
/* forward declarations */
extern void RemoveInputEdge( block_edge *edge );
extern bool BlockTrim( void );
static instruction *FindOneCond( block *blk )
/************************************************/
{
instruction *ins;
instruction *cond;
cond = NULL;
for( ins = blk->ins.hd.next;
ins->head.opcode != OP_BLOCK; ins = ins->head.next ) {
if( _OpIsCondition( ins->head.opcode ) ) {
if( cond != NULL ) return( NULL );
cond = ins;
}
}
return( cond );
}
static void UnMarkBlocks( void )
/**********************************/
{
block *blk;
blk = HeadBlock;
while( blk != NULL ) {
blk->class &= ~BLOCK_VISITED;
blk = blk->next_block;
}
}
static void MarkReachableBlocks( void )
/*****************************************/
/* Written NON-Recursively for a very good reason. (stack blew up)*/
{
block *blk;
block *son;
bool change;
int i;
for( ;; ) {
change = FALSE;
blk = HeadBlock;
while( blk != NULL ) {
if( blk->class & ( BIG_LABEL | BLOCK_VISITED | SELECT ) ) {
blk->class |= BLOCK_VISITED;
i = blk->targets;
while( --i >= 0 ) {
son = blk->edge[ i ].destination;
if( ( son->class & BLOCK_VISITED ) == EMPTY ) {
son->class |= BLOCK_VISITED;
change = TRUE;
}
}
}
blk = blk->next_block;
}
if( change == FALSE ) break;
}
}
extern int CountIns( block *blk )
/************************************/
{
int num_instrs;
instruction *ins;
num_instrs = 0;
ins = blk->ins.hd.next;
while( ins->head.opcode != OP_BLOCK ) {
num_instrs++;
ins = ins->head.next;
}
return( num_instrs );
}
static bool FindBlock( block *target )
/****************************************/
{
block *blk;
blk = HeadBlock;
while( blk != NULL ) {
if( blk == target ) return( TRUE );
blk = blk->next_block;
}
return( FALSE );
}
extern void RemoveBlock( block *blk )
/***************************************/
{
int i;
unsigned last_line;
block *chk;
block *next;
instruction *next_ins;
if( blk->prev_block != NULL ) {
blk->prev_block->next_block = blk->next_block;
}
if( blk->next_block != NULL ) {
blk->next_block->prev_block = blk->prev_block;
}
i = 0;
while( i < blk->targets ) {
/* block may have already been removed by dead code removal*/
if( FindBlock( blk->edge[ i ].destination ) ) {
RemoveInputEdge( & blk->edge[ i ] );
}
++ i;
}
last_line = blk->ins.hd.line_num;
for( ;; ) {
next_ins = blk->ins.hd.next;
if( next_ins == (instruction *)&blk->ins ) break;
if( next_ins->head.line_num != 0 ) {
last_line = next_ins->head.line_num;
}
FreeIns( next_ins );
}
/*
Move the last line number from the block being deleted to the head
of the next block in source order, if that block doesn't already
have a line number on it.
*/
if( blk->next_block != NULL && blk->next_block->gen_id == (blk->gen_id + 1) ) {
/* quick check to see if following block is next one in src order */
next = blk->next_block;
} else {
next = NULL;
for( chk = HeadBlock; chk != NULL; chk = chk->next_block ) {
if( (chk != blk)
&& (chk->gen_id > blk->gen_id)
&& (next == NULL || next->gen_id > chk->gen_id) ) {
next = chk;
}
}
}
if( next != NULL && next->ins.hd.line_num == 0 ) {
next->ins.hd.line_num = last_line;
}
if( HeadBlock == blk ) {
HeadBlock = blk->next_block;
}
if( BlockList == blk ) {
BlockList = blk->prev_block;
if( BlockList == NULL ) {
BlockList = HeadBlock;
}
}
TellScrapLabel( blk->label );
if( blk->dataflow != NULL ) {
_Free( blk->dataflow, sizeof( data_flow_def ) );
}
FreeABlock( blk );
}
extern void RemoveInputEdge( block_edge *edge )
/*************************************************/
{
block *dest;
block_edge *prev;
if( ( edge->flags & DEST_IS_BLOCK ) == EMPTY ) return;
dest = edge->destination;
dest->inputs --;
prev = dest->input_edges;
if( prev == edge ) {
dest->input_edges = edge->next_source;
} else {
while( prev->next_source != edge ) {
prev = prev->next_source;
}
prev->next_source = edge->next_source;
}
}
extern void MoveHead( block *old, block *new )
/*************************************************
We're eliminating a loop header, so move it the the new
block and point all loop_head pointers to the new block.
*/
{
block *blk;
if( !( old->class & LOOP_HEADER ) ) return;
for( blk = HeadBlock; blk != NULL; blk = blk->next_block ) {
if( blk->loop_head == old ) {
blk->loop_head = new;
}
}
new->class |= old->class & (LOOP_HEADER|ITERATIONS_KNOWN);
old->class &= ~( LOOP_HEADER | ITERATIONS_KNOWN );
new->iterations = old->iterations;
new->loop_head = old->loop_head;
old->loop_head = new;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?