📄 iblock.c
字号:
if (node)
{
if (node->ans->size == new->dc.left->size || node->ans->size == - new
->dc.left->size)
new->dc.left = node;
else
new->livein |= IM_LIVELEFT;
}
else {
if (!ToQuadConst(&new->dc.left))
new->livein |= IM_LIVELEFT;
}
node = LookupNVHash(&new->dc.right, sizeof(void*), name_hash);
if (node)
{
if (node->ans->size == new->dc.right->size || node->ans->size == - new
->dc.right->size)
new->dc.right = node;
else
new->livein |= IM_LIVERIGHT;
}
else {
if (!ToQuadConst(&new->dc.right))
new->livein |= IM_LIVERIGHT;
}
/* constant folding, now! */
ConstantFold(new);
/* Now replace the CSE or enter it into the table */
node = LookupNVHash(new, DAGCOMPARE, ins_hash);
if (!node)
{
if (prm_locsub)
/* take care of volatiles by not registering volatile expressions
* in the CSE table. At this point a temp var will already exist
* in the case that a volatile exists as the answer.
*/
if (new->ans && !(new->ans->offset && (new->ans->offset->cflags
&DF_VOL) || (new->dc.left && (new->livein & IM_LIVELEFT) && new->dc.left->offset && (new
->dc.left->offset->cflags &DF_VOL)
) || (new->dc.right && (new->livein & IM_LIVERIGHT) && new->dc.right->vol)))
if (new->ans->mode == i_direct && new->ans->offset->nodetype == en_tempref)
ReplaceHash(new, new, DAGCOMPARE, ins_hash);
/* convert back to a quad structure and generate code */
node = new;
outnode = liveout(node);
add_intermed(outnode);
}
else
{
outnode = xalloc(sizeof(QUAD));
outnode->dc.opcode = i_assn;
outnode->ans = new->ans;
outnode->dc.left = node->ans;
add_intermed(outnode);
}
/* Save the new node structure for later lookups
* always save constants even when no LCSE is to be done because it
* is needed for constant-folding in subsequent instructions
*/
if (new->ans && (prm_locsub || node->dc.opcode == i_icon || node->dc.opcode
== i_fcon || node->dc.opcode == i_imcon || node->dc.opcode == i_cxcon))
ReplaceHash(node, &new->ans, sizeof(void*), name_hash);
}
//-------------------------------------------------------------------------
static void flush_dag(void)
{
int i;
if (name_hash)
{
memset(name_hash, 0, sizeof(void*) * DAGSIZE);
memset(ins_hash, 0, sizeof(void*) * DAGSIZE);
}
}
//-------------------------------------------------------------------------
void dag_rundown(void)
{
name_hash = ins_hash = 0;
}
//-------------------------------------------------------------------------
void addblock(int val)
/*
* create a block
*/
{
BLOCKLIST *list;
BLOCK *block;
QUAD *q;
if (blockhead)
{
blocktail->block->tail = intermed_tail;
}
switch (val)
{
case i_ret:
case i_rett:
return ;
}
/* block statement gets included */
q = xalloc(sizeof(QUAD));
q->dc.opcode = i_block;
q->ans = q->dc.right = 0;
q->dc.label = blocknum;
add_intermed(q);
/* now make a basic block and add to the blocklist */
block = xalloc(sizeof(BLOCK));
list = xalloc(sizeof(BLOCK));
list->link = 0;
list->block = block;
block->flowback = 0;
block->flowfwd = 0;
block->blocknum = blocknum++;
if (blockhead == 0)
blockhead = blocktail = list;
else
blocktail = blocktail->link = list;
block->head = intermed_tail;
}
/*
* intermed code poitners
*/
void gen_label(int labno)
/*
* add a compiler generated label to the intermediate list.
*/
{
QUAD *new;
flush_dag();
if (!wasgoto)
addblock(i_label);
wasgoto = FALSE;
new = xalloc(sizeof(QUAD));
new->dc.opcode = i_label;
new->dc.label = labno;
add_intermed(new);
}
//-------------------------------------------------------------------------
void gen_icode(int op, IMODE *res, IMODE *left, IMODE *right)
/*
* generate a code sequence into the peep list.
*/
{
QUAD *new;
switch (op)
{
case i_ret:
case i_rett:
flush_dag();
break;
}
new = xalloc(sizeof(QUAD));
new->dc.opcode = op;
new->dc.left = left;
new->dc.right = right;
new->ans = res;
add_dag(new);
switch (op)
{
case i_ret:
case i_rett:
flush_dag();
addblock(op);
}
wasgoto = FALSE;
}
//-------------------------------------------------------------------------
void gen_iiconst(IMODE *res, LLONG_TYPE val)
/*
* generate an integer constant sequence into the peep list.
*/
{
QUAD *new;
new = xalloc(sizeof(QUAD));
new->dc.opcode = i_icon;
new->dc.v.i = val;
new->ans = res;
add_dag(new);
wasgoto = FALSE;
}
//-------------------------------------------------------------------------
void gen_ifconst(IMODE *res, long double val)
/*
* generate an integer constant sequence into the peep list.
*/
{
QUAD *new;
new = xalloc(sizeof(QUAD));
new->dc.opcode = i_fcon;
new->dc.v.f = val;
new->ans = res;
add_dag(new);
wasgoto = FALSE;
}
//-------------------------------------------------------------------------
void gen_igoto(long label)
/*
* generate a code sequence into the peep list.
*/
{
QUAD *new;
flush_dag();
new = xalloc(sizeof(QUAD));
new->dc.opcode = i_goto;
new->dc.left = new->dc.right = new->ans = 0;
new->dc.label = label;
add_intermed(new);
addblock(i_goto);
wasgoto = TRUE;
}
//-------------------------------------------------------------------------
void gen_idc(long label)
/*
* generate a code sequence into the peep list.
*/
{
QUAD *new;
flush_dag();
new = xalloc(sizeof(QUAD));
new->dc.opcode = i_dc;
new->dc.left = new->dc.right = new->ans = 0;
new->dc.label = label;
add_intermed(new);
wasgoto = FALSE;
}
//-------------------------------------------------------------------------
void gen_data(int val)
{
QUAD *new;
flush_dag();
new = xalloc(sizeof(QUAD));
new->dc.opcode = i_genword;
new->dc.left = new->dc.right = new->ans = 0;
new->dc.label = val;
add_intermed(new);
wasgoto = FALSE;
}
//-------------------------------------------------------------------------
void gen_icgoto(int op, long label, IMODE *left, IMODE *right)
/*
* generate a code sequence into the peep list.
*/
{
QUAD *new;
new = xalloc(sizeof(QUAD));
new->dc.opcode = op;
new->dc.left = left;
new->dc.right = right;
new->ans = 0;
new->dc.label = label;
add_dag(new);
flush_dag();
addblock(op);
wasgoto = TRUE;
}
//-------------------------------------------------------------------------
void gen_igosub(int op, IMODE *left)
/*
* generate a code sequence into the peep list.
*/
{
QUAD *new;
new = xalloc(sizeof(QUAD));
new->dc.opcode = op;
new->dc.left = left;
new->dc.right = 0;
new->ans = 0;
new->dc.label = 0;
add_dag(new);
flush_dag();
addblock(op);
wasgoto = TRUE;
}
//-------------------------------------------------------------------------
void gen_icode2(int op, IMODE *res, IMODE *left, IMODE *right, int label)
/*
* generate a code sequence into the peep list.
*/
{
QUAD *new;
new = xalloc(sizeof(QUAD));
new->dc.opcode = op;
new->dc.left = left;
new->dc.right = right;
new->ans = res;
new->dc.label = label;
add_intermed(new);
wasgoto = FALSE;
}
//-------------------------------------------------------------------------
void gen_line(SNODE *stmt)
/*
* generate a line number statement
*/
{
QUAD *new;
new = xalloc(sizeof(QUAD));
new->dc.opcode = i_line;
new->dc.left = (IMODE*)stmt->label;
new->dc.label = (long)stmt->exp;
add_intermed(new);
}
//-------------------------------------------------------------------------
void gen_asm(SNODE *stmt)
/*
* generate an ASM statement
*/
{
QUAD *new;
new = xalloc(sizeof(QUAD));
new->dc.opcode = i_passthrough;
new->dc.left = (IMODE*)stmt->exp;
flush_dag();
add_intermed(new);
}
//-------------------------------------------------------------------------
void gen_nodag(int op, IMODE *res, IMODE *left, IMODE *right)
/*
* generate a code sequence into the peep list.
*/
{
QUAD *new;
new = xalloc(sizeof(QUAD));
new->dc.opcode = op;
new->dc.left = left;
new->dc.right = right;
new->ans = res;
add_intermed(new);
wasgoto = FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -