insutil.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 492 行 · 第 1/2 页
C
492 行
/****************************************************************************
*
* 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: Instruction data manipulation routines.
*
****************************************************************************/
#include "standard.h"
#include "coderep.h"
#include "conflict.h"
#include "opcodes.h"
#include "pattern.h"
#include "procdef.h"
#include "sysmacro.h"
#include "zoiks.h"
typedef enum {
CB_FOR_INS1 = 0x01,
CB_FOR_INS2 = 0x02,
CB_NONE = 0x00
} conflict_bits;
typedef struct conflict_info {
conflict_node *conf;
conflict_bits flags;
} conflict_info;
extern block *HeadBlock;
extern conflict_node *ConfList;
extern bool HaveLiveInfo;
extern void FreeIns(instruction*);
extern void UpdateLive(instruction*,instruction*);
extern name *DeAlias(name*);
extern int CountIns(block*);
#define MAX_CONF_INFO (2*( MAX_OPS_PER_INS+1 )+1)
static int CurrInfo;
static conflict_info ConflictInfo[ MAX_CONF_INFO ];
static void RenumFrom( instruction *ins ) {
/*****************************************/
block *blk;
instruction_id id;
if( ins->head.opcode == OP_BLOCK ) {
Renumber();
} else {
id = ins->id;
ins = ins->head.next;
for( ;; ) {
while( ins->head.opcode != OP_BLOCK ) {
++id;
if( ins->id > id ) return;
ins->id = id;
ins = ins->head.next;
}
blk = _BLOCK( ins )->next_block;
if( blk == NULL ) break;
ins = blk->ins.hd.next;
}
}
}
static conflict_info *AddConfInfo( conflict_node *conf ) {
/***********************************************************/
conflict_info *info;
if( conf->state & CONF_VISITED ) {
info = &ConflictInfo[ 0 ];
for( info = &ConflictInfo[ 0 ];; ++info ) {
if( info->conf == conf ) return( info );
}
} else {
info = &ConflictInfo[ CurrInfo++ ];
info->conf = conf;
conf->state |= CONF_VISITED;
}
return( info );
}
static void FindNameConf( name *name, instruction *ins,
instruction *other, conflict_bits for_which ) {
/***********************************************************************/
conflict_node *conf;
conflict_info *info;
if( name->n.class == N_INDEXED ) {
name = name->i.index;
}
if( name->n.class == N_TEMP ) {
name = DeAlias( name );
} else if( name->n.class != N_MEMORY ) {
return;
}
conf = name->v.conflict;
info = NULL;
while( conf != NULL && info == NULL ) {
if( conf->ins_range.first == ins
|| conf->ins_range.first == other
|| conf->ins_range.last == ins
|| conf->ins_range.last == other ) {
info = AddConfInfo( conf );
info->flags |= for_which;
}
conf = conf->next_for_name;
}
}
static void FindAllConflicts( instruction *ins,
instruction *other, conflict_bits for_which ) {
/***************************************************************************/
int i;
i = ins->num_operands;
while( --i >= 0 ) {
FindNameConf( ins->operands[ i ], ins, other, for_which );
}
if( ins->result != NULL ) {
FindNameConf( ins->result, ins, other, for_which );
}
}
static void MakeConflictInfo( instruction *ins1, instruction *ins2 ) {
/************************************************************************/
int i;
conflict_info *info;
for( i = 0; i < MAX_CONF_INFO; ++i ) {
ConflictInfo[ i ].conf = NULL;
ConflictInfo[ i ].flags = CB_NONE;
}
CurrInfo = 0;
FindAllConflicts( ins1, ins2, CB_FOR_INS1 );
FindAllConflicts( ins2, ins1, CB_FOR_INS2 );
for( info = ConflictInfo; info->conf != NULL; ++info ) {
info->conf->state &= ~CONF_VISITED;
}
}
extern void PrefixInsRenum( instruction *ins, instruction *pref, bool renum ) {
/*****************************************************************/
conflict_info *info;
conflict_node *conf;
block *blk;
instruction *next;
/* Link the new instruction into the instruction ring*/
/* If renum = true, assign id and renumber. renum can be false only */
/* if you're going to call Renumber() manually. */
_INS_NOT_BLOCK( pref );
pref->head.prev = ins->head.prev;
pref->head.prev->head.next = pref;
pref->head.next = ins;
ins->head.prev = pref;
if( ins->head.opcode != OP_BLOCK ) {
pref->head.line_num = ins->head.line_num;
ins->head.line_num = 0;
pref->stk_entry = ins->stk_entry;
pref->stk_exit = ins->stk_entry;
// pref->s.stk_extra = ins->s.stk_extra;
pref->sequence = ins->sequence;
pref->id = ins->id;
} else {
pref->head.line_num = 0;
if ( renum ) {
/*
* Oops. There is no id in OP_BLOCK and assigned id will be invalid.
* This condition happens sometimes in loop optimizer.
* NOTE: this case can be a bug. It means that we're trying to add
* last instruction to the block. But other code can expect that
* last instruction is NOP, but it'll not.
* Currently we'll try to find next instruction with valid id.
*/
next = ins;
for (;;) {
blk = _BLOCK( next )->next_block;
if( blk == NULL ) {
Zoiks( ZOIKS_141 );
break;
}
next = blk->ins.hd.next;
if ( next->head.opcode != OP_BLOCK ) break;
}
pref->id = next->id;
}
}
if ( renum ) {
RenumFrom( pref );
}
if( HaveLiveInfo ) {
/* move the first/last pointers of any relevant conflict nodes */
if( ins->head.opcode != OP_BLOCK ) {
MakeConflictInfo( pref, ins );
for( info = ConflictInfo; info->conf != NULL; ++info ) {
if( info->flags & CB_FOR_INS1 ) {
conf = info->conf;
if( !( info->flags & CB_FOR_INS2 ) ) {
if( conf->ins_range.last == ins ) {
conf->ins_range.last = pref;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?