under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding!
+ what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
#include "common.h"
+#include "newalloc.h"
/*-----------------------------------------------------------------*/
/* newCseDef - new cseDef */
cseDef *newCseDef (operand *sym, iCode *ic)
{
cseDef *cdp ;
-
+
assert (sym);
- ALLOC(cdp,sizeof(cseDef));
+ cdp = Safe_calloc(1,sizeof(cseDef));
cdp->sym = sym;
cdp->diCode = ic;
- cdp->key = sym->key;
-
+ cdp->key = sym->key;
+
return cdp;
}
int isCseDefEqual ( void *vsrc, void *vdest)
{
cseDef *src = vsrc;
- cseDef *dest = vdest;
+ cseDef *dest = vdest;
if (src == dest)
- return 1;
-
+ return 1;
+
return (src->key == dest->key &&
- src->diCode == dest->diCode ) ;
-
+ src->diCode == dest->diCode ) ;
+
}
/*-----------------------------------------------------------------*/
iCodeTable *icTab ;
(void)ap;
-
+
if (!cdp->sym)
- fprintf(stdout,"**null op**");
+ fprintf(stdout,"**null op**");
printOperand(cdp->sym,stdout);
icTab = getTableEntry(cdp->diCode->op) ;
icTab->iCodePrint(stdout,cdp->diCode,icTab->printName);
iCode *lic;
for (lic = ic ; lic ; lic = lic->next ) {
- int siaddr ;
-
- /* do the special cases first */
- if (lic->op == IFX) {
- if (IS_SYMOP(to) &&
- IC_COND(lic)->key == from->key) {
-
- bitVectUnSetBit (OP_USES(from),lic->key);
- OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
- siaddr = IC_COND(lic)->isaddr ;
- IC_COND(lic) = operandFromOperand(to);
- IC_COND(lic)->isaddr = siaddr ;
-
- }
- continue ;
- }
-
- if (lic->op == JUMPTABLE) {
- if (IS_SYMOP(to) &&
- IC_JTCOND(lic)->key == from->key) {
-
- bitVectUnSetBit (OP_USES(from),lic->key);
- OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
- siaddr = IC_COND(lic)->isaddr ;
- IC_JTCOND(lic) = operandFromOperand(to);
- IC_JTCOND(lic)->isaddr = siaddr ;
-
- }
- continue ;
- }
-
- if (IC_RESULT(lic) && IC_RESULT(lic)->key == from->key ) {
- /* maintain du chains */
- if (POINTER_SET(lic)) {
- bitVectUnSetBit (OP_USES(from),lic->key);
- OP_USES(to) = bitVectSetBit (OP_USES(to),lic->key);
-
- /* also check if the "from" was in the non-dominating
- pointer sets and replace it with "to" in the bitVector */
- if (bitVectBitValue(*ndpset,from->key)) {
- bitVectUnSetBit(*ndpset,from->key);
- bitVectSetBit(*ndpset,to->key);
- }
-
- }
- else {
- bitVectUnSetBit (OP_DEFS(from),lic->key);
- OP_DEFS(to) = bitVectSetBit (OP_DEFS(to),lic->key);
- }
- siaddr = IC_RESULT(lic)->isaddr ;
- IC_RESULT(lic) = operandFromOperand(to);
- IC_RESULT(lic)->isaddr = siaddr ;
- }
-
- if (IS_SYMOP(to) &&
- IC_RIGHT(lic) && IC_RIGHT(lic)->key == from->key ) {
- bitVectUnSetBit (OP_USES(from),lic->key);
- OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
- siaddr = IC_RIGHT(lic)->isaddr ;
- IC_RIGHT(lic) = operandFromOperand(to);
- IC_RIGHT(lic)->isaddr = siaddr ;
- }
-
- if (IS_SYMOP(to) &&
- IC_LEFT(lic) && IC_LEFT(lic)->key == from->key ) {
- bitVectUnSetBit (OP_USES(from),lic->key);
- OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
- siaddr = IC_LEFT(lic)->isaddr ;
- IC_LEFT(lic) = operandFromOperand(to);
- IC_LEFT(lic)->isaddr = siaddr ;
- }
+ int siaddr ;
+
+ /* do the special cases first */
+ if (lic->op == IFX) {
+ if (IS_SYMOP(to) &&
+ IC_COND(lic)->key == from->key) {
+
+ bitVectUnSetBit (OP_USES(from),lic->key);
+ OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
+ siaddr = IC_COND(lic)->isaddr ;
+ IC_COND(lic) = operandFromOperand(to);
+ IC_COND(lic)->isaddr = siaddr ;
+
+ }
+ continue ;
+ }
+
+ if (lic->op == JUMPTABLE) {
+ if (IS_SYMOP(to) &&
+ IC_JTCOND(lic)->key == from->key) {
+
+ bitVectUnSetBit (OP_USES(from),lic->key);
+ OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
+ siaddr = IC_COND(lic)->isaddr ;
+ IC_JTCOND(lic) = operandFromOperand(to);
+ IC_JTCOND(lic)->isaddr = siaddr ;
+
+ }
+ continue ;
+ }
+
+ if (IC_RESULT(lic) && IC_RESULT(lic)->key == from->key ) {
+ /* maintain du chains */
+ if (POINTER_SET(lic)) {
+ bitVectUnSetBit (OP_USES(from),lic->key);
+ OP_USES(to) = bitVectSetBit (OP_USES(to),lic->key);
+
+ /* also check if the "from" was in the non-dominating
+ pointer sets and replace it with "to" in the bitVector */
+ if (bitVectBitValue(*ndpset,from->key)) {
+ bitVectUnSetBit(*ndpset,from->key);
+ bitVectSetBit(*ndpset,to->key);
+ }
+
+ }
+ else {
+ bitVectUnSetBit (OP_DEFS(from),lic->key);
+ OP_DEFS(to) = bitVectSetBit (OP_DEFS(to),lic->key);
+ }
+ siaddr = IC_RESULT(lic)->isaddr ;
+ IC_RESULT(lic) = operandFromOperand(to);
+ IC_RESULT(lic)->isaddr = siaddr ;
+ }
+
+ if (IS_SYMOP(to) &&
+ IC_RIGHT(lic) && IC_RIGHT(lic)->key == from->key ) {
+ bitVectUnSetBit (OP_USES(from),lic->key);
+ OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
+ siaddr = IC_RIGHT(lic)->isaddr ;
+ IC_RIGHT(lic) = operandFromOperand(to);
+ IC_RIGHT(lic)->isaddr = siaddr ;
+ }
+
+ if (IS_SYMOP(to) &&
+ IC_LEFT(lic) && IC_LEFT(lic)->key == from->key ) {
+ bitVectUnSetBit (OP_USES(from),lic->key);
+ OP_USES(to) = bitVectSetBit(OP_USES(to),lic->key);
+ siaddr = IC_LEFT(lic)->isaddr ;
+ IC_LEFT(lic) = operandFromOperand(to);
+ IC_LEFT(lic)->isaddr = siaddr ;
+ }
}
}
V_ARG(int,key);
if (cdp->diCode->key == key)
- return 1;
+ return 1;
else
- return 0;
+ return 0;
}
/*-----------------------------------------------------------------*/
V_ARG(eBBlock *,cbp);
if (ebp->visited)
- return 0;
+ return 0;
ebp->visited = 1;
deleteItemIf(&ebp->inExprs,iCodeKeyIs,ic->key);
if (ebp != cbp && !bitVectBitValue(cbp->domVect,ebp->bbnum))
- replaceAllSymBySym(ebp->sch,from,to,&ebp->ndompset);
+ replaceAllSymBySym(ebp->sch,from,to,&ebp->ndompset);
applyToSet(ebp->succList,removeFromInExprs,ic,from,to,cbp);
return 0;
/*-----------------------------------------------------------------*/
static bool isGlobalInNearSpace (operand *op)
{
- link *type = getSpec(operandType(op));
+ sym_link *type = getSpec(operandType(op));
/* this is 8051 specific: optimization
suggested by Jean-Louis VERN, with 8051s we have no
advantage of putting variables in near space into
registers */
- if (isOperandGlobal(op) &&
- IN_DIRSPACE(SPEC_OCLS(type)))
- return TRUE;
+ if (isOperandGlobal(op) && !IN_FARSPACE(SPEC_OCLS(type)) &&
+ IN_DIRSPACE(SPEC_OCLS(type)))
+ return TRUE;
else
- return FALSE;
+ return FALSE;
}
/*-----------------------------------------------------------------*/
/* findCheaperOp - cseBBlock support routine, will check to see if */
/* we have a operand previously defined */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(findCheaperOp)
+DEFSETFUNC(findCheaperOp)
{
- cseDef *cdp = item ;
+ cseDef *cdp = item ;
V_ARG(operand *,cop);
V_ARG(operand **,opp);
/* if we have already found it */
- if (*opp)
- return 1;
+ if (*opp)
+ return 1;
/* not found it yet check if this is the one */
/* and this is not the defining one */
if (cop->key == cdp->key) {
- /* do a special check this will help in */
- /* constant propagation & dead code elim*/
- /* for assignments only */
- if (cdp->diCode->op == '=') {
- /* if the result is volatile then return result */
- if (IS_OP_VOLATILE (IC_RESULT(cdp->diCode)))
- *opp = IC_RESULT(cdp->diCode);
- else
- /* if this is a straight assignment and
- left is a temp then prefer the temporary to the
- true symbol */
- if (!POINTER_SET(cdp->diCode) &&
- IS_ITEMP(IC_RESULT(cdp->diCode)) &&
- IS_TRUE_SYMOP(IC_RIGHT(cdp->diCode)))
- *opp = IC_RESULT(cdp->diCode);
- else
- /* if straight assignement && and both
- are temps then prefer the one that
- will not need extra space to spil, also
- take into consideration if right side
- an induction variable
- */
- if (!POINTER_SET(cdp->diCode) &&
- IS_ITEMP(IC_RESULT(cdp->diCode)) &&
- IS_ITEMP(IC_RIGHT(cdp->diCode)) &&
- !OP_SYMBOL(IC_RIGHT(cdp->diCode))->isind &&
- ( (!SPIL_LOC(IC_RIGHT(cdp->diCode)) &&
- SPIL_LOC(IC_RESULT(cdp->diCode))) ||
- ( SPIL_LOC(IC_RESULT(cdp->diCode)) &&
- SPIL_LOC(IC_RESULT(cdp->diCode)) ==
- SPIL_LOC(IC_RIGHT(cdp->diCode))) )
- )
- *opp = IC_RESULT(cdp->diCode);
- else
- *opp = IC_RIGHT(cdp->diCode);
- }
- else
- *opp = IC_RESULT(cdp->diCode) ;
+ /* do a special check this will help in */
+ /* constant propagation & dead code elim*/
+ /* for assignments only */
+ if (cdp->diCode->op == '=') {
+ /* if the result is volatile then return result */
+ if (IS_OP_VOLATILE (IC_RESULT(cdp->diCode)))
+ *opp = IC_RESULT(cdp->diCode);
+ else
+ /* if this is a straight assignment and
+ left is a temp then prefer the temporary to the
+ true symbol */
+ if (!POINTER_SET(cdp->diCode) &&
+ IS_ITEMP(IC_RESULT(cdp->diCode)) &&
+ IS_TRUE_SYMOP(IC_RIGHT(cdp->diCode)))
+ *opp = IC_RESULT(cdp->diCode);
+ else
+ /* if straight assignement && and both
+ are temps then prefer the one that
+ will not need extra space to spil, also
+ take into consideration if right side
+ an induction variable
+ */
+ if (!POINTER_SET(cdp->diCode) &&
+ IS_ITEMP(IC_RESULT(cdp->diCode)) &&
+ IS_ITEMP(IC_RIGHT(cdp->diCode)) &&
+ !OP_SYMBOL(IC_RIGHT(cdp->diCode))->isind &&
+ ( (!SPIL_LOC(IC_RIGHT(cdp->diCode)) &&
+ SPIL_LOC(IC_RESULT(cdp->diCode))) ||
+ ( SPIL_LOC(IC_RESULT(cdp->diCode)) &&
+ SPIL_LOC(IC_RESULT(cdp->diCode)) ==
+ SPIL_LOC(IC_RIGHT(cdp->diCode))) )
+ )
+ *opp = IC_RESULT(cdp->diCode);
+ else
+ *opp = IC_RIGHT(cdp->diCode);
+ }
+ else
+ *opp = IC_RESULT(cdp->diCode) ;
}
/* if this is an assign to a temp. then check
if the right side is this then return this */
- if (IS_TRUE_SYMOP(cop) &&
- cdp->diCode->op == '=' &&
- !POINTER_SET(cdp->diCode) &&
- cop->key == IC_RIGHT(cdp->diCode)->key &&
- !isGlobalInNearSpace (IC_RIGHT(cdp->diCode)) &&
- IS_ITEMP(IC_RESULT(cdp->diCode)))
- *opp = IC_RESULT(cdp->diCode);
+ if (IS_TRUE_SYMOP(cop) &&
+ cdp->diCode->op == '=' &&
+ !POINTER_SET(cdp->diCode) &&
+ cop->key == IC_RIGHT(cdp->diCode)->key &&
+ !isGlobalInNearSpace (IC_RIGHT(cdp->diCode)) &&
+ IS_ITEMP(IC_RESULT(cdp->diCode)))
+ *opp = IC_RESULT(cdp->diCode);
if (*opp) {
- if ((isGlobalInNearSpace(cop) &&
- !isOperandLiteral(*opp)) ||
- isOperandVolatile(*opp,FALSE)
- ) {
- *opp = NULL;
- return 0;
- }
-
- if (cop->key == (*opp)->key ) {
- *opp = NULL ;
- return 0;
- }
-
- if ((*opp)->isaddr != cop->isaddr && IS_ITEMP(cop)) {
- *opp = operandFromOperand(*opp);
- (*opp)->isaddr = cop->isaddr;
- }
-
- return 1;
-
+ if ((isGlobalInNearSpace(cop) &&
+ !isOperandLiteral(*opp)) ||
+ isOperandVolatile(*opp,FALSE)
+ ) {
+ *opp = NULL;
+ return 0;
+ }
+
+ if (cop->key == (*opp)->key ) {
+ *opp = NULL ;
+ return 0;
+ }
+
+ if ((*opp)->isaddr != cop->isaddr && IS_ITEMP(cop)) {
+ *opp = operandFromOperand(*opp);
+ (*opp)->isaddr = cop->isaddr;
+ }
+
+ return 1;
+
}
-
+
return 0;
}
V_ARG(operand *,rop);
if (POINTER_SET(cdp->diCode) &&
- IC_RESULT(cdp->diCode)->key == op->key &&
- !isOperandVolatile(IC_RESULT(cdp->diCode),TRUE) &&
- !isOperandVolatile(IC_RIGHT(cdp->diCode),TRUE) &&
- getSize(operandType(IC_RIGHT(cdp->diCode))) ==
- getSize(operandType(rop))) {
- *opp = IC_RIGHT(cdp->diCode);
- return 1;
+ IC_RESULT(cdp->diCode)->key == op->key &&
+ !isOperandVolatile(IC_RESULT(cdp->diCode),TRUE) &&
+ !isOperandVolatile(IC_RIGHT(cdp->diCode),TRUE) &&
+ getSize(operandType(IC_RIGHT(cdp->diCode))) ==
+ getSize(operandType(rop))) {
+ *opp = IC_RIGHT(cdp->diCode);
+ return 1;
}
return 0;
/*-----------------------------------------------------------------*/
DEFSETFUNC(findPrevIc)
{
- cseDef *cdp = item ;
+ cseDef *cdp = item ;
V_ARG(iCode *,ic);
V_ARG(iCode **,icp);
/* if already found */
if (*icp)
- return 1;
-
+ return 1;
+
/* if the iCodes are the same */
- if (isiCodeEqual(ic,cdp->diCode) &&
- isOperandEqual(cdp->sym,IC_RESULT(cdp->diCode))) {
- *icp = cdp->diCode ;
- return 1;
+ if (isiCodeEqual(ic,cdp->diCode) &&
+ isOperandEqual(cdp->sym,IC_RESULT(cdp->diCode))) {
+ *icp = cdp->diCode ;
+ return 1;
}
/* if iCodes are not the same */
/* see the operands maybe interchanged */
if (ic->op == cdp->diCode->op &&
- ( ic->op == '+' || ic->op == '*' ) &&
- isOperandEqual(IC_LEFT(ic),IC_RIGHT(cdp->diCode)) &&
- isOperandEqual(IC_RIGHT(ic),IC_LEFT(cdp->diCode))) {
- *icp = cdp->diCode ;
- return 1;
+ ( ic->op == '+' || ic->op == '*' ) &&
+ isOperandEqual(IC_LEFT(ic),IC_RIGHT(cdp->diCode)) &&
+ isOperandEqual(IC_RIGHT(ic),IC_LEFT(cdp->diCode))) {
+ *icp = cdp->diCode ;
+ return 1;
}
return 0;
DEFSETFUNC(ifDefGlobal)
{
cseDef *cdp = item;
-
+
return (isOperandGlobal(cdp->sym));
}
+/*-----------------------------------------------------------------*/
+/* ifAnyGetPointer - if get pointer icode */
+/*-----------------------------------------------------------------*/
+DEFSETFUNC(ifAnyGetPointer)
+{
+ cseDef *cdp = item;
+
+ if (cdp->diCode && POINTER_GET(cdp->diCode)) return 1;
+ return 0;
+}
+
/*-----------------------------------------------------------------*/
/* ifOperandsHave - if any of the operand are the same as this */
/*-----------------------------------------------------------------*/
DEFSETFUNC(ifOperandsHave)
{
- cseDef *cdp = item;
- V_ARG(operand *,op);
-
-
- if (IC_LEFT(cdp->diCode) &&
- IS_SYMOP(IC_LEFT(cdp->diCode)) &&
- IC_LEFT(cdp->diCode)->key == op->key)
- return 1;
-
+ cseDef *cdp = item;
+ V_ARG(operand *,op);
+
+
+ if (IC_LEFT(cdp->diCode) &&
+ IS_SYMOP(IC_LEFT(cdp->diCode)) &&
+ IC_LEFT(cdp->diCode)->key == op->key)
+ return 1;
+
if (IC_RIGHT(cdp->diCode) &&
- IS_SYMOP(IC_RIGHT(cdp->diCode)) &&
- IC_RIGHT(cdp->diCode)->key == op->key)
- return 1;
-
+ IS_SYMOP(IC_RIGHT(cdp->diCode)) &&
+ IC_RIGHT(cdp->diCode)->key == op->key)
+ return 1;
+
/* or if any of the operands are volatile */
- if (IC_LEFT(cdp->diCode) &&
- IS_OP_VOLATILE(IC_LEFT(cdp->diCode)))
- return 1;
+ if (IC_LEFT(cdp->diCode) &&
+ IS_OP_VOLATILE(IC_LEFT(cdp->diCode)))
+ return 1;
+
+ if (IC_RIGHT(cdp->diCode) &&
+ IS_OP_VOLATILE(IC_RIGHT(cdp->diCode)))
+ return 1;
- if (IC_RIGHT(cdp->diCode) &&
- IS_OP_VOLATILE(IC_RIGHT(cdp->diCode)))
- return 1;
-
- if (IC_RESULT(cdp->diCode) &&
- IS_OP_VOLATILE(IC_RESULT(cdp->diCode)))
- return 1;
+ if (IC_RESULT(cdp->diCode) &&
+ IS_OP_VOLATILE(IC_RESULT(cdp->diCode)))
+ return 1;
return 0;
}
set *sl ;
if (!sym || !IS_SYMOP(sym))
- return 0;
+ return 0;
for (sl = cseSet ; sl ; sl = sl->next ) {
- loop = sl->item;
- if (loop->sym->key == sym->key )
- return 1;
+ loop = sl->item;
+ if (loop->sym->key == sym->key )
+ return 1;
}
return 0;
}
/* ifDefSymIsX - will return 1 if the symbols match */
/*-----------------------------------------------------------------*/
DEFSETFUNC(ifDefSymIsX)
-{
+{
cseDef *cdp = item;
- V_ARG(operand *,op);
+ V_ARG(operand *,op);
if (op && cdp->sym)
- return cdp->sym->key == op->key ;
+ return cdp->sym->key == op->key ;
else
- return ( isOperandEqual(cdp->sym,op) );
-
-}
+ return ( isOperandEqual(cdp->sym,op) );
+
+}
/*-----------------------------------------------------------------*/
{
cseDef *loop;
set *sl;
-
+
if (!ic)
- return 0;
+ return 0;
for (sl = cseSet ; sl ; sl = sl->next ) {
- loop = sl->item ;
- if (loop->diCode == ic)
- return 1;
+ loop = sl->item ;
+ if (loop->diCode == ic)
+ return 1;
}
return 0;
-
+
}
/*-----------------------------------------------------------------*/
operand *left = IC_LEFT(cdp->diCode);
if (POINTER_GET(dic) && left->key == op->key)
- return 1;
+ return 1;
return 0;
}
V_ARG(operand *,op);
if (POINTER_SET(cdp->diCode) &&
- IC_RESULT(cdp->diCode)->key == op->key)
- return 1;
+ IC_RESULT(cdp->diCode)->key == op->key)
+ return 1;
return 0;
}
/* ifDiCodeIsX - will return 1 if the symbols match */
/*-----------------------------------------------------------------*/
DEFSETFUNC(ifDiCodeIsX)
-{
+{
cseDef *cdp = item;
- V_ARG(iCode *,ic);
+ V_ARG(iCode *,ic);
return cdp->diCode == ic;
-
+
}
/*-----------------------------------------------------------------*/
/* we don't deal with the following iCodes
here */
if (ic->op == IFX ||
- ic->op == IPUSH ||
- ic->op == IPOP ||
- ic->op == CALL ||
- ic->op == PCALL ||
- ic->op == RETURN ||
- POINTER_GET(ic))
- return ;
+ ic->op == IPUSH ||
+ ic->op == IPOP ||
+ ic->op == CALL ||
+ ic->op == PCALL ||
+ ic->op == RETURN ||
+ POINTER_GET(ic))
+ return ;
/* if both operands present & ! IFX */
/* then if they are both literal we */
/* perform the operation right now */
if (IC_RESULT(ic) &&
- IC_RIGHT(ic) &&
- IC_LEFT(ic) &&
- IS_OP_LITERAL(IC_LEFT(ic)) &&
- IS_OP_LITERAL(IC_RIGHT(ic))) {
-
- IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
- IC_RIGHT(ic),
- ic->op,
- operandType(IC_RESULT(ic)));
- ic->op = '=';
- IC_LEFT(ic) = NULL ;
- SET_RESULT_RIGHT(ic);
- return ;
-
+ IC_RIGHT(ic) &&
+ IC_LEFT(ic) &&
+ IS_OP_LITERAL(IC_LEFT(ic)) &&
+ IS_OP_LITERAL(IC_RIGHT(ic))) {
+
+ IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
+ IC_RIGHT(ic),
+ ic->op,
+ operandType(IC_RESULT(ic)));
+ ic->op = '=';
+ IC_LEFT(ic) = NULL ;
+ SET_RESULT_RIGHT(ic);
+ return ;
+
}
/* if not ifx & only one operand present */
if (IC_RESULT(ic) &&
- IC_LEFT(ic) &&
- IS_OP_LITERAL(IC_LEFT(ic)) &&
- !IC_RIGHT(ic)) {
-
- IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
- IC_RIGHT(ic),
- ic->op,
- operandType(IC_RESULT(ic)));
- ic->op = '=';
- IC_LEFT(ic) = NULL ;
- SET_RESULT_RIGHT(ic);
- return ;
+ IC_LEFT(ic) &&
+ IS_OP_LITERAL(IC_LEFT(ic)) &&
+ !IC_RIGHT(ic)) {
+
+ IC_RIGHT(ic) = operandOperation (IC_LEFT(ic),
+ IC_RIGHT(ic),
+ ic->op,
+ operandType(IC_RESULT(ic)));
+ ic->op = '=';
+ IC_LEFT(ic) = NULL ;
+ SET_RESULT_RIGHT(ic);
+ return ;
}
-
- /* a special case : or in short a kludgy solution will think
+
+ /* a special case : or in short a kludgy solution will think
about a better solution over a glass of wine someday */
if ( ic->op == GET_VALUE_AT_ADDRESS ) {
- if (IS_ITEMP(IC_RESULT(ic)) &&
- IS_TRUE_SYMOP(IC_LEFT(ic))) {
-
- ic->op = '=' ;
- IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic));
- IC_RIGHT(ic)->isaddr = 0;
- IC_LEFT(ic) = NULL;
- IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
- IC_RESULT(ic)->isaddr = 0;
- setOperandType(IC_RESULT(ic),operandType(IC_RIGHT(ic)));
- return;
- }
-
- if (IS_ITEMP(IC_LEFT(ic)) &&
- IS_ITEMP(IC_RESULT(ic)) &&
-/* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
-/* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
- !IC_LEFT(ic)->isaddr ) {
- ic->op = '=' ;
- IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic));
- IC_RIGHT(ic)->isaddr = 0;
- IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
- IC_RESULT(ic)->isaddr = 0;
- IC_LEFT(ic) = NULL;
- return;
- }
+ if (IS_ITEMP(IC_RESULT(ic)) &&
+ IS_TRUE_SYMOP(IC_LEFT(ic))) {
+
+ ic->op = '=' ;
+ IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic));
+ IC_RIGHT(ic)->isaddr = 0;
+ IC_LEFT(ic) = NULL;
+ IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
+ IC_RESULT(ic)->isaddr = 0;
+ setOperandType(IC_RESULT(ic),operandType(IC_RIGHT(ic)));
+ return;
+ }
+
+ if (IS_ITEMP(IC_LEFT(ic)) &&
+ IS_ITEMP(IC_RESULT(ic)) &&
+/* !OP_SYMBOL(IC_RESULT(ic))->isreqv && */
+/* !OP_SYMBOL(IC_LEFT(ic))->isreqv && */
+ !IC_LEFT(ic)->isaddr ) {
+ ic->op = '=' ;
+ IC_RIGHT(ic) = operandFromOperand(IC_LEFT(ic));
+ IC_RIGHT(ic)->isaddr = 0;
+ IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
+ IC_RESULT(ic)->isaddr = 0;
+ IC_LEFT(ic) = NULL;
+ return;
+ }
}
-
+
/* depending on the operation */
switch (ic->op) {
case '+' :
- /* if adding the same thing change to left shift by 1*/
- if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key &&
- !IS_FLOAT(operandType(IC_RESULT(ic)))) {
- ic->op = LEFT_OP ;
- IC_RIGHT(ic) = operandFromLit(1);
- return;
- }
- /* if addition then check if one of them is a zero */
- /* if yes turn it into assignmnt*/
- if (IS_OP_LITERAL(IC_LEFT(ic)) &&
- operandLitValue(IC_LEFT(ic)) == 0.0 ) {
-
- ic->op = '=' ;
- IC_LEFT(ic) = NULL ;
- SET_ISADDR(IC_RESULT(ic),0);
- SET_ISADDR(IC_RIGHT(ic),0);
- return ;
- }
- if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
- operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
-
- ic->op = '=' ;
- IC_RIGHT(ic) = IC_LEFT(ic) ;
- IC_LEFT(ic) = 0;
- SET_ISADDR(IC_RIGHT(ic),0);
- SET_ISADDR(IC_RESULT(ic),0);
- return ;
- }
- break ;
+ /* if adding the same thing change to left shift by 1*/
+ if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key &&
+ !IS_FLOAT(operandType(IC_RESULT(ic)))) {
+ ic->op = LEFT_OP ;
+ IC_RIGHT(ic) = operandFromLit(1);
+ return;
+ }
+ /* if addition then check if one of them is a zero */
+ /* if yes turn it into assignmnt*/
+ if (IS_OP_LITERAL(IC_LEFT(ic)) &&
+ operandLitValue(IC_LEFT(ic)) == 0.0 ) {
+
+ ic->op = '=' ;
+ IC_LEFT(ic) = NULL ;
+ SET_ISADDR(IC_RESULT(ic),0);
+ SET_ISADDR(IC_RIGHT(ic),0);
+ return ;
+ }
+ if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
+ operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
+
+ ic->op = '=' ;
+ IC_RIGHT(ic) = IC_LEFT(ic) ;
+ IC_LEFT(ic) = 0;
+ SET_ISADDR(IC_RIGHT(ic),0);
+ SET_ISADDR(IC_RESULT(ic),0);
+ return ;
+ }
+ break ;
case '-' :
- /* if subtracting the the same thing then zero */
- if ( IC_LEFT(ic)->key == IC_RIGHT(ic)->key ) {
- ic->op = '=';
- IC_RIGHT(ic) = operandFromLit(0);
- IC_LEFT(ic) = NULL ;
- IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
- IC_RESULT(ic)->isaddr = 0;
- return ;
- }
-
- /* if subtraction then check if one of the operand */
- /* is zero then depending on which operand change */
- /* to assignment or unary minus */
- if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
- operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
- /* right size zero change to assignment */
- ic->op = '=' ;
- IC_RIGHT(ic) = IC_LEFT(ic);
- IC_LEFT(ic) = NULL;
- SET_ISADDR(IC_RIGHT(ic),0);
- SET_ISADDR(IC_RESULT(ic),0);
- return ;
- }
- if (IS_OP_LITERAL(IC_LEFT(ic)) &&
- operandLitValue (IC_LEFT(ic)) == 0.0) {
- /* left zero turn into an unary minus */
- ic->op = UNARYMINUS ;
- IC_LEFT(ic) = IC_RIGHT(ic);
- IC_RIGHT(ic) = NULL ;
- return ;
- }
- break;
- /* if multiplication then check if either of */
- /* them is zero then the result is zero */
- /* if either of them is one then result is */
- /* the other one */
+ /* if subtracting the the same thing then zero */
+ if ( IC_LEFT(ic)->key == IC_RIGHT(ic)->key ) {
+ ic->op = '=';
+ IC_RIGHT(ic) = operandFromLit(0);
+ IC_LEFT(ic) = NULL ;
+ IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
+ IC_RESULT(ic)->isaddr = 0;
+ return ;
+ }
+
+ /* if subtraction then check if one of the operand */
+ /* is zero then depending on which operand change */
+ /* to assignment or unary minus */
+ if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
+ operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
+ /* right size zero change to assignment */
+ ic->op = '=' ;
+ IC_RIGHT(ic) = IC_LEFT(ic);
+ IC_LEFT(ic) = NULL;
+ SET_ISADDR(IC_RIGHT(ic),0);
+ SET_ISADDR(IC_RESULT(ic),0);
+ return ;
+ }
+ if (IS_OP_LITERAL(IC_LEFT(ic)) &&
+ operandLitValue (IC_LEFT(ic)) == 0.0) {
+ /* left zero turn into an unary minus */
+ ic->op = UNARYMINUS ;
+ IC_LEFT(ic) = IC_RIGHT(ic);
+ IC_RIGHT(ic) = NULL ;
+ return ;
+ }
+ break;
+ /* if multiplication then check if either of */
+ /* them is zero then the result is zero */
+ /* if either of them is one then result is */
+ /* the other one */
case '*' :
- if (IS_OP_LITERAL(IC_LEFT(ic))) {
-
- if (operandLitValue(IC_LEFT(ic)) == 0.0) {
- ic->op = '=' ;
- IC_RIGHT(ic) = IC_LEFT(ic);
- IC_LEFT(ic) = NULL;
- SET_RESULT_RIGHT(ic);
- return ;
- }
- if ( operandLitValue(IC_LEFT(ic)) == 1.0) {
- ic->op = '=' ;
- IC_LEFT(ic) = NULL ;
- SET_RESULT_RIGHT(ic);
- return ;
- }
- }
-
- if (IS_OP_LITERAL(IC_RIGHT(ic))) {
-
- if (operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
- ic->op = '=';
- IC_LEFT(ic) = NULL ;
- SET_RESULT_RIGHT(ic);
- return ;
- }
-
- if (operandLitValue(IC_RIGHT(ic)) == 1.0) {
- ic->op = '=' ;
- IC_RIGHT(ic) = IC_LEFT(ic);
- IC_LEFT(ic) = NULL ;
- SET_RESULT_RIGHT(ic);
- return ;
- }
- }
- break ;
+ if (IS_OP_LITERAL(IC_LEFT(ic))) {
+
+ if (operandLitValue(IC_LEFT(ic)) == 0.0) {
+ ic->op = '=' ;
+ IC_RIGHT(ic) = IC_LEFT(ic);
+ IC_LEFT(ic) = NULL;
+ SET_RESULT_RIGHT(ic);
+ return ;
+ }
+ if ( operandLitValue(IC_LEFT(ic)) == 1.0) {
+ ic->op = '=' ;
+ IC_LEFT(ic) = NULL ;
+ SET_RESULT_RIGHT(ic);
+ return ;
+ }
+ }
+
+ if (IS_OP_LITERAL(IC_RIGHT(ic))) {
+
+ if (operandLitValue(IC_RIGHT(ic)) == 0.0 ) {
+ ic->op = '=';
+ IC_LEFT(ic) = NULL ;
+ SET_RESULT_RIGHT(ic);
+ return ;
+ }
+
+ if (operandLitValue(IC_RIGHT(ic)) == 1.0) {
+ ic->op = '=' ;
+ IC_RIGHT(ic) = IC_LEFT(ic);
+ IC_LEFT(ic) = NULL ;
+ SET_RESULT_RIGHT(ic);
+ return ;
+ }
+ }
+ break ;
case '/':
- /* if division by self then 1 */
- if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key) {
- ic->op = '=';
- IC_RIGHT(ic) = operandFromLit(1);
- IC_LEFT(ic) = NULL;
- IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
- IC_RESULT(ic)->isaddr = 0;
- }
- /* if this is a division then check if right */
- /* is one then change it to an assignment */
- if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
- operandLitValue(IC_RIGHT(ic)) == 1.0 ) {
-
- ic->op = '=' ;
- IC_RIGHT(ic) = IC_LEFT(ic);
- IC_LEFT(ic) = NULL;
- SET_RESULT_RIGHT(ic);
- return ;
- }
- break;
- /* if both are the same for an comparison operators */
+ /* if division by self then 1 */
+ if (IC_LEFT(ic)->key == IC_RIGHT(ic)->key) {
+ ic->op = '=';
+ IC_RIGHT(ic) = operandFromLit(1);
+ IC_LEFT(ic) = NULL;
+ IC_RESULT(ic) = operandFromOperand(IC_RESULT(ic));
+ IC_RESULT(ic)->isaddr = 0;
+ }
+ /* if this is a division then check if right */
+ /* is one then change it to an assignment */
+ if (IS_OP_LITERAL(IC_RIGHT(ic)) &&
+ operandLitValue(IC_RIGHT(ic)) == 1.0 ) {
+
+ ic->op = '=' ;
+ IC_RIGHT(ic) = IC_LEFT(ic);
+ IC_LEFT(ic) = NULL;
+ SET_RESULT_RIGHT(ic);
+ return ;
+ }
+ break;
+ /* if both are the same for an comparison operators */
case EQ_OP :
case LE_OP :
case GE_OP :
- if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) {
- ic->op = '=';
- IC_RIGHT(ic) = operandFromLit(1);
- IC_LEFT(ic) = NULL;
- SET_RESULT_RIGHT(ic);
- }
- break;
+ if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) {
+ ic->op = '=';
+ IC_RIGHT(ic) = operandFromLit(1);
+ IC_LEFT(ic) = NULL;
+ SET_RESULT_RIGHT(ic);
+ }
+ break;
case NE_OP :
case '>' :
case '<' :
- if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) {
- ic->op = '=';
- IC_RIGHT(ic) = operandFromLit(0);
- IC_LEFT(ic) = NULL ;
- SET_RESULT_RIGHT(ic);
- }
- break ;
+ if (isOperandEqual(IC_LEFT(ic),IC_RIGHT(ic))) {
+ ic->op = '=';
+ IC_RIGHT(ic) = operandFromLit(0);
+ IC_LEFT(ic) = NULL ;
+ SET_RESULT_RIGHT(ic);
+ }
+ break ;
case CAST :
- /* if this is a cast of a literal value */
- if ( IS_OP_LITERAL(IC_RIGHT(ic))) {
- ic->op = '=' ;
- IC_RIGHT(ic) =
- operandFromValue (valCastLiteral(operandType(IC_LEFT(ic)),
- operandLitValue(IC_RIGHT(ic))));
- IC_LEFT(ic) = NULL;
- SET_ISADDR(IC_RESULT(ic),0);
- }
- /* if casting to the same */
- if ( checkType(operandType(IC_RESULT(ic)),
- operandType(IC_RIGHT(ic))) == 1) {
- ic->op = '=';
- IC_LEFT(ic) = NULL;
- SET_ISADDR(IC_RESULT(ic),0);
- }
- break;
+ /* if this is a cast of a literal value */
+ if ( IS_OP_LITERAL(IC_RIGHT(ic))) {
+ ic->op = '=' ;
+ IC_RIGHT(ic) =
+ operandFromValue (valCastLiteral(operandType(IC_LEFT(ic)),
+ operandLitValue(IC_RIGHT(ic))));
+ IC_LEFT(ic) = NULL;
+ SET_ISADDR(IC_RESULT(ic),0);
+ }
+ /* if casting to the same */
+ if ( checkType(operandType(IC_RESULT(ic)),
+ operandType(IC_RIGHT(ic))) == 1) {
+ ic->op = '=';
+ IC_LEFT(ic) = NULL;
+ SET_ISADDR(IC_RESULT(ic),0);
+ }
+ break;
case '!' :
- if (IS_OP_LITERAL(IC_LEFT(ic))) {
- ic->op = '=' ;
- IC_RIGHT(ic) =
- (operandLitValue(IC_LEFT(ic)) == 0 ?
- operandFromLit(1) : operandFromLit(0));
- IC_LEFT(ic) = NULL;
- SET_ISADDR(IC_RESULT(ic),0);
- }
+ if (IS_OP_LITERAL(IC_LEFT(ic))) {
+ ic->op = '=' ;
+ IC_RIGHT(ic) =
+ (operandLitValue(IC_LEFT(ic)) == 0 ?
+ operandFromLit(1) : operandFromLit(0));
+ IC_LEFT(ic) = NULL;
+ SET_ISADDR(IC_RESULT(ic),0);
+ }
}
-
+
return ;
}
#define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
void updateSpillLocation ( iCode *ic)
{
- link *setype;
+ sym_link *setype;
+
+ if (POINTER_SET(ic))
+ return;
- if (POINTER_SET(ic))
- return;
-
if (ic->nosupdate)
- return;
+ return;
/* for the form true_symbol := iTempNN */
if (ASSIGN_ITEMP_TO_SYM(ic)
- && !SPIL_LOC(IC_RIGHT(ic))) {
+ && !SPIL_LOC(IC_RIGHT(ic))) {
+
+ setype = getSpec(operandType(IC_RESULT(ic)));
- setype = getSpec(operandType(IC_RESULT(ic)));
-
if (!IC_RIGHT(ic)->noSpilLoc &&
- !IS_VOLATILE(setype) &&
- !IN_FARSPACE(SPEC_OCLS(setype)) &&
- !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )
-
- SPIL_LOC(IC_RIGHT(ic)) =
- IC_RESULT(ic)->operand.symOperand;
+ !IS_VOLATILE(setype) &&
+ !IN_FARSPACE(SPEC_OCLS(setype)) &&
+ !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )
+
+ SPIL_LOC(IC_RIGHT(ic)) =
+ IC_RESULT(ic)->operand.symOperand;
}
if (ASSIGN_ITEMP_TO_ITEMP(ic) &&
- !SPIL_LOC(IC_RIGHT(ic)) &&
+ !SPIL_LOC(IC_RIGHT(ic)) &&
!bitVectBitsInCommon(OP_DEFS(IC_RIGHT(ic)),OP_USES(IC_RESULT(ic))) &&
- OP_SYMBOL(IC_RESULT(ic))->isreqv) {
-
- setype = getSpec(operandType(IC_RESULT(ic)));
+ OP_SYMBOL(IC_RESULT(ic))->isreqv) {
+
+ setype = getSpec(operandType(IC_RESULT(ic)));
if (!IC_RIGHT(ic)->noSpilLoc &&
- !IS_VOLATILE(setype) &&
- !IN_FARSPACE(SPEC_OCLS(setype)) &&
- !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )
-
- SPIL_LOC(IC_RIGHT(ic)) =
- SPIL_LOC(IC_RESULT(ic));
+ !IS_VOLATILE(setype) &&
+ !IN_FARSPACE(SPEC_OCLS(setype)) &&
+ !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) )
+
+ SPIL_LOC(IC_RIGHT(ic)) =
+ SPIL_LOC(IC_RESULT(ic));
}
}
/*-----------------------------------------------------------------*/
/* setUsesDef - sets the uses def bitvector for a given operand */
/*-----------------------------------------------------------------*/
-void setUsesDefs (operand *op, bitVect *bdefs,
- bitVect *idefs, bitVect **oud)
+void setUsesDefs (operand *op, bitVect *bdefs,
+ bitVect *idefs, bitVect **oud)
{
/* compute the definitions alive at this point */
bitVect *adefs = bitVectUnion(bdefs,idefs);
/* of these definitions find the ones that are */
/* for this operand */
adefs = bitVectIntersect(adefs,OP_DEFS(op));
-
+
/* these are the definitions that this operand can use */
op->usesDefs = adefs;
-
+
/* the out defs is an union */
*oud = bitVectUnion(*oud,adefs);
}
/*-----------------------------------------------------------------*/
/* unsetDefsAndUses - clear this operation for the operands */
/*-----------------------------------------------------------------*/
-void unsetDefsAndUses ( iCode *ic )
+void unsetDefsAndUses ( iCode *ic )
{
if ( ic->op == JUMPTABLE)
- return ;
+ return ;
/* take away this definition from the def chain of the */
/* result & take away from use set of the operands */
if (ic->op != IFX) {
- /* turn off def set */
- if (IS_SYMOP(IC_RESULT(ic))) {
- if ( !POINTER_SET(ic))
- bitVectUnSetBit(OP_DEFS(IC_RESULT(ic)),ic->key);
- else
- bitVectUnSetBit(OP_USES(IC_RESULT(ic)),ic->key);
- }
- /* turn off the useSet for the operands */
- if (IS_SYMOP(IC_LEFT(ic)))
- bitVectUnSetBit (OP_USES(IC_LEFT(ic)),ic->key);
-
- if (IS_SYMOP(IC_RIGHT(ic)))
- bitVectUnSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
+ /* turn off def set */
+ if (IS_SYMOP(IC_RESULT(ic))) {
+ if ( !POINTER_SET(ic))
+ bitVectUnSetBit(OP_DEFS(IC_RESULT(ic)),ic->key);
+ else
+ bitVectUnSetBit(OP_USES(IC_RESULT(ic)),ic->key);
+ }
+ /* turn off the useSet for the operands */
+ if (IS_SYMOP(IC_LEFT(ic)))
+ bitVectUnSetBit (OP_USES(IC_LEFT(ic)),ic->key);
+
+ if (IS_SYMOP(IC_RIGHT(ic)))
+ bitVectUnSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
}
else /* must be ifx turn off the use */
- if (IS_SYMOP(IC_COND(ic)))
- bitVectUnSetBit (OP_USES(IC_COND(ic)),ic->key);
+ if (IS_SYMOP(IC_COND(ic)))
+ bitVectUnSetBit (OP_USES(IC_COND(ic)),ic->key);
}
/*-----------------------------------------------------------------*/
/* ifxOptimize - changes ifx conditions if it can */
/*-----------------------------------------------------------------*/
-void ifxOptimize (iCode *ic, set *cseSet,
- int computeOnly ,
- eBBlock *ebb, int *change,
- eBBlock **ebbs, int count)
+void ifxOptimize (iCode *ic, set *cseSet,
+ int computeOnly ,
+ eBBlock *ebb, int *change,
+ eBBlock **ebbs, int count)
{
operand *pdop ;
symbol *label;
/* if the condition can be replaced */
if (!computeOnly) {
- pdop = NULL ;
- applyToSetFTrue (cseSet,findCheaperOp,IC_COND(ic),&pdop);
- if (pdop) {
- IC_COND(ic) = pdop ;
- (*change)++;
- }
+ pdop = NULL ;
+ applyToSetFTrue (cseSet,findCheaperOp,IC_COND(ic),&pdop);
+ if (pdop) {
+ IC_COND(ic) = pdop ;
+ (*change)++;
+ }
}
-
+
/* if the conditional is a literal then */
- if (IS_OP_LITERAL(IC_COND(ic))) {
-
- if ( (operandLitValue(IC_COND(ic)) != 0.0) && IC_TRUE(ic)) {
-
- /* change to a goto */
- ic->op = GOTO ;
- IC_LABEL(ic) = IC_TRUE(ic);
- (*change)++;
-
- } else {
-
- if (!operandLitValue(IC_COND(ic)) && IC_FALSE(ic)) {
- ic->op = GOTO ;
- IC_LABEL(ic) = IC_FALSE(ic);
- (*change)++;
-
- } else {
- /* then kill this if condition */
- remiCodeFromeBBlock (ebb,ic);
- }
- }
-
- /* now we need to recompute the control flow */
- /* since the control flow has changed */
- /* this is very expensive but it does not happen */
- /* too often, if it does happen then the user pays */
- /* the price */
- computeControlFlow (ebbs,count,1);
- werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
- return ;
+ if (IS_OP_LITERAL(IC_COND(ic))) {
+
+ if ( (operandLitValue(IC_COND(ic)) != 0.0) && IC_TRUE(ic)) {
+
+ /* change to a goto */
+ ic->op = GOTO ;
+ IC_LABEL(ic) = IC_TRUE(ic);
+ (*change)++;
+
+ } else {
+
+ if (!operandLitValue(IC_COND(ic)) && IC_FALSE(ic)) {
+ ic->op = GOTO ;
+ IC_LABEL(ic) = IC_FALSE(ic);
+ (*change)++;
+
+ } else {
+ /* then kill this if condition */
+ remiCodeFromeBBlock (ebb,ic);
+ }
+ }
+
+ /* now we need to recompute the control flow */
+ /* since the control flow has changed */
+ /* this is very expensive but it does not happen */
+ /* too often, if it does happen then the user pays */
+ /* the price */
+ computeControlFlow (ebbs,count,1);
+ werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
+ return ;
}
-
+
/* if there is only one successor and that successor
is the same one we are conditionally going to then
we can remove this conditional statement */
label = (IC_TRUE(ic) ? IC_TRUE(ic) : IC_FALSE(ic));
if (elementsInSet(ebb->succList) == 1 &&
- isinSet(ebb->succList,eBBWithEntryLabel(ebbs,label,count))) {
+ isinSet(ebb->succList,eBBWithEntryLabel(ebbs,label,count))) {
- remiCodeFromeBBlock(ebb,ic);
- computeControlFlow (ebbs,count,1);
- werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
- return ;
+ remiCodeFromeBBlock(ebb,ic);
+ computeControlFlow (ebbs,count,1);
+ werror (W_CONTROL_FLOW,ic->filename,ic->lineno);
+ return ;
}
-
-
+
+
/* if it remains an IFX the update the use Set */
OP_USES(IC_COND(ic)) = bitVectSetBit(OP_USES(IC_COND(ic)),ic->key);
setUsesDefs(IC_COND(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
- return ;
+ return ;
}
/*-----------------------------------------------------------------*/
/* if already found */
if (*dic)
- return 0;
+ return 0;
/* if not if this is the defining iCode */
if (sym->key == cdp->key) {
- *dic = cdp->diCode ;
- return 1;
+ *dic = cdp->diCode ;
+ return 1;
}
return 0;
int constFold (iCode *ic, set *cseSet)
{
iCode *dic = NULL;
+ iCode *ldic= NULL;
/* this routine will change
a = b + 10;
c = a + 10;
/* deal with only + & - */
if (ic->op != '+' &&
- ic->op != '-' )
- return 0;
+ ic->op != '-' )
+ return 0;
/* this check is a hueristic to prevent live ranges
from becoming too long */
if (IS_PTR(operandType(IC_RESULT(ic))))
- return 0;
+ return 0;
/* check if operation with a literal */
if (!IS_OP_LITERAL(IC_RIGHT(ic)))
- return 0;
+ return 0;
/* check if we can find a definition for the
right hand side */
if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(ic),&dic)))
- return 0;
+ return 0;
/* check that this is also a +/- */
if (dic->op != '+' && dic->op != '-')
- return 0;
+ return 0;
/* with a literal */
if (!IS_OP_LITERAL(IC_RIGHT(dic)))
- return 0;
+ return 0;
+
+ /* find the definition of the left operand
+ of dic.then check if this defined with a
+ get_pointer return 0 if the pointer size is
+ less than 2 (MCS51 specific) */
+ if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(dic),&ldic)))
+ return 0;
+
+ if (POINTER_GET(ldic) && getSize(operandType(IC_LEFT(ldic))) <= 1)
+ return 0;
/* it is if the operations are the same*/
/* the literal parts need to be added */
- IC_LEFT(ic) = operandFromOperand(IC_LEFT(dic));
+ IC_LEFT(ic) = operandFromOperand(IC_LEFT(dic));
if (ic->op == dic->op )
- IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic))+
- operandLitValue(IC_RIGHT(dic)));
+ IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic))+
+ operandLitValue(IC_RIGHT(dic)));
else
- IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) -
- operandLitValue(IC_RIGHT(dic)));
+ IC_RIGHT(ic) = operandFromLit(operandLitValue(IC_RIGHT(ic)) -
+ operandLitValue(IC_RIGHT(dic)));
if (IS_ITEMP(IC_RESULT(ic))) {
- SPIL_LOC(IC_RESULT(ic)) = NULL;
- IC_RESULT(ic)->noSpilLoc = 1;
+ SPIL_LOC(IC_RESULT(ic)) = NULL;
+ IC_RESULT(ic)->noSpilLoc = 1;
}
-
-
+
+
return 1;
}
set *compItems = NULL;
cseDef *cdp ;
operand *cop;
-
+
/* easy return */
if (!*cseSet && !*pss)
- return ;
-
+ return ;
+
/* first find all items computed from this operand .
This done fairly simply go thru the list and find
those that are computed by arthimetic with this
op */
for (cdp = setFirstItem(*cseSet); cdp ; cdp = setNextItem(*cseSet)) {
- if (IS_ARITHMETIC_OP(cdp->diCode)) {
- if (isOperandEqual(IC_LEFT(cdp->diCode),op) ||
- isOperandEqual(IC_RIGHT(cdp->diCode),op)) {
- /* save it in our list of items */
- addSet(&compItems,IC_RESULT(cdp->diCode));
- }
- /* also check for those computed from our computed
- list . This will take care of situations like
- iTemp1 = iTemp0 + 8;
- iTemp2 = iTemp1 + 8; */
- if (isinSetWith(compItems,IC_LEFT(cdp->diCode),isOperandEqual) ||
- isinSetWith(compItems,IC_RIGHT(cdp->diCode),isOperandEqual)) {
- addSet(&compItems,IC_RESULT(cdp->diCode));
- }
- }
+ if (IS_ARITHMETIC_OP(cdp->diCode)) {
+ if (isOperandEqual(IC_LEFT(cdp->diCode),op) ||
+ isOperandEqual(IC_RIGHT(cdp->diCode),op)) {
+ /* save it in our list of items */
+ addSet(&compItems,IC_RESULT(cdp->diCode));
+ }
+ /* also check for those computed from our computed
+ list . This will take care of situations like
+ iTemp1 = iTemp0 + 8;
+ iTemp2 = iTemp1 + 8; */
+ if (isinSetWith(compItems,IC_LEFT(cdp->diCode),isOperandEqual) ||
+ isinSetWith(compItems,IC_RIGHT(cdp->diCode),isOperandEqual)) {
+ addSet(&compItems,IC_RESULT(cdp->diCode));
+ }
+ }
}
-
+
/* now delete all pointer gets with this op */
deleteItemIf(cseSet,ifPointerGet,op);
deleteItemIf(pss,ifPointerSet,op);
ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,op->key);
/* now for the computed items */
for (cop = setFirstItem(compItems); cop ; cop = setNextItem(compItems)) {
- ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,cop->key);
- deleteItemIf(cseSet,ifPointerGet,cop);
- deleteItemIf(pss,ifPointerSet,cop);
+ ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,cop->key);
+ deleteItemIf(cseSet,ifPointerGet,cop);
+ deleteItemIf(pss,ifPointerSet,cop);
}
}
V_ARG(int,dfnum);
if (ebp->visited)
- return 0;
-
+ return 0;
+
ebp->visited = 1;
if (ebp->dfnum > dfnum) {
- deleteItemIf(&ebp->inExprs,ifPointerGet,op);
+ deleteItemIf(&ebp->inExprs,ifPointerGet,op);
}
return applyToSet(ebp->succList,delGetPointerSucc,op,dfnum);
-}
+}
+
+/*-----------------------------------------------------------------*/
+/* fixUpTypes - KLUGE HACK fixup a lowering problem */
+/*-----------------------------------------------------------------*/
+static void fixUpTypes(iCode *ic)
+{
+ sym_link *t1 = operandType(IC_LEFT(ic)) ,*t2;
+
+ if (IS_DS390_PORT)
+ {
+ /* hack-o-matic! */
+ return;
+ }
+
+ /* for pointer_gets if the types of result & left r the
+ same then change it type of result to next */
+ if (IS_PTR(t1) &&
+ checkType(t2=operandType(IC_RESULT(ic)),t1) == 1) {
+ setOperandType(IC_RESULT(ic),t2->next);
+ }
+}
/*-----------------------------------------------------------------*/
/* cseBBlock - common subexpression elimination for basic blocks */
/* system. also the most important, since almost all */
/* data flow related information is computed by it */
/*-----------------------------------------------------------------*/
-int cseBBlock ( eBBlock *ebb, int computeOnly,
- eBBlock **ebbs, int count)
+int cseBBlock ( eBBlock *ebb, int computeOnly,
+ eBBlock **ebbs, int count)
{
set *cseSet ;
- iCode *ic ;
+ iCode *ic ;
int change = 0 ;
- int i;
+ int i;
set *ptrSetSet = NULL;
/* if this block is not reachable */
if (ebb->noPath)
- return change;
+ return change;
+
+ /* set of common subexpressions */
+ cseSet = setFromSet (ebb->inExprs) ;
- /* set of common subexpressions */
- cseSet = setFromSet (ebb->inExprs) ;
-
/* these will be computed by this routine */
- setToNull ((void **)&ebb->outDefs);
+ setToNull ((void **)&ebb->outDefs);
setToNull ((void **)&ebb->defSet);
setToNull ((void **)&ebb->usesDefs);
setToNull ((void **)&ebb->ptrsSet);
/* for all the instructions in this block do */
for (ic = ebb->sch ; ic ; ic = ic->next ) {
-
- iCode *pdic;
- operand *pdop ;
- iCode *defic;
-
- if (SKIP_IC2(ic))
- continue ;
-
- /* if this is an assignment from true symbol
- to a temp then do pointer post inc/dec optimzation */
- if (ic->op == '=' && !POINTER_SET(ic) &&
- IS_PTR(operandType(IC_RESULT(ic)))) {
- ptrPostIncDecOpt(ic);
- }
-
- /* clear the def & use chains for the operands involved */
- /* in this operation . since it can change due to opts */
- unsetDefsAndUses (ic);
-
- if ( ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE) {
- /* add to defSet of the symbol */
- OP_DEFS(IC_RESULT(ic)) =
- bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
- /* add to the definition set of this block */
- ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);
- ebb->ldefs = bitVectSetBit (ebb->ldefs,ic->key);
- ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic)));
- setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
- /* delete global variables from the cseSet
- since they can be modified by the function call */
- deleteItemIf(&cseSet,ifDefGlobal);
- }
-
- /* for pcall & ipush we need to add to the useSet */
- if ((ic->op == PCALL ||
- ic->op == IPUSH ||
- ic->op == IPOP ||
- ic->op == SEND) &&
- IS_SYMOP(IC_LEFT(ic))) {
-
- /* check if they can be replaced */
- if ( !computeOnly ) {
- pdop = NULL ;
- applyToSetFTrue(cseSet,findCheaperOp,IC_LEFT(ic),&pdop);
- if (pdop)
- IC_LEFT(ic) = pdop ;
- }
- /* the lookup could have changed it*/
- if (IS_SYMOP(IC_LEFT(ic))) {
- OP_USES(IC_LEFT(ic)) =
- bitVectSetBit(OP_USES(IC_LEFT(ic)),ic->key);
- setUsesDefs(IC_LEFT(ic),ebb->defSet,
- ebb->outDefs,&ebb->usesDefs);
- }
-
-
- /* if we a sending a pointer as a parameter
- then kill all cse since the pointed to item
- might be changed in the function being called */
- if ((ic->op == IPUSH || ic->op == SEND) &&
- IS_PTR(operandType(IC_LEFT(ic)))) {
- deleteGetPointers(&cseSet,&ptrSetSet,IC_LEFT(ic),ebb);
- ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_LEFT(ic)->key);
- for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
- applyToSet(ebb->succList,delGetPointerSucc,
- IC_LEFT(ic),ebb->dfnum);
- }
- continue;
- }
-
- /* if jumptable then mark the usage */
- if (ic->op == JUMPTABLE ) {
- OP_USES(IC_JTCOND(ic)) =
- bitVectSetBit(OP_USES(IC_JTCOND(ic)),ic->key);
- setUsesDefs(IC_JTCOND(ic),ebb->defSet,
- ebb->outDefs,&ebb->usesDefs);
- continue;
- }
-
- if (SKIP_IC(ic))
- continue ;
-
- /* do some algebraic optimizations if possible */
- algebraicOpts (ic);
- while (constFold(ic,cseSet));
-
- /* small klugde */
- if (POINTER_GET(ic) && !IS_PTR(operandType(IC_LEFT(ic)))) {
- setOperandType(IC_LEFT(ic),
- aggrToPtr(operandType(IC_LEFT(ic)),FALSE));
- }
- if (POINTER_SET(ic) && !IS_PTR(operandType(IC_RESULT(ic)))) {
- setOperandType(IC_RESULT(ic),
- aggrToPtr(operandType(IC_RESULT(ic)),FALSE));
- }
-
- /* if this is a condition statment then */
- /* check if the condition can be replaced */
- if (ic->op == IFX ) {
- ifxOptimize (ic, cseSet, computeOnly,
- ebb, &change,
- ebbs, count);
- continue ;
- }
-
- /* if the assignment & result is a temp */
- /* see if we can replace it */
- if (ic->op == '=') {
-
- /* update the spill location for this */
- updateSpillLocation (ic);
-
- if (POINTER_SET(ic)) {
- pdop = NULL ;
- applyToSetFTrue (cseSet,findCheaperOp,IC_RESULT(ic),&pdop);
- if (pdop && IS_ITEMP(pdop) && !computeOnly)
- IC_RESULT(ic) = pdop;
- }
- }
-
- /* do the operand lookup i.e. for both the */
- /* right & left operand : check the cseSet */
- /* to see if they have been replaced if yes*/
- /* then replace them with those from cseSet*/
- /* left operand */
- /* and left is a symbol */
- if (IS_SYMOP(IC_LEFT(ic)) &&
- !computeOnly && ic->op != ADDRESS_OF ) {
-
- pdop = NULL;
- applyToSetFTrue (cseSet,findCheaperOp,IC_LEFT(ic),&pdop) ;
- if (pdop) {
- if (POINTER_GET(ic)) {
- if (IS_ITEMP(pdop) || IS_OP_LITERAL(pdop)) {
- IC_LEFT(ic) = pdop;
- change = 1;
- }
- /* check if there is a pointer set
- for the same pointer visible if yes
- then change this into an assignment */
- pdop = NULL;
- if (applyToSetFTrue(cseSet,findPointerSet,IC_LEFT(ic),&pdop,IC_RESULT(ic)) &&
- !bitVectBitValue(ebb->ptrsSet,pdop->key)){
- ic->op = '=';
- IC_LEFT(ic) = NULL;
- IC_RIGHT(ic) = pdop;
- SET_ISADDR(IC_RESULT(ic),0);
- }
-
- }
- else {
- IC_LEFT(ic) = pdop ;
- change = 1;
- }
- }
- }
-
- /*right operand */
- if (IS_SYMOP(IC_RIGHT(ic)) && !computeOnly) {
-
- pdop = NULL ;
- applyToSetFTrue (cseSet,findCheaperOp,IC_RIGHT(ic),&pdop);
- if (pdop) {
-
- IC_RIGHT(ic) = pdop;
- change = 1;
- }
- }
-
- /* if left or right changed then do algebraic */
- if (change) {
- algebraicOpts(ic);
- while(constFold(ic,cseSet));
- }
-
- /* if after all this it becomes a assignment to self
- then delete it and continue */
- if (ASSIGNMENT_TO_SELF(ic)) {
- remiCodeFromeBBlock(ebb,ic);
- continue;
- }
-
- /* now we will check to see if the entire */
- /* operation has been performed before */
- /* and is available */
- /* don't do assignments they will be killed */
- /* by dead code elimination if required do */
- /* it only if result is a temporary */
- pdic = NULL ;
- if (!( POINTER_GET(ic) &&
- (IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
- isOperandVolatile(IC_LEFT(ic),TRUE) ||
- bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))) &&
- ! ASSIGNMENT(ic) &&
- IS_ITEMP(IC_RESULT(ic)) &&
- ! computeOnly) {
- applyToSet (cseSet,findPrevIc,ic,&pdic);
- }
-
- /* if found then eliminate this and add to*/
- /* to cseSet an element containing result */
- /* of this with previous opcode */
- if (pdic) {
-
- if (IS_ITEMP(IC_RESULT(ic))) {
-
- /* replace in the remaining of this block */
- replaceAllSymBySym(ic->next,IC_RESULT(ic),IC_RESULT(pdic),&ebb->ndompset);
- /* remove this iCode from inexpressions of all
- its successors, it cannot be in the in expressions
- of any of the predecessors */
- for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
- applyToSet(ebb->succList,removeFromInExprs,ic,IC_RESULT(ic),
- IC_RESULT(pdic),ebb);
-
- /* if this was moved from another block */
- /* then replace in those blocks too */
- if ( ic->movedFrom ) {
- eBBlock *owner ;
- for (owner = setFirstItem(ic->movedFrom); owner ;
- owner = setNextItem(ic->movedFrom))
- replaceAllSymBySym(owner->sch,IC_RESULT(ic),IC_RESULT(pdic),&owner->ndompset);
- }
- pdic->movedFrom = unionSets(pdic->movedFrom,ic->movedFrom,THROW_NONE);
- }
- else
- addSetHead (&cseSet,newCseDef(IC_RESULT(ic),pdic));
-
- if (!computeOnly)
- /* eliminate this */
- remiCodeFromeBBlock (ebb,ic);
-
- defic = pdic ;
- change++ ;
-
- if (IS_ITEMP(IC_RESULT(ic)))
- continue ;
-
- } else {
-
- /* just add this as a previous expression except in */
- /* case of a pointer access in which case this is a */
- /* usage not a definition */
- if (! (POINTER_SET(ic)) && IC_RESULT(ic)){
- deleteItemIf (&cseSet, ifDefSymIsX,IC_RESULT(ic));
- addSetHead(&cseSet,newCseDef(IC_RESULT(ic),ic));
- }
- defic = ic;
-
- }
-
- /* if assignment to a parameter which is not
- mine and type is a pointer then delete
- pointerGets to take care of aliasing */
- if (ASSIGNMENT(ic) &&
- OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) &&
- IS_PTR(operandType(IC_RESULT(ic)))) {
- deleteGetPointers(&cseSet,&ptrSetSet,IC_RIGHT(ic),ebb);
- for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
- applyToSet(ebb->succList,delGetPointerSucc,IC_RIGHT(ic),ebb->dfnum);
- ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RIGHT(ic)->key);
- }
-
- /* if this is a pointerget then see if we can replace
- this with a previously assigned pointer value */
- if (POINTER_GET(ic) &&
- !(IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
- isOperandVolatile(IC_LEFT(ic),TRUE))) {
- pdop = NULL;
- applyToSet(ptrSetSet,findPointerSet,IC_LEFT(ic),&pdop,IC_RESULT(ic));
- /* if we find it then locally replace all
- references to the result with what we assigned */
- if (pdop) {
- replaceAllSymBySym(ic->next,IC_RESULT(ic),pdop,&ebb->ndompset);
- }
- }
-
- /* delete from the cseSet anything that has */
- /* operands matching the result of this */
- /* except in case of pointer access */
- if (!(POINTER_SET(ic)) && IC_RESULT(ic)) {
- deleteItemIf (&cseSet,ifOperandsHave,IC_RESULT(ic));
- /* delete any previous definitions */
- ebb->defSet = bitVectCplAnd (ebb->defSet,OP_DEFS(IC_RESULT(ic)));
-
- }
-
- /* add the left & right to the defUse set */
- if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic))) {
- OP_USES(IC_LEFT(ic)) =
- bitVectSetBit (OP_USES(IC_LEFT(ic)),ic->key);
- setUsesDefs(IC_LEFT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
-
- }
-
- if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic))) {
- OP_USES(IC_RIGHT(ic)) =
- bitVectSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
- setUsesDefs(IC_RIGHT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
-
- }
-
- /* for the result it is special case, put the result */
- /* in the defuseSet if it a pointer or array access */
- if ( POINTER_SET(defic) ) {
- OP_USES(IC_RESULT(ic)) =
- bitVectSetBit (OP_USES(IC_RESULT(ic)),ic->key);
- setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
- deleteItemIf(&cseSet,ifPointerGet,IC_RESULT(ic));
- ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RESULT(ic)->key);
- /* delete from inexpressions of all successors which
- have dfNum > than this block */
- for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
- applyToSet(ebb->succList,delGetPointerSucc,IC_RESULT(ic),ebb->dfnum);
-
- /* delete from cseSet all other pointer sets
- for this operand */
- deleteItemIf(&ptrSetSet,ifPointerSet,IC_RESULT(ic));
- /* add to the local pointerset set */
- addSetHead(&ptrSetSet,newCseDef(IC_RESULT(ic),ic));
- }
- else /* add the result to defintion set */
- if (IC_RESULT(ic)) {
- OP_DEFS(IC_RESULT(ic)) =
- bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
- ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);
- ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic)));
- ebb->ldefs = bitVectSetBit (ebb->ldefs,ic->key);
- }
-
-
- /* if this is an addressof instruction then */
- /* put the symbol in the address of list & */
- /* delete it from the cseSet */
- if (defic->op == ADDRESS_OF) {
- addSetHead (&ebb->addrOf, IC_LEFT(ic));
- deleteItemIf(&cseSet,ifDefSymIsX,IC_LEFT(ic));
- }
+
+ iCode *pdic;
+ operand *pdop ;
+ iCode *defic;
+
+ if (SKIP_IC2(ic))
+ continue ;
+
+ /* if this is an assignment from true symbol
+ to a temp then do pointer post inc/dec optimzation */
+ if (ic->op == '=' && !POINTER_SET(ic) &&
+ IS_PTR(operandType(IC_RESULT(ic)))) {
+ ptrPostIncDecOpt(ic);
+ }
+
+ /* clear the def & use chains for the operands involved */
+ /* in this operation . since it can change due to opts */
+ unsetDefsAndUses (ic);
+
+ if ( ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE) {
+ /* add to defSet of the symbol */
+ OP_DEFS(IC_RESULT(ic)) =
+ bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
+ /* add to the definition set of this block */
+ ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);
+ ebb->ldefs = bitVectSetBit (ebb->ldefs,ic->key);
+ ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic)));
+ setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
+ /* delete global variables from the cseSet
+ since they can be modified by the function call */
+ deleteItemIf(&cseSet,ifDefGlobal);
+ /* delete all getpointer iCodes from cseSet, this should
+ be done only for global arrays & pointers but at this
+ point we don't know if globals, so to be safe do all*/
+ deleteItemIf(&cseSet,ifAnyGetPointer);
+ }
+
+ /* for pcall & ipush we need to add to the useSet */
+ if ((ic->op == PCALL ||
+ ic->op == IPUSH ||
+ ic->op == IPOP ||
+ ic->op == SEND) &&
+ IS_SYMOP(IC_LEFT(ic))) {
+
+ /* check if they can be replaced */
+ if ( !computeOnly ) {
+ pdop = NULL ;
+ applyToSetFTrue(cseSet,findCheaperOp,IC_LEFT(ic),&pdop);
+ if (pdop)
+ IC_LEFT(ic) = pdop ;
+ }
+ /* the lookup could have changed it*/
+ if (IS_SYMOP(IC_LEFT(ic))) {
+ OP_USES(IC_LEFT(ic)) =
+ bitVectSetBit(OP_USES(IC_LEFT(ic)),ic->key);
+ setUsesDefs(IC_LEFT(ic),ebb->defSet,
+ ebb->outDefs,&ebb->usesDefs);
+ }
+
+
+ /* if we a sending a pointer as a parameter
+ then kill all cse since the pointed to item
+ might be changed in the function being called */
+ if ((ic->op == IPUSH || ic->op == SEND) &&
+ IS_PTR(operandType(IC_LEFT(ic)))) {
+ deleteGetPointers(&cseSet,&ptrSetSet,IC_LEFT(ic),ebb);
+ ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_LEFT(ic)->key);
+ for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
+ applyToSet(ebb->succList,delGetPointerSucc,
+ IC_LEFT(ic),ebb->dfnum);
+ }
+ continue;
+ }
+
+ /* if jumptable then mark the usage */
+ if (ic->op == JUMPTABLE ) {
+ OP_USES(IC_JTCOND(ic)) =
+ bitVectSetBit(OP_USES(IC_JTCOND(ic)),ic->key);
+ setUsesDefs(IC_JTCOND(ic),ebb->defSet,
+ ebb->outDefs,&ebb->usesDefs);
+ continue;
+ }
+
+ if (SKIP_IC(ic))
+ continue ;
+
+ /* do some algebraic optimizations if possible */
+ algebraicOpts (ic);
+ while (constFold(ic,cseSet));
+
+ /* small klugde */
+ if (POINTER_GET(ic) && !IS_PTR(operandType(IC_LEFT(ic)))) {
+ setOperandType(IC_LEFT(ic),
+ aggrToPtr(operandType(IC_LEFT(ic)),FALSE));
+ fixUpTypes(ic);
+
+ }
+ if (POINTER_SET(ic) && !IS_PTR(operandType(IC_RESULT(ic)))) {
+ setOperandType(IC_RESULT(ic),
+ aggrToPtr(operandType(IC_RESULT(ic)),FALSE));
+ }
+
+ /* if this is a condition statment then */
+ /* check if the condition can be replaced */
+ if (ic->op == IFX ) {
+ ifxOptimize (ic, cseSet, computeOnly,
+ ebb, &change,
+ ebbs, count);
+ continue ;
+ }
+
+ /* if the assignment & result is a temp */
+ /* see if we can replace it */
+ if (ic->op == '=') {
+
+ /* update the spill location for this */
+ updateSpillLocation (ic);
+
+ if (POINTER_SET(ic) &&
+ !(IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype))) {
+ pdop = NULL ;
+ applyToSetFTrue (cseSet,findCheaperOp,IC_RESULT(ic),&pdop);
+ if (pdop && IS_ITEMP(pdop) && !computeOnly)
+ IC_RESULT(ic) = pdop;
+ }
+ }
+
+ /* do the operand lookup i.e. for both the */
+ /* right & left operand : check the cseSet */
+ /* to see if they have been replaced if yes*/
+ /* then replace them with those from cseSet*/
+ /* left operand */
+ /* and left is a symbol */
+ if (IS_SYMOP(IC_LEFT(ic)) &&
+ !computeOnly && ic->op != ADDRESS_OF ) {
+
+ pdop = NULL;
+ applyToSetFTrue (cseSet,findCheaperOp,IC_LEFT(ic),&pdop) ;
+ if (pdop) {
+ if (POINTER_GET(ic)) {
+ if (IS_ITEMP(pdop) || IS_OP_LITERAL(pdop)) {
+ IC_LEFT(ic) = pdop;
+ change = 1;
+ }
+ /* check if there is a pointer set
+ for the same pointer visible if yes
+ then change this into an assignment */
+ pdop = NULL;
+ if (applyToSetFTrue(cseSet,findPointerSet,IC_LEFT(ic),&pdop,IC_RESULT(ic)) &&
+ !bitVectBitValue(ebb->ptrsSet,pdop->key)){
+ ic->op = '=';
+ IC_LEFT(ic) = NULL;
+ IC_RIGHT(ic) = pdop;
+ SET_ISADDR(IC_RESULT(ic),0);
+ }
+
+ }
+ else {
+ IC_LEFT(ic) = pdop ;
+ change = 1;
+ }
+ }
+ }
+
+ /*right operand */
+ if (IS_SYMOP(IC_RIGHT(ic)) && !computeOnly) {
+
+ pdop = NULL ;
+ applyToSetFTrue (cseSet,findCheaperOp,IC_RIGHT(ic),&pdop);
+ if (pdop) {
+
+ IC_RIGHT(ic) = pdop;
+ change = 1;
+ }
+ }
+
+ /* if left or right changed then do algebraic */
+ if (change) {
+ algebraicOpts(ic);
+ while(constFold(ic,cseSet));
+ }
+
+ /* if after all this it becomes a assignment to self
+ then delete it and continue */
+ if (ASSIGNMENT_TO_SELF(ic)) {
+ remiCodeFromeBBlock(ebb,ic);
+ continue;
+ }
+
+ /* now we will check to see if the entire */
+ /* operation has been performed before */
+ /* and is available */
+ /* don't do assignments they will be killed */
+ /* by dead code elimination if required do */
+ /* it only if result is a temporary */
+ pdic = NULL ;
+ if (!( POINTER_GET(ic) &&
+ (IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
+ isOperandVolatile(IC_LEFT(ic),TRUE) ||
+ bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))) &&
+ ! ASSIGNMENT(ic) &&
+ IS_ITEMP(IC_RESULT(ic)) &&
+ ! computeOnly) {
+ applyToSet (cseSet,findPrevIc,ic,&pdic);
+ if (pdic && checkType(operandType(IC_RESULT(pdic)),
+ operandType(IC_RESULT(ic))) != 1)
+ pdic = NULL;
+ }
+
+ /* if found then eliminate this and add to*/
+ /* to cseSet an element containing result */
+ /* of this with previous opcode */
+ if (pdic) {
+
+ if (IS_ITEMP(IC_RESULT(ic))) {
+
+ /* replace in the remaining of this block */
+ replaceAllSymBySym(ic->next,IC_RESULT(ic),IC_RESULT(pdic),&ebb->ndompset);
+ /* remove this iCode from inexpressions of all
+ its successors, it cannot be in the in expressions
+ of any of the predecessors */
+ for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
+ applyToSet(ebb->succList,removeFromInExprs,ic,IC_RESULT(ic),
+ IC_RESULT(pdic),ebb);
+
+ /* if this was moved from another block */
+ /* then replace in those blocks too */
+ if ( ic->movedFrom ) {
+ eBBlock *owner ;
+ for (owner = setFirstItem(ic->movedFrom); owner ;
+ owner = setNextItem(ic->movedFrom))
+ replaceAllSymBySym(owner->sch,IC_RESULT(ic),IC_RESULT(pdic),&owner->ndompset);
+ }
+ pdic->movedFrom = unionSets(pdic->movedFrom,ic->movedFrom,THROW_NONE);
+ }
+ else
+ addSetHead (&cseSet,newCseDef(IC_RESULT(ic),pdic));
+
+ if (!computeOnly)
+ /* eliminate this */
+ remiCodeFromeBBlock (ebb,ic);
+
+ defic = pdic ;
+ change++ ;
+
+ if (IS_ITEMP(IC_RESULT(ic)))
+ continue ;
+
+ } else {
+
+ /* just add this as a previous expression except in */
+ /* case of a pointer access in which case this is a */
+ /* usage not a definition */
+ if (! (POINTER_SET(ic)) && IC_RESULT(ic)){
+ deleteItemIf (&cseSet, ifDefSymIsX,IC_RESULT(ic));
+ addSetHead(&cseSet,newCseDef(IC_RESULT(ic),ic));
+ }
+ defic = ic;
+
+ }
+
+ /* if assignment to a parameter which is not
+ mine and type is a pointer then delete
+ pointerGets to take care of aliasing */
+ if (ASSIGNMENT(ic) &&
+ OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))) &&
+ IS_PTR(operandType(IC_RESULT(ic)))) {
+ deleteGetPointers(&cseSet,&ptrSetSet,IC_RIGHT(ic),ebb);
+ for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
+ applyToSet(ebb->succList,delGetPointerSucc,IC_RIGHT(ic),ebb->dfnum);
+ ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RIGHT(ic)->key);
+ }
+
+ /* if this is a pointerget then see if we can replace
+ this with a previously assigned pointer value */
+ if (POINTER_GET(ic) &&
+ !(IS_BITFIELD(OP_SYMBOL(IC_RESULT(ic))->etype) ||
+ isOperandVolatile(IC_LEFT(ic),TRUE))) {
+ pdop = NULL;
+ applyToSet(ptrSetSet,findPointerSet,IC_LEFT(ic),&pdop,IC_RESULT(ic));
+ /* if we find it then locally replace all
+ references to the result with what we assigned */
+ if (pdop) {
+ replaceAllSymBySym(ic->next,IC_RESULT(ic),pdop,&ebb->ndompset);
+ }
+ }
+
+ /* delete from the cseSet anything that has */
+ /* operands matching the result of this */
+ /* except in case of pointer access */
+ if (!(POINTER_SET(ic)) && IC_RESULT(ic)) {
+ deleteItemIf (&cseSet,ifOperandsHave,IC_RESULT(ic));
+ /* delete any previous definitions */
+ ebb->defSet = bitVectCplAnd (ebb->defSet,OP_DEFS(IC_RESULT(ic)));
+
+ }
+
+ /* add the left & right to the defUse set */
+ if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic))) {
+ OP_USES(IC_LEFT(ic)) =
+ bitVectSetBit (OP_USES(IC_LEFT(ic)),ic->key);
+ setUsesDefs(IC_LEFT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
+
+ }
+
+ if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic))) {
+ OP_USES(IC_RIGHT(ic)) =
+ bitVectSetBit (OP_USES(IC_RIGHT(ic)),ic->key);
+ setUsesDefs(IC_RIGHT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
+
+ }
+
+ /* for the result it is special case, put the result */
+ /* in the defuseSet if it a pointer or array access */
+ if ( POINTER_SET(defic) ) {
+ OP_USES(IC_RESULT(ic)) =
+ bitVectSetBit (OP_USES(IC_RESULT(ic)),ic->key);
+ setUsesDefs(IC_RESULT(ic),ebb->defSet,ebb->outDefs,&ebb->usesDefs);
+ deleteItemIf(&cseSet,ifPointerGet,IC_RESULT(ic));
+ ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,IC_RESULT(ic)->key);
+ /* delete from inexpressions of all successors which
+ have dfNum > than this block */
+ for (i = 0 ; i < count ;ebbs[i++]->visited = 0);
+ applyToSet(ebb->succList,delGetPointerSucc,IC_RESULT(ic),ebb->dfnum);
+
+ /* delete from cseSet all other pointer sets
+ for this operand */
+ deleteItemIf(&ptrSetSet,ifPointerSet,IC_RESULT(ic));
+ /* add to the local pointerset set */
+ addSetHead(&ptrSetSet,newCseDef(IC_RESULT(ic),ic));
+ }
+ else /* add the result to defintion set */
+ if (IC_RESULT(ic)) {
+ OP_DEFS(IC_RESULT(ic)) =
+ bitVectSetBit (OP_DEFS(IC_RESULT(ic)),ic->key);
+ ebb->defSet = bitVectSetBit (ebb->defSet,ic->key);
+ ebb->outDefs= bitVectCplAnd (ebb->outDefs,OP_DEFS(IC_RESULT(ic)));
+ ebb->ldefs = bitVectSetBit (ebb->ldefs,ic->key);
+ }
+
+
+ /* if this is an addressof instruction then */
+ /* put the symbol in the address of list & */
+ /* delete it from the cseSet */
+ if (defic->op == ADDRESS_OF) {
+ addSetHead (&ebb->addrOf, IC_LEFT(ic));
+ deleteItemIf(&cseSet,ifDefSymIsX,IC_LEFT(ic));
+ }
}
setToNull ((void **)&ebb->outExprs);
- ebb->outExprs = cseSet;
+ ebb->outExprs = cseSet;
ebb->outDefs = bitVectUnion (ebb->outDefs,ebb->defSet);
ebb->ptrsSet = bitVectUnion (ebb->ptrsSet,ebb->inPtrsSet);
return change ;
/* if optimization turned off */
- for (i = 0 ; i < count ;i++ )
- change += cseBBlock (ebbs[i],FALSE,ebbs,count);
+ for (i = 0 ; i < count ;i++ )
+ change += cseBBlock (ebbs[i],FALSE,ebbs,count);
return change;
}
-
+