edge.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 194 行
C
194 行
/****************************************************************************
*
* 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: Manage basic block edges.
*
****************************************************************************/
#include "standard.h"
#include "coderep.h"
#include "opcodes.h"
#include "sysmacro.h"
extern block *MakeBlock(label_handle,block_num);
extern void SuffixIns(instruction *,instruction *);
extern void RemoveIns(instruction *);
extern label_handle AskForNewLabel(void);
extern byte *Copy( void *, void *, uint );
extern void FixBlockIds(void);
extern void PointEdge( block_edge *edge, block *new_dest )
/*************************************************************
Make edge point to block new_dest
*/
{
/* hook edge into new destination's input list*/
edge->next_source = new_dest->input_edges;
new_dest->input_edges = edge;
new_dest->inputs++;
/* point edge at new block*/
edge->destination = new_dest;
edge->flags = DEST_IS_BLOCK;
edge->source->targets++;
}
extern void RemoveEdge( block_edge *edge )
/*********************************************
Remove the given edge from it's block.
*/
{
block_edge *curr;
block_edge **owner;
/* unhook edge from its old destination's input list*/
if( edge->flags & DEST_IS_BLOCK ) {
owner = &edge->destination->input_edges;
for(;;) {
curr = *owner;
if( curr == edge ) break;
owner = &(*owner)->next_source;
}
*owner = curr->next_source;
edge->destination->inputs--;
}
edge->source->targets--;
}
extern void MoveEdge( block_edge *edge, block *new_dest )
/************************************************************
Move edge to point to block new_dest
*/
{
RemoveEdge( edge );
PointEdge( edge, new_dest );
}
extern block *SplitBlock( block *blk, instruction *ins )
/**********************************************************
Split a block in two before the given instruction. The first block
will simply jump to the second block, which will receive all the
edges from the previous block.
*/
{
block *new_blk;
block_edge *edge;
instruction *old;
block_num i;
new_blk = MakeBlock( AskForNewLabel(), blk->targets );
Copy( blk, new_blk, sizeof(block)+(sizeof(block_edge)*(blk->targets-1)) );
new_blk->next_block = blk->next_block;
new_blk->prev_block = blk;
blk->next_block = new_blk;
new_blk->next_block->prev_block = new_blk;
blk->class = blk->class & ~( CONDITIONAL | RETURN | SELECT |
LOOP_EXIT | UNKNOWN_DESTINATION );
blk->class |= JUMP;
blk->targets = 1;
new_blk->class = new_blk->class & ~( LOOP_HEADER );
new_blk->inputs = 0;
new_blk->input_edges = NULL;
new_blk->id = NO_BLOCK_ID;
PointEdge( &blk->edge[ 0 ], new_blk );
edge = &new_blk->edge[ 0 ];
i = 0;
while( i < new_blk->targets ) {
edge->source = new_blk;
edge++;
i++;
}
while( ins->head.opcode != OP_BLOCK ) {
old = ins;
ins = ins->head.next;
RemoveIns( old );
SuffixIns( new_blk->ins.hd.prev, old );
};
FixBlockIds();
return( new_blk );
}
typedef struct edge_entry {
struct edge_entry *next;
block_edge *edge;
} edge_entry;
typedef struct edge_stack {
edge_entry *top;
} edge_stack;
extern edge_stack *EdgeStackInit( void )
/********************************************/
{
edge_stack *stk;
_Alloc( stk, sizeof( edge_stack ) );
stk->top = NULL;
return( stk );
}
extern bool EdgeStackEmpty( edge_stack *stk )
/*******************************************************/
{
return( stk->top == NULL );
}
extern void EdgeStackPush( edge_stack *stk, block_edge *edge )
/************************************************************************/
{
edge_entry *new_entry;
_Alloc( new_entry, sizeof( edge_entry ) );
new_entry->edge = edge;
new_entry->next = stk->top;
stk->top = new_entry;
}
extern block_edge *EdgeStackPop( edge_stack *stk )
/******************************************************/
{
edge_entry *top;
block_edge *edge;
if( stk->top != NULL ) {
top = stk->top;
edge = top->edge;
stk->top = top->next;
_Free( top, sizeof( edge_entry ) );
return( edge );
}
return( NULL );
}
extern void EdgeStackFini( edge_stack *stk )
/******************************************************/
{
while( !EdgeStackEmpty( stk ) ) {
EdgeStackPop( stk );
}
_Free( stk, sizeof( edge_stack ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?