📄 igcse.c
字号:
list = list->fwd;
}
}
}
//-------------------------------------------------------------------------
static void CalculateAvailable(void)
{
int i, changed, j;
for (i = 0; i < blocknum; i++)
memcpy(blockarray[i]->block->p_aout, blockarray[i]->block->p_agen,
avail_bytes);
do
{
changed = FALSE;
for (i = 0; i < blocknum; i++)
{
BLOCK *t = blockarray[dfst[i]]->block;
BLOCKLIST *l = t->flowback;
if (l)
memset(t->p_ain, 0xff, avail_bytes);
while (l)
{
for (j = 0; j < avail_bytes; j++)t->p_ain[j] &= l->block
->p_aout[j];
l = l->link;
}
for (j = 0; j < avail_bytes; j++)
{
int v = t->p_aout[j];
t->p_aout[j] = t->p_agen[j] | (t->p_ain[j] &~t->p_akill[j]);
changed |= (v != t->p_aout[j]);
}
}
}
while (changed)
;
}
//-------------------------------------------------------------------------
static void EnterCSE(QUAD *list)
{
if (cse_count >= cse_max)
{
QUAD **newarray = oalloc(sizeof(QUAD*)*(cse_max += 16));
if (cse_count)
memcpy(newarray, csearray, sizeof(QUAD*) * cse_count);
csearray = newarray;
}
csearray[cse_count++] = list;
}
//-------------------------------------------------------------------------
static void GatherCSE(BLOCKLIST *l, QUAD *match)
{
QUAD *list;
while (l)
{
if (!(l->block->flags &BLOCKLIST_VISITED))
{
l->block->flags |= BLOCKLIST_VISITED;
list = l->block->tail;
while (list != l->block->head)
{
if (!memcmp(match, list, sizeof(struct _basic_dag)))
break;
list = list->back;
}
if (list == l->block->head)
{
GatherCSE(l->block->flowback, match);
if (csexit)
return ;
}
else
{
if (csesize != - 1000 && list->ans->size != csesize)
{
csexit = TRUE;
return ;
}
EnterCSE(list);
csesize = list->ans->size;
}
}
l = l->link;
}
}
//-------------------------------------------------------------------------
static void unvisit(void)
{
int i;
for (i = 0; i < blocknum; i++)
blockarray[i]->block->flags = 0;
}
//-------------------------------------------------------------------------
static int ScanForGCSE(BLOCK *l, int index)
{
int rv = FALSE;
QUAD *list = l->head;
QUAD *match = availarray[index];
BLOCKLIST *s;
IMODE *im, *ima;
QUAD *t;
LIST *l1;
int i, ptr, j;
SYM *sp;
memcpy(temparray4, l->p_pin, sourcebytes *pointer_count);
while (1)
{
while (list && list->back != l->tail && memcmp(match, list, sizeof
(struct _basic_dag)))
{
switch (list->dc.opcode)
{
case i_add:
case i_sub:
case i_udiv:
case i_umod:
case i_sdiv:
case i_smod:
case i_umul:
case i_smul:
case i_lsl:
case i_lsr:
case i_asl:
case i_asr:
case i_neg:
case i_not:
case i_and:
case i_or:
case i_eor:
case i_setne:
case i_sete:
case i_setc:
case i_seta:
case i_setnc:
case i_setbe:
case i_setl:
case i_setg:
case i_setle:
case i_setge:
case i_assn:
if (list->ans == match->dc.left || list->ans == match
->dc.right)
return rv;
// take pointers into account for avail & reaching
if (list->ans->mode == i_ind)
{
BYTE *t4;
ptr = findPointer(list->ans);
if (ptr < pointer_count)
{
t4 = temparray4 + ptr * sourcebytes;
if (isset(t4, 0))
{
return rv;
}
else
{
for (i = 1; i < source_count; i++)
{
if (isset(t4, i))
{
sp = varsp(sourcearray[i]->dc.left
->offset);
if (sp->imvalue == match->dc.left || sp
->imvalue == match->dc.right)
return rv;
if (sourcearray[i]->dc.right)
{
sp = sourcearray[i]->dc.right
->offset;
if (sp->imvalue == match->dc.left
|| sp->imvalue == match
->dc.right)
return rv;
}
}
}
}
}
}
else
{
ptr = findPointer(list->ans);
if (ptr < pointer_count)
{
SYM *sp = varsp(list->ans->offset);
if (sp)
{
l1 = findans(availhash, sp->imind);
if (l1)
return rv;
}
}
}
break;
case i_parm:
sp = varsp(list->dc.left->offset);
if (list->dc.left->mode == i_immed)
{
if (sp)
{
if (sp->imvalue == match->dc.left || sp->imvalue ==
match->dc.right)
return rv;
}
}
else
{
if (list->dc.left->mode == i_direct)
{
ptr = findPointer(list->dc.left);
if (ptr < pointer_count)
{
BYTE *t4 = temparray4 + ptr * sourcebytes;
if (isset(t4, 0))
return rv;
else
for (i = 1; i < source_count; i++)
{
if (isset(t4, i))
{
sp = varsp(sourcearray[i]->dc.left
->offset);
if (sp->imvalue == match->dc.left || sp
->imvalue == match->dc.right)
return rv;
sp = varsp(sourcearray[i]->dc.right
->offset);
if (sp)
if (sp->imvalue == match->dc.left
|| sp->imvalue == match
->dc.right)
return rv;
}
}
}
}
}
break;
case i_gosub:
switch (match->dc.left->offset->nodetype)
{
case en_nacon:
case en_napccon:
case en_nalabcon:
case en_labcon:
case en_absacon:
return rv;
}
switch (match->dc.right->offset->nodetype)
{
case en_nacon:
case en_napccon:
case en_nalabcon:
case en_labcon:
case en_absacon:
return rv;
}
for (i = 0; i < pointer_count; i++)
switch (pointerarray[i]->offset->nodetype)
{
case en_nacon:
case en_napccon:
case en_nalabcon:
case en_labcon:
case en_absacon:
if (isset(temparray4 + i * sourcebytes, 0))
return rv;
for (j = 1; j < source_count; j++)
{
if (sourcearray[j]->dc.left == match->dc.left)
return rv;
if (sourcearray[j]->dc.left == match->dc.right)
return rv;
if (sourcearray[j]->dc.right == match->dc.left)
return rv;
if (sourcearray[j]->dc.right == match->dc.right)
return rv;
}
break;
}
break;
}
ptrindex(list, l, temparray4);
list = list->fwd;
}
if (!list || list->back == l->tail)
return rv;
unvisit();
cse_count = 0;
csesize = - 1000;
csexit = FALSE;
GatherCSE(l->flowback, match);
if (cse_count && !csexit)
{
rv = TRUE;
im = 0;
for (i = 0; i < cse_count; i++)
{
sp = varsp(csearray[i]->ans->offset);
if (!sp->iglobal && sp->storage_class == sc_temp)
{
im = sp->imvalue;
break;
}
}
if (!im)
im = tempreg(csesize, FALSE);
for (i = 0; i < cse_count; i++)
{
if (im != csearray[i]->ans)
{
ima = csearray[i]->ans;
csearray[i]->ans = im;
t = xalloc(sizeof(QUAD));
t->ans = ima;
t->dc.left = im;
t->dc.opcode = i_assn;
t->fwd = csearray[i]->fwd;
t->fwd->back = t;
t->back = csearray[i];
t->back->fwd = t;
}
}
list->dc.left = im;
list->dc.opcode = i_assn;
list->dc.right = 0;
}
else
list = list->fwd;
}
}
//-------------------------------------------------------------------------
void gcse(void)
{
int i, j;
int done = FALSE;
availhash = oalloc(sizeof(LIST3*) * AHASH);
availhash2 = oalloc(sizeof(LIST3*) * AHASH);
tempindexarray = oalloc(sizeof(SYM*) * tempnum);
CountAvail();
CreateAvailBitArrays();
while (!done)
{
done = TRUE;
CalculateAvailBasics();
CalculateAvailable();
#ifdef DUMP_GCSE_INFO
dump_avail();
#endif
for (i = 0; i < blocknum; i++)
{
BLOCK *l = blockarray[dfst[i]]->block;
for (j = 0; j < avail_count; j++)
if (isset(l->p_ain, j))
if (ScanForGCSE(l, j))
done = FALSE;
}
}
}
//-------------------------------------------------------------------------
void gcseRundown(void)
{
cse_max = cse_count = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -