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"
+#include "dbuf_string.h"
+
/*-----------------------------------------------------------------*/
/* newCseDef - new cseDef */
/*-----------------------------------------------------------------*/
-cseDef *newCseDef (operand *sym, iCode *ic)
+cseDef *
+newCseDef (operand * sym, iCode * ic)
{
- cseDef *cdp ;
-
- assert (sym);
- ALLOC(cdp,sizeof(cseDef));
-
- cdp->sym = sym;
- cdp->diCode = ic;
- cdp->key = sym->key;
-
- return cdp;
+ cseDef *cdp;
+
+ assert (sym);
+ cdp = Safe_alloc (sizeof (cseDef));
+
+ cdp->sym = sym;
+ cdp->diCode = ic;
+ cdp->key = sym->key;
+ cdp->ancestors = newBitVect(iCodeKey);
+ cdp->fromGlobal = 0;
+ cdp->fromAddrTaken = 0;
+
+ if (ic->op!=IF && ic->op!=JUMPTABLE)
+ {
+ if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
+ {
+ bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
+ cdp->fromGlobal |= isOperandGlobal (IC_LEFT (ic));
+ cdp->fromAddrTaken |= OP_SYMBOL (IC_LEFT (ic))->addrtaken;
+ }
+ if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
+ {
+ bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
+ cdp->fromGlobal |= isOperandGlobal (IC_RIGHT (ic));
+ cdp->fromAddrTaken |= OP_SYMBOL (IC_RIGHT (ic))->addrtaken;
+ }
+ }
+
+ return cdp;
}
+void
+updateCseDefAncestors(cseDef *cdp, set * cseSet)
+{
+ cseDef *loop;
+ set *sl;
+ iCode *ic = cdp->diCode;
+
+ if (ic->op!=IF && ic->op!=JUMPTABLE)
+ {
+ if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
+ {
+ bitVectSetBit (cdp->ancestors, IC_LEFT (ic)->key);
+ for (sl = cseSet; sl; sl = sl->next)
+ {
+ loop = sl->item;
+ if (loop->sym->key == IC_LEFT (ic)->key)
+ {
+ cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
+ cdp->fromGlobal |= loop->fromGlobal;
+ cdp->fromAddrTaken |= loop->fromAddrTaken;
+ break;
+ }
+ }
+ }
+ if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
+ {
+ bitVectSetBit (cdp->ancestors, IC_RIGHT (ic)->key);
+ for (sl = cseSet; sl; sl = sl->next)
+ {
+ loop = sl->item;
+ if (loop->sym->key == IC_RIGHT (ic)->key)
+ {
+ cdp->ancestors = bitVectUnion (cdp->ancestors, loop->ancestors);
+ cdp->fromGlobal |= loop->fromGlobal;
+ cdp->fromAddrTaken |= loop->fromAddrTaken;
+ break;
+ }
+ }
+ }
+ }
+}
/*-----------------------------------------------------------------*/
/* int isCseDefEqual - two definitions are equal */
/*-----------------------------------------------------------------*/
-int isCseDefEqual ( void *vsrc, void *vdest)
+int
+isCseDefEqual (void *vsrc, void *vdest)
{
- cseDef *src = vsrc;
- cseDef *dest = vdest;
-
- if (src == dest)
- return 1;
-
- return (src->key == dest->key &&
- src->diCode == dest->diCode ) ;
-
+ cseDef *src = vsrc;
+ cseDef *dest = vdest;
+
+ if (src == dest)
+ return 1;
+
+ return (src->key == dest->key &&
+ src->diCode == dest->diCode);
+
}
/*-----------------------------------------------------------------*/
/* pcseDef - in the cseDef */
/*-----------------------------------------------------------------*/
-int pcseDef (void *item, va_list ap)
+int
+pcseDef (void *item, va_list ap)
{
- cseDef *cdp = item;
- iCodeTable *icTab ;
-
- (void)ap;
-
- if (!cdp->sym)
- fprintf(stdout,"**null op**");
- printOperand(cdp->sym,stdout);
- icTab = getTableEntry(cdp->diCode->op) ;
- icTab->iCodePrint(stdout,cdp->diCode,icTab->printName);
- return 1;
+ cseDef *cdp = item;
+ iCodeTable *icTab;
+ struct dbuf_s dbuf;
+
+ (void) ap;
+
+ if (!cdp->sym)
+ fprintf (stdout, "**null op**");
+ printOperand (cdp->sym, stdout);
+ icTab = getTableEntry (cdp->diCode->op);
+ dbuf_init (&dbuf, 1024);
+ icTab->iCodePrint (&dbuf, cdp->diCode, icTab->printName);
+ dbuf_write_and_destroy (&dbuf, stdout);
+ return 1;
+}
+
+void ReplaceOpWithCheaperOp(operand **op, operand *cop) {
+#ifdef RANGEHUNT
+ printf ("ReplaceOpWithCheaperOp\n\t");
+ printOperand (*op, stdout);
+ printf ("\nwith\t");
+ printOperand (cop, stdout);
+
+ // if op is a register equivalent
+ if (IS_ITEMP(cop) && IS_SYMOP((*op)) && OP_SYMBOL((*op))->isreqv) {
+ operand **rop = &OP_SYMBOL((*op))->usl.spillLoc->reqv;
+ if (isOperandEqual(*rop, *op)) {
+ printf ("true");
+ *rop=cop;
+ OP_SYMBOL((*op))->isreqv=0;
+ OP_SYMBOL(cop)->isreqv=1;
+ } else {
+ printf ("false");
+ }
+ }
+ printf ("\n");
+#endif
+ *op=cop;
}
/*-----------------------------------------------------------------*/
/* replaceAllSymBySym - replaces all operands by operand in an */
/* instruction chain */
/*-----------------------------------------------------------------*/
-void replaceAllSymBySym (iCode *ic, operand *from , operand *to, bitVect **ndpset)
+void
+replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
{
- 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 ;
- }
+ iCode *lic;
+
+#ifdef RANGEHUNT
+ printf ("replaceAllSymBySym\n\t");
+ printOperand (from, stdout);
+ printf ("\nwith\t");
+ printOperand (to, stdout);
+ printf ("\n");
+#endif
+ for (lic = ic; lic; lic = lic->next)
+ {
+ int isaddr;
+
+ /* 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);
+ isaddr = IC_COND (lic)->isaddr;
+ IC_COND (lic) = operandFromOperand (to);
+ IC_COND (lic)->isaddr = isaddr;
+
+ }
+ 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);
+ isaddr = IC_COND (lic)->isaddr;
+ IC_JTCOND (lic) = operandFromOperand (to);
+ IC_JTCOND (lic)->isaddr = isaddr;
+
+ }
+ continue;
+ }
+
+ if (IS_SYMOP(to) &&
+ 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);
+ }
+ isaddr = IC_RESULT (lic)->isaddr;
+ IC_RESULT (lic) = operandFromOperand (to);
+ IC_RESULT (lic)->isaddr = isaddr;
+ }
+
+ 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);
+ isaddr = IC_RIGHT (lic)->isaddr;
+ IC_RIGHT (lic) = operandFromOperand (to);
+ IC_RIGHT (lic)->isaddr = isaddr;
+ }
+
+ 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);
+ isaddr = IC_LEFT (lic)->isaddr;
+ IC_LEFT (lic) = operandFromOperand (to);
+ IC_LEFT (lic)->isaddr = isaddr;
+ }
}
}
/*-----------------------------------------------------------------*/
/* iCodeKeyIs - if the icode keys match then return 1 */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(iCodeKeyIs)
+DEFSETFUNC (iCodeKeyIs)
{
- cseDef *cdp = item;
- V_ARG(int,key);
+ cseDef *cdp = item;
+ V_ARG (int, key);
- if (cdp->diCode->key == key)
- return 1;
- else
- return 0;
+ if (cdp->diCode->key == key)
+ return 1;
+ else
+ return 0;
}
/*-----------------------------------------------------------------*/
/* removeFromInExprs - removes an icode from inexpressions */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(removeFromInExprs)
+DEFSETFUNC (removeFromInExprs)
{
- eBBlock *ebp = item;
- V_ARG(iCode *,ic);
- V_ARG(operand *,from);
- V_ARG(operand *,to);
- V_ARG(eBBlock *,cbp);
+ eBBlock *ebp = item;
+ V_ARG (iCode *, ic);
+ V_ARG (operand *, from);
+ V_ARG (operand *, to);
+ V_ARG (eBBlock *, cbp);
- if (ebp->visited)
- return 0;
+ if (ebp->visited)
+ 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);
+ ebp->visited = 1;
+ deleteItemIf (&ebp->inExprs, iCodeKeyIs, ic->key);
+ if (ebp != cbp && !bitVectBitValue (cbp->domVect, ebp->bbnum))
+ replaceAllSymBySym (ebp->sch, from, to, &ebp->ndompset);
- applyToSet(ebp->succList,removeFromInExprs,ic,from,to,cbp);
- return 0;
+ applyToSet (ebp->succList, removeFromInExprs, ic, from, to, cbp);
+ return 0;
}
/*-----------------------------------------------------------------*/
/* isGlobalInNearSpace - return TRUE if valriable is a globalin data */
/*-----------------------------------------------------------------*/
-static bool isGlobalInNearSpace (operand *op)
+static bool
+isGlobalInNearSpace (operand * op)
{
- 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;
- else
- return FALSE;
+ 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_FARSPACE (SPEC_OCLS (type)) &&
+ IN_DIRSPACE (SPEC_OCLS (type)))
+ return TRUE;
+ else
+ return FALSE;
}
/*-----------------------------------------------------------------*/
/* findCheaperOp - cseBBlock support routine, will check to see if */
/* we have a operand previously defined */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(findCheaperOp)
+DEFSETFUNC (findCheaperOp)
{
- cseDef *cdp = item ;
- V_ARG(operand *,cop);
- V_ARG(operand **,opp);
-
- /* if we have already found it */
- 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) ;
+ cseDef *cdp = item;
+ V_ARG (operand *, cop);
+ V_ARG (operand **, opp);
+ V_ARG (int, checkSign);
+
+ /* if we have already found it */
+ 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 assignment and both
+ are temps then prefer the one that
+ will not need extra space to spil, also
+ take into consideration if right side
+ is 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 &&
+ !OP_SYMBOL(IC_RIGHT (cdp->diCode))->isreqv &&
+ ((!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 (*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 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 ((*opp) &&
+ (isOperandLiteral(*opp) || !checkSign ||
+ (checkSign &&
+ IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
+ (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
+ (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*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;
+ }
+
+ /* copy signedness to literal operands */
+ if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp))
+ && isOperandLiteral(*opp)
+ && SPEC_NOUN(operandType(*opp)) == SPEC_NOUN(operandType(cop))
+ && SPEC_USIGN(operandType(*opp)) != SPEC_USIGN(operandType(cop)))
+ {
+ SPEC_USIGN(operandType(*opp)) = SPEC_USIGN(operandType(cop));
+ }
+
+ if (IS_SPEC(operandType (cop)) && IS_SPEC(operandType (*opp)) &&
+ SPEC_NOUN(operandType(cop)) != SPEC_NOUN(operandType(*opp)))
+ {
+ // special case: we can make an unsigned char literal
+ // into an int literal with no cost.
+ if (isOperandLiteral(*opp)
+ && SPEC_NOUN(operandType(*opp)) == V_CHAR
+ && SPEC_NOUN(operandType(cop)) == V_INT)
+ {
+ *opp = operandFromOperand (*opp);
+ SPEC_NOUN(operandType(*opp)) = V_INT;
+ }
+ else
+ {
+ // No clue...
+ *opp = NULL;
+ return 0;
+ }
+
+ }
+
+ return 1;
+
}
-
- return 0;
+ *opp=NULL;
+ return 0;
}
/*-----------------------------------------------------------------*/
/* findPointerSet - finds the right side of a pointer set op */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(findPointerSet)
+DEFSETFUNC (findPointerSet)
{
- cseDef *cdp = item;
- V_ARG(operand *,op);
- V_ARG(operand **,opp);
- 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;
+ cseDef *cdp = item;
+ V_ARG (operand *, op);
+ V_ARG (operand **, opp);
+ 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)))
+ {
+ if (IS_SPEC (operandType (IC_RIGHT (cdp->diCode))) &&
+ SPEC_USIGN (operandType (IC_RIGHT (cdp->diCode))) !=
+ SPEC_USIGN (operandType (rop)))
+ {
+ /* bug #1493710
+ Reminder for Bernhard: check of signedness
+ could be unnecessary together with 'checkSign', if
+ signedness of operation is stored in ic */
+ return 0;
+ }
+ *opp = IC_RIGHT (cdp->diCode);
+ return 1;
}
- return 0;
+ return 0;
}
/*-----------------------------------------------------------------*/
/* findPrevIc - cseBBlock support function will return the iCode */
/* which matches the current one */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(findPrevIc)
+DEFSETFUNC (findPrevIc)
{
- cseDef *cdp = item ;
- V_ARG(iCode *,ic);
- V_ARG(iCode **,icp);
-
- /* if already found */
- if (*icp)
- 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;
+ cseDef *cdp = item;
+ V_ARG (iCode *, ic);
+ V_ARG (iCode **, icp);
+
+ /* if already found */
+ if (*icp)
+ 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 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;
+ /* if iCodes are not the same */
+ /* see the operands maybe interchanged */
+ if (ic->op == cdp->diCode->op &&
+ IS_ASSOCIATIVE(ic) &&
+ isOperandEqual (IC_LEFT (ic), IC_RIGHT (cdp->diCode)) &&
+ isOperandEqual (IC_RIGHT (ic), IC_LEFT (cdp->diCode)))
+ {
+ *icp = cdp->diCode;
+ return 1;
}
- return 0;
+ return 0;
+}
+
+/*-------------------------------------------------------------------*/
+/* ifAssignedFromGlobal - if definition is an assignment from global */
+/*-------------------------------------------------------------------*/
+DEFSETFUNC (ifAssignedFromGlobal)
+{
+ cseDef *cdp = item;
+ iCode *dic=cdp->diCode;
+
+ if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
+ return 1;
+ }
+ return 0;
+}
+
+/*-------------------------------------------------------------------*/
+/* ifFromGlobal - if definition is derived from global */
+/*-------------------------------------------------------------------*/
+DEFSETFUNC (ifFromGlobal)
+{
+ cseDef *cdp = item;
+
+ return cdp->fromGlobal;
}
/*-----------------------------------------------------------------*/
/* ifDefGlobal - if definition is global */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(ifDefGlobal)
+DEFSETFUNC (ifDefGlobal)
+{
+ cseDef *cdp = item;
+
+ return (isOperandGlobal (cdp->sym));
+}
+
+/*-------------------------------------------------------------------*/
+/* ifFromAddrTaken - if definition is derived from a symbol whose */
+/* address was taken */
+/*-------------------------------------------------------------------*/
+DEFSETFUNC (ifFromAddrTaken)
{
- cseDef *cdp = item;
-
- return (isOperandGlobal(cdp->sym));
+ cseDef *cdp = item;
+
+ return cdp->fromAddrTaken;
}
+
/*-----------------------------------------------------------------*/
/* ifAnyGetPointer - if get pointer icode */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(ifAnyGetPointer)
+DEFSETFUNC (ifAnyGetPointer)
{
- cseDef *cdp = item;
-
- if (cdp->diCode && POINTER_GET(cdp->diCode)) return 1;
- return 0;
+ 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)
+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;
-
- if (IC_RIGHT(cdp->diCode) &&
- 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_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;
+ cseDef *cdp = item;
+ V_ARG (operand *, op);
- return 0;
+ if (bitVectBitValue(cdp->ancestors, op->key))
+ return 1;
+
+ 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;
+
+ /* or if any of the operands are volatile */
+ 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_RESULT (cdp->diCode) &&
+ IS_OP_VOLATILE (IC_RESULT (cdp->diCode)))
+ return 1;
+
+ return 0;
}
/*-----------------------------------------------------------------*/
/* ifDefSymIs - if a definition is found in the set */
/*-----------------------------------------------------------------*/
- int ifDefSymIs (set *cseSet, operand *sym)
+int
+ifDefSymIs (set * cseSet, operand * sym)
{
- cseDef *loop ;
- set *sl ;
-
- if (!sym || !IS_SYMOP(sym))
- return 0;
- for (sl = cseSet ; sl ; sl = sl->next ) {
- loop = sl->item;
- if (loop->sym->key == sym->key )
- return 1;
- }
+ cseDef *loop;
+ set *sl;
+
+ if (!sym || !IS_SYMOP (sym))
return 0;
+ for (sl = cseSet; sl; sl = sl->next)
+ {
+ 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);
-
- if (op && cdp->sym)
- return cdp->sym->key == op->key ;
- else
- return ( isOperandEqual(cdp->sym,op) );
-
-}
+DEFSETFUNC (ifDefSymIsX)
+{
+ cseDef *cdp = item;
+ V_ARG (operand *, op);
+ int match;
+
+ if (op && cdp->sym)
+ match = cdp->sym->key == op->key;
+ else
+ match = (isOperandEqual (cdp->sym, op));
+ #if 0
+ if (match)
+ printf("%s ",OP_SYMBOL(cdp->sym)->name);
+ #endif
+ return match;
+}
/*-----------------------------------------------------------------*/
-/* ifDiCodeIs - returns truw if diCode is same */
+/* ifDiCodeIs - returns true if diCode is same */
/*-----------------------------------------------------------------*/
- int ifDiCodeIs (set *cseSet, iCode *ic)
+int
+ifDiCodeIs (set * cseSet, iCode * ic)
{
- cseDef *loop;
- set *sl;
-
- if (!ic)
- return 0;
-
- for (sl = cseSet ; sl ; sl = sl->next ) {
- loop = sl->item ;
- if (loop->diCode == ic)
- return 1;
- }
+ cseDef *loop;
+ set *sl;
+
+ if (!ic)
return 0;
-
+
+ for (sl = cseSet; sl; sl = sl->next)
+ {
+ loop = sl->item;
+ if (loop->diCode == ic)
+ return 1;
+ }
+ return 0;
+
}
/*-----------------------------------------------------------------*/
/* ifPointerGet - returns true if the icode is pointer get sym */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(ifPointerGet)
+DEFSETFUNC (ifPointerGet)
{
- cseDef *cdp = item;
- V_ARG(operand *,op);
- iCode *dic = cdp->diCode;
- operand *left = IC_LEFT(cdp->diCode);
+ cseDef *cdp = item;
+ V_ARG (operand *, op);
+ iCode *dic = cdp->diCode;
+ operand *left = IC_LEFT (cdp->diCode);
- if (POINTER_GET(dic) && left->key == op->key)
- return 1;
+ if (POINTER_GET (dic) && left->key == op->key)
+ return 1;
- return 0;
+ return 0;
}
/*-----------------------------------------------------------------*/
/* ifPointerSet - returns true if the icode is pointer set sym */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(ifPointerSet)
+DEFSETFUNC (ifPointerSet)
{
- cseDef *cdp = item;
- V_ARG(operand *,op);
+ cseDef *cdp = item;
+ V_ARG (operand *, op);
- if (POINTER_SET(cdp->diCode) &&
- IC_RESULT(cdp->diCode)->key == op->key)
- return 1;
+ if (POINTER_SET (cdp->diCode) &&
+ IC_RESULT (cdp->diCode)->key == op->key)
+ return 1;
- return 0;
+ return 0;
}
/*-----------------------------------------------------------------*/
/* ifDiCodeIsX - will return 1 if the symbols match */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(ifDiCodeIsX)
-{
- cseDef *cdp = item;
- V_ARG(iCode *,ic);
+DEFSETFUNC (ifDiCodeIsX)
+{
+ cseDef *cdp = item;
+ V_ARG (iCode *, ic);
+
+ return cdp->diCode == ic;
- return cdp->diCode == ic;
-
+}
+
+/*-----------------------------------------------------------------*/
+/* findBackwardDef - scan backwards to find deinition of operand */
+/*-----------------------------------------------------------------*/
+iCode *findBackwardDef(operand *op,iCode *ic)
+{
+ iCode *lic;
+
+ for (lic = ic; lic ; lic = lic->prev) {
+ if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic)))
+ return lic;
+ }
+ return NULL;
}
/*-----------------------------------------------------------------*/
/* algebraicOpts - does some algebraic optimizations */
/*-----------------------------------------------------------------*/
-void algebraicOpts (iCode *ic)
+static void
+algebraicOpts (iCode * ic, eBBlock * ebp)
{
- /* 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 ;
-
- /* 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 ;
-
+ /* 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;
+
+ /* 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;
+
}
- /* 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 ;
+ /* 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;
}
-
- /* 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;
- }
+
+ /* 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;
+ }
}
-
- /* 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 ;
- 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 */
- 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 ;
+
+ /* 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)))
+ || IS_FIXED(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 assignment or cast */
+ if (IS_OP_LITERAL (IC_LEFT (ic)) &&
+ operandLitValue (IC_LEFT (ic)) == 0.0)
+ {
+ int typematch;
+ typematch = compareType (operandType (IC_RESULT (ic)),
+ operandType (IC_RIGHT (ic)));
+ if ((typematch<0) || (IS_TRUE_SYMOP (IC_RIGHT (ic))))
+ {
+ ic->op = CAST;
+ IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
+ }
+ else
+ {
+ ic->op = '=';
+ IC_LEFT (ic) = NULL;
+ if (typematch==0)
+ {
+ /* for completely different types, preserve the source type */
+ IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
+ setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
+ }
+ }
+ 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)
+ {
+ int typematch;
+ typematch = compareType (operandType (IC_RESULT (ic)),
+ operandType (IC_LEFT (ic)));
+ if ((typematch<0) || (IS_TRUE_SYMOP (IC_LEFT (ic))))
+ {
+ ic->op = CAST;
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
+ }
+ else
+ {
+ ic->op = '=';
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = NULL;
+ if (typematch==0)
+ {
+ /* for completely different types, preserve the source type */
+ IC_RIGHT (ic) = operandFromOperand (IC_RIGHT (ic));
+ setOperandType (IC_RIGHT (ic), operandType (IC_RESULT (ic)));
+ }
+ }
+ SET_ISADDR (IC_RIGHT (ic), 0);
+ SET_ISADDR (IC_RESULT (ic), 0);
+ return;
+ }
+ break;
+ case '-':
+ /* if subtracting 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)))
+ {
+ double leftValue = operandLitValue (IC_LEFT (ic));
+
+ if (leftValue == 0.0)
+ {
+ ic->op = '=';
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+ if (leftValue == 1.0)
+ {
+ /* '*' can have two unsigned chars as operands */
+ /* and an unsigned int as result. */
+ if (compareType (operandType (IC_RESULT (ic)),
+ operandType (IC_RIGHT (ic))) == 1)
+ {
+ ic->op = '=';
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ }
+ else
+ {
+ ic->op = CAST;
+ IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic));
+ IC_LEFT (ic)->type = TYPE;
+ IC_LEFT (ic)->isLiteral = 0;
+ setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
+ }
+ return;
+ }
+ if (leftValue == -1.0)
+ {
+ /* convert -1 * x to -x */
+ ic->op = UNARYMINUS;
+ IC_LEFT (ic) = IC_RIGHT (ic);
+ IC_RIGHT (ic) = NULL;
+ return;
+ }
+ }
+
+ if (IS_OP_LITERAL (IC_RIGHT (ic)))
+ {
+ double rightValue = operandLitValue (IC_RIGHT (ic));
+
+ if (rightValue == 0.0)
+ {
+ ic->op = '=';
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+
+ if (rightValue == 1.0)
+ {
+ /* '*' can have two unsigned chars as operands */
+ /* and an unsigned int as result. */
+ if (compareType (operandType (IC_RESULT (ic)),
+ operandType (IC_LEFT (ic))) == 1)
+ {
+ ic->op = '=';
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ }
+ else
+ {
+ operand *op;
+
+ ic->op = CAST;
+ op = IC_RIGHT (ic);
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = operandFromOperand (op);
+ IC_LEFT (ic)->type = TYPE;
+ IC_LEFT (ic)->isLiteral = 0;
+ setOperandType (IC_LEFT (ic), operandType (IC_RESULT (ic)));
+ }
+ return;
+ }
+ if (rightValue == -1.0)
+ {
+ /* '*' can have two unsigned chars as operands */
+ /* and an unsigned int as result. */
+ if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
+ {
+ if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
+ (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
+ {
+ operand * op;
+ iCode * newic;
+ /* Widen to int. */
+ op = operandFromOperand (IC_RESULT (ic));
+ op->type = TYPE;
+ setOperandType (op, INTTYPE);
+ newic = newiCode (CAST, op, IC_LEFT (ic));
+ IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
+ addiCodeToeBBlock (ebp, newic, ic);
+ IC_LEFT (ic) = IC_RESULT (newic);
+ }
+ }
+ /* convert x * -1 to -x */
+ ic->op = UNARYMINUS;
+ IC_RIGHT (ic) = NULL;
+ 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 */
- 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;
- 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 ;
- 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;
- 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 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;
+ return;
+ }
+ /* if this is a division then check if left is zero */
+ /* and right is not then change it to an assignment */
+ if (IS_OP_LITERAL (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic)) &&
+ (operandLitValue (IC_LEFT (ic)) == 0.0) && (operandLitValue (IC_RIGHT (ic)) != 0.0))
+ {
+ ic->op = '=';
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+ /* if this is a division then check if right */
+ /* is one then change it to an assignment */
+ if (IS_OP_LITERAL (IC_RIGHT (ic)))
+ {
+ double rightValue = operandLitValue (IC_RIGHT (ic));
+ if (rightValue == 1.0)
+ {
+ ic->op = '=';
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+ if (rightValue == -1.0)
+ {
+ /* '/' can have two unsigned chars as operands */
+ /* and an unsigned int as result. */
+ if (IS_INTEGRAL (operandType (IC_LEFT (ic))))
+ {
+ if ((getSize (operandType (IC_LEFT (ic))) < (unsigned int) INTSIZE) &&
+ (getSize (operandType (IC_LEFT (ic))) < getSize (operandType (IC_RESULT (ic)))))
+ {
+ operand * op;
+ iCode * newic;
+ /* Widen to int. */
+ op = operandFromOperand (IC_RESULT (ic));
+ op->type = TYPE;
+ setOperandType (op, INTTYPE);
+ newic = newiCode (CAST, op, IC_LEFT (ic));
+ IC_RESULT (newic) = newiTempOperand (INTTYPE, TRUE);
+ addiCodeToeBBlock (ebp, newic, ic);
+ IC_LEFT (ic) = IC_RESULT (newic);
+ }
+ }
+ /* convert x / -1 to -x */
+ ic->op = UNARYMINUS;
+ IC_RIGHT (ic) = NULL;
+ 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;
+ 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;
+ case CAST:
+ {
+ sym_link *otype = operandType(IC_RIGHT(ic));
+ sym_link *ctype = operandType(IC_LEFT(ic));
+ /* if this is a cast of a literal value */
+ if (IS_OP_LITERAL (IC_RIGHT (ic)) &&
+ !(IS_GENPTR(ctype) && (IS_PTR(otype) && !IS_GENPTR(otype))))
+ {
+ 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 (compareType (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);
+ }
+ break;
+ case BITWISEAND:
+ /* if both operands are equal */
+ /* if yes turn it into assignment */
+ if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
+ {
+ if (IS_OP_VOLATILE (IC_LEFT (ic)))
+ {
+ iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+ IC_RESULT (newic) = IC_LEFT (ic);
+ newic->filename = ic->filename;
+ newic->lineno = ic->lineno;
+ addiCodeToeBBlock (ebp, newic, ic->next);
+ }
+ ic->op = '=';
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+ /* swap literal to right ic */
+ if (IS_OP_LITERAL (IC_LEFT (ic)))
+ {
+ operand *op;
+
+ op = IC_LEFT (ic);
+ IC_LEFT (ic) = IC_RIGHT (ic);
+ IC_RIGHT (ic) = op;
+ }
+ if (IS_OP_LITERAL (IC_RIGHT (ic)))
+ {
+ /* if BITWISEAND then check if one of them is a zero */
+ /* if yes turn it into 0 assignment */
+ if (operandLitValue (IC_RIGHT (ic)) == 0.0)
+ {
+ if (IS_OP_VOLATILE (IC_LEFT (ic)))
+ {
+ iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+ IC_RESULT (newic) = IC_LEFT (ic);
+ newic->filename = ic->filename;
+ newic->lineno = ic->lineno;
+ addiCodeToeBBlock (ebp, newic, ic->next);
+ }
+ ic->op = '=';
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+ /* if BITWISEAND then check if one of them is 0xff... */
+ /* if yes turn it into assignment */
+ {
+ unsigned val;
+
+ switch (getSize (operandType (IC_RIGHT (ic))))
+ {
+ case 1:
+ val = 0xff;
+ break;
+ case 2:
+ val = 0xffff;
+ break;
+ case 4:
+ val = 0xffffffff;
+ break;
+ default:
+ return;
+ }
+ if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
+ {
+ ic->op = '=';
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+ }
+ }
+ break;
+ case '|':
+ /* if both operands are equal */
+ /* if yes turn it into assignment */
+ if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
+ {
+ if (IS_OP_VOLATILE (IC_LEFT (ic)))
+ {
+ iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+ IC_RESULT (newic) = IC_LEFT (ic);
+ newic->filename = ic->filename;
+ newic->lineno = ic->lineno;
+ addiCodeToeBBlock (ebp, newic, ic->next);
+ }
+ ic->op = '=';
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+ /* swap literal to right ic */
+ if (IS_OP_LITERAL (IC_LEFT (ic)))
+ {
+ operand *op;
+
+ op = IC_LEFT (ic);
+ IC_LEFT (ic) = IC_RIGHT (ic);
+ IC_RIGHT (ic) = op;
+ }
+ if (IS_OP_LITERAL (IC_RIGHT (ic)))
+ {
+ /* if BITWISEOR then check if one of them is a zero */
+ /* if yes turn it into assignment */
+ if (operandLitValue (IC_RIGHT (ic)) == 0.0)
+ {
+ ic->op = '=';
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+ /* if BITWISEOR then check if one of them is 0xff... */
+ /* if yes turn it into 0xff... assignment */
+ {
+ unsigned val;
+
+ switch (getSize (operandType (IC_RIGHT (ic))))
+ {
+ case 1:
+ val = 0xff;
+ break;
+ case 2:
+ val = 0xffff;
+ break;
+ case 4:
+ val = 0xffffffff;
+ break;
+ default:
+ return;
+ }
+ if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
+ {
+ if (IS_OP_VOLATILE (IC_LEFT (ic)))
+ {
+ iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+ IC_RESULT (newic) = IC_LEFT (ic);
+ newic->filename = ic->filename;
+ newic->lineno = ic->lineno;
+ addiCodeToeBBlock (ebp, newic, ic->next);
+ }
+ ic->op = '=';
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+ }
+ }
+ break;
+ case '^':
+ /* if both operands are equal */
+ /* if yes turn it into 0 assignment */
+ if (isOperandEqual (IC_LEFT (ic), IC_RIGHT (ic)))
+ {
+ if (IS_OP_VOLATILE (IC_LEFT (ic)))
+ {
+ iCode *newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+ IC_RESULT (newic) = IC_LEFT (ic);
+ newic->filename = ic->filename;
+ newic->lineno = ic->lineno;
+ addiCodeToeBBlock (ebp, newic, ic->next);
+
+ newic = newiCode (DUMMY_READ_VOLATILE, NULL, IC_LEFT (ic));
+ IC_RESULT (newic) = IC_LEFT (ic);
+ newic->filename = ic->filename;
+ newic->lineno = ic->lineno;
+ addiCodeToeBBlock (ebp, newic, ic->next);
+ }
+ ic->op = '=';
+ IC_RIGHT (ic) = operandFromLit (0);
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+ /* swap literal to right ic */
+ if (IS_OP_LITERAL (IC_LEFT (ic)))
+ {
+ operand *op;
+
+ op = IC_LEFT (ic);
+ IC_LEFT (ic) = IC_RIGHT (ic);
+ IC_RIGHT (ic) = op;
+ }
+ /* if XOR then check if one of them is a zero */
+ /* if yes turn it into assignment */
+ if (IS_OP_LITERAL (IC_RIGHT (ic)))
+ {
+ if (operandLitValue (IC_RIGHT (ic)) == 0.0)
+ {
+ ic->op = '=';
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = NULL;
+ SET_RESULT_RIGHT (ic);
+ return;
+ }
+ }
+ break;
}
-
- return ;
+
+ return;
}
#define OTHERS_PARM(s) (s->_isparm && !s->ismyparm)
/*-----------------------------------------------------------------*/
/* updateSpillLocation - keeps track of register spill location */
/*-----------------------------------------------------------------*/
-void updateSpillLocation ( iCode *ic)
+void
+updateSpillLocation (iCode * ic, int induction)
{
-
- link *setype;
-
- if (POINTER_SET(ic))
- return;
-
- if (ic->nosupdate)
- return;
-
- /* for the form true_symbol := iTempNN */
- if (ASSIGN_ITEMP_TO_SYM(ic)
- && !SPIL_LOC(IC_RIGHT(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;
- }
-
- if (ASSIGN_ITEMP_TO_ITEMP(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)));
-
- 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));
- }
+ sym_link *setype;
+
+ if (POINTER_SET (ic))
+ return;
+
+ if (ic->nosupdate)
+ return;
+
+#if 0
+ /* for the form true_symbol := iTempNN */
+ if (ASSIGN_ITEMP_TO_SYM (ic) &&
+ !SPIL_LOC (IC_RIGHT (ic))) {
+
+ setype = getSpec (operandType (IC_RESULT (ic)));
+
+ if (!OP_SYMBOL(IC_RIGHT (ic))->noSpilLoc &&
+ !IS_VOLATILE (setype) &&
+ !IN_FARSPACE (SPEC_OCLS (setype)) &&
+ !OTHERS_PARM (OP_SYMBOL (IC_RESULT (ic))))
+ {
+ wassert(IS_SYMOP(IC_RESULT (ic)));
+ wassert(IS_SYMOP(IC_RIGHT (ic)));
+ SPIL_LOC (IC_RIGHT (ic)) =
+ IC_RESULT (ic)->operand.symOperand;
+ }
+
+ }
+#endif
+
+#if 0 /* this needs furthur investigation can save a lot of code */
+ if (ASSIGN_SYM_TO_ITEMP(ic) &&
+ !SPIL_LOC(IC_RESULT(ic))) {
+ if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
+ SPIL_LOC (IC_RESULT (ic)) =
+ IC_RIGHT (ic)->operand.symOperand;
+ }
+#endif
+ if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
+
+ if (!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)));
+
+ if (!OP_SYMBOL(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));
+ OP_SYMBOL (IC_RIGHT (ic))->prereqv =
+ OP_SYMBOL (IC_RESULT (ic))->prereqv;
+ }
+ }
+ /* special case for inductions */
+ if (induction &&
+ OP_SYMBOL(IC_RIGHT(ic))->isreqv &&
+ !OP_SYMBOL(IC_RESULT (ic))->noSpilLoc &&
+ !SPIL_LOC(IC_RESULT(ic))) {
+ SPIL_LOC (IC_RESULT (ic)) = SPIL_LOC (IC_RIGHT (ic));
+ OP_SYMBOL (IC_RESULT (ic))->prereqv =
+ OP_SYMBOL (IC_RIGHT (ic))->prereqv;
+ }
+ }
}
-
/*-----------------------------------------------------------------*/
/* 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);
+ /* 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 ;
-
- /* 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);
+ if (ic->op == JUMPTABLE)
+ 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);
}
- else /* must be ifx turn off the use */
- if (IS_SYMOP(IC_COND(ic)))
- bitVectUnSetBit (OP_USES(IC_COND(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);
}
/*-----------------------------------------------------------------*/
/* 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,
+ ebbIndex * ebbi)
{
- 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)++;
- }
+ operand *pdop;
+ symbol *label;
+
+ /* if the condition can be replaced */
+ if (!computeOnly)
+ {
+ pdop = NULL;
+ applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
+ if (pdop)
+ {
+ ReplaceOpWithCheaperOp(&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 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 (ebbi);
+ if (!options.lessPedantic)
+ {
+ werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
+ }
+ 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))) {
-
- remiCodeFromeBBlock(ebb,ic);
- 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 (ebbi, label)))
+ {
+ if (!options.lessPedantic)
+ {
+ werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
+ }
+ if (IS_OP_VOLATILE (IC_COND (ic)))
+ {
+ IC_RIGHT (ic) = IC_COND (ic);
+ IC_LEFT (ic) = NULL;
+ IC_RESULT (ic) = NULL;
+ ic->op = DUMMY_READ_VOLATILE;
+ }
+ else
+ {
+ remiCodeFromeBBlock (ebb, ic);
+ computeControlFlow (ebbi);
+ 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 ;
+
+ /* if it remains an IFX then update the use Set */
+ if (ic->op == IFX)
+ {
+ OP_USES(IC_COND (ic))=bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
+ setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
+ }
+ else if (ic->op == DUMMY_READ_VOLATILE)
+ {
+ OP_USES(IC_RIGHT (ic))=bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+ setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
+ }
+ return;
}
/*-----------------------------------------------------------------*/
/* diCodeForSym - finds the definiting instruction for a symbol */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(diCodeForSym)
+DEFSETFUNC (diCodeForSym)
{
- cseDef *cdp = item;
- V_ARG(operand *,sym);
- V_ARG(iCode **,dic);
-
- /* if already found */
- if (*dic)
- return 0;
-
- /* if not if this is the defining iCode */
- if (sym->key == cdp->key) {
- *dic = cdp->diCode ;
- return 1;
- }
+ cseDef *cdp = item;
+ V_ARG (operand *, sym);
+ V_ARG (iCode **, dic);
+ /* if already found */
+ if (*dic)
return 0;
+
+ /* if not if this is the defining iCode */
+ if (sym->key == cdp->key)
+ {
+ *dic = cdp->diCode;
+ return 1;
+ }
+
+ return 0;
}
/*-----------------------------------------------------------------*/
/* constFold - does some constant folding */
/*-----------------------------------------------------------------*/
-int constFold (iCode *ic, set *cseSet)
+int
+constFold (iCode * ic, set * cseSet)
{
- iCode *dic = NULL;
- iCode *ldic= NULL;
- /* this routine will change
- a = b + 10;
- c = a + 10;
- to
- c = b + 20; */
-
- /* deal with only + & - */
- if (ic->op != '+' &&
- 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;
-
- /* check if operation with a literal */
- if (!IS_OP_LITERAL(IC_RIGHT(ic)))
- return 0;
-
- /* check if we can find a definition for the
- right hand side */
- if (!(applyToSet(cseSet,diCodeForSym,IC_LEFT(ic),&dic)))
- return 0;
-
- /* check that this is also a +/- */
- if (dic->op != '+' && dic->op != '-')
- return 0;
-
- /* with a literal */
- if (!IS_OP_LITERAL(IC_RIGHT(dic)))
- 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));
- if (ic->op == dic->op )
- 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)));
-
- if (IS_ITEMP(IC_RESULT(ic))) {
- SPIL_LOC(IC_RESULT(ic)) = NULL;
- IC_RESULT(ic)->noSpilLoc = 1;
+ iCode *dic = NULL;
+ iCode *ldic = NULL;
+ /* this routine will change
+ a = b + 10;
+ c = a + 10;
+ to
+ c = b + 20; */
+
+ /* deal with only + & - */
+ if (ic->op != '+' &&
+ ic->op != '-')
+ return 0;
+
+ /* this check is a heuristic to prevent live ranges
+ from becoming too long */
+ if (IS_PTR (operandType (IC_RESULT (ic))))
+ return 0;
+
+ /* check if operation with a literal */
+ if (!IS_OP_LITERAL (IC_RIGHT (ic)))
+ return 0;
+
+ /* check if we can find a definition for the
+ left hand side */
+ if (!(applyToSet (cseSet, diCodeForSym, IC_LEFT (ic), &dic)))
+ return 0;
+
+ /* check that this is also a +/- */
+ if (dic->op != '+' && dic->op != '-')
+ return 0;
+
+ /* with a literal */
+ if (!IS_OP_LITERAL (IC_RIGHT (dic)))
+ 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));
+ if (ic->op == dic->op)
+ 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)));
+
+ if (IS_ITEMP (IC_RESULT (ic)))
+ {
+ SPIL_LOC (IC_RESULT (ic)) = NULL;
+ OP_SYMBOL(IC_RESULT (ic))->noSpilLoc = 1;
}
-
-
- return 1;
+
+
+ return 1;
}
/*-----------------------------------------------------------------*/
/* will delete from cseSet all get pointers computed from this */
/* pointer. A simple ifOperandsHave is not good enough here */
/*-----------------------------------------------------------------*/
-static void deleteGetPointers (set **cseSet, set **pss, operand *op,eBBlock *ebb)
+static void
+deleteGetPointers (set ** cseSet, set ** pss, operand * op, eBBlock * ebb)
{
- set *compItems = NULL;
- cseDef *cdp ;
- operand *cop;
-
- /* easy return */
- if (!*cseSet && !*pss)
- 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));
- }
- }
+ set *compItems = NULL;
+ cseDef *cdp;
+ operand *cop;
+ int changes;
+
+ /* easy return */
+ if (!*cseSet && !*pss)
+ return;
+
+ addSet (&compItems, op);
+
+ /* Recursively find all items computed from this operand .
+ This done fairly simply go thru the list and find
+ those that are computed by arthimetic with these
+ ops */
+ /* Also check for those computed from our computed
+ list . This will take care of situations like
+ iTemp1 = iTemp0 + 8;
+ iTemp2 = iTemp1 + 8; */
+ do
+ {
+ changes = 0;
+ for (cdp = setFirstItem (*cseSet); cdp; cdp = setNextItem (*cseSet))
+ {
+ if (IS_ARITHMETIC_OP (cdp->diCode) || POINTER_GET(cdp->diCode))
+ {
+ if (isinSetWith (compItems, (void*)IC_LEFT (cdp->diCode),
+ (insetwithFunc)isOperandEqual) ||
+ isinSetWith (compItems, (void*)IC_RIGHT (cdp->diCode),
+ (insetwithFunc)isOperandEqual))
+ {
+ if (!isinSetWith (compItems, (void*)IC_RESULT (cdp->diCode),
+ (insetwithFunc)isOperandEqual))
+ {
+ addSet (&compItems, IC_RESULT (cdp->diCode));
+ changes++;
+ }
+ }
+ }
+ }
}
-
- /* now delete all pointer gets with this op */
- deleteItemIf(cseSet,ifPointerGet,op);
- deleteItemIf(pss,ifPointerSet,op);
-
- /* set the bit vector used by dataFlow computation later */
- 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);
+ while (changes);
+
+ /* 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 (cseSet, ifDefSymIsX, cop);
+ deleteItemIf (pss, ifPointerSet, cop);
}
}
/*-----------------------------------------------------------------*/
-/* delGetPointerSucc - delete get pointer from inExprs of succ with*/
+/* delGetPointerSucc - delete get pointer from inExprs of succ with */
/* dfnum > supplied */
/*-----------------------------------------------------------------*/
-DEFSETFUNC(delGetPointerSucc)
+DEFSETFUNC (delGetPointerSucc)
{
- eBBlock *ebp = item;
- V_ARG(operand *,op);
- V_ARG(int,dfnum);
-
- if (ebp->visited)
- return 0;
-
- ebp->visited = 1;
- if (ebp->dfnum > dfnum) {
- deleteItemIf(&ebp->inExprs,ifPointerGet,op);
+ eBBlock *ebp = item;
+ V_ARG (operand *, op);
+ V_ARG (int, dfnum);
+
+ if (ebp->visited)
+ return 0;
+
+ ebp->visited = 1;
+ if (ebp->dfnum > dfnum)
+ {
+ deleteItemIf (&ebp->inExprs, ifPointerGet, op);
}
- return applyToSet(ebp->succList,delGetPointerSucc,op,dfnum);
-}
+ return applyToSet (ebp->succList, delGetPointerSucc, op, dfnum);
+}
/*-----------------------------------------------------------------*/
/* fixUpTypes - KLUGE HACK fixup a lowering problem */
/*-----------------------------------------------------------------*/
-static void fixUpTypes(iCode *ic)
+static void
+fixUpTypes (iCode * ic)
+{
+ sym_link *t1 = operandType (IC_LEFT (ic)), *t2;
+
+ /* if (TARGET_IS_DS390) */
+ if (options.model == MODEL_FLAT24)
+ {
+ /* 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) &&
+ compareType (t2 = operandType (IC_RESULT (ic)), t1) == 1)
+ {
+ setOperandType (IC_RESULT (ic), t2->next);
+ }
+}
+
+/*-----------------------------------------------------------------*/
+/* isSignedOp - will return 1 if sign is important to operation */
+/*-----------------------------------------------------------------*/
+static int isSignedOp (iCode *ic)
{
- link *t1 = operandType(IC_LEFT(ic)) ,*t2;
-
- extern PORT ds390_port;
-
- if (port == &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);
- }
+ switch (ic->op) {
+ case '!':
+ case '~':
+ case UNARYMINUS:
+ case IPUSH:
+ case IPOP:
+ case CALL:
+ case PCALL:
+ case RETURN:
+ case '+':
+ case '-':
+ case EQ_OP:
+ case AND_OP:
+ case OR_OP:
+ case '^':
+ case '|':
+ case BITWISEAND:
+ case INLINEASM:
+ case LEFT_OP:
+ case GET_VALUE_AT_ADDRESS:
+ case '=':
+ case IFX:
+ case RECEIVE:
+ case SEND:
+ return 0;
+ case '*':
+ case '/':
+ case '%':
+ case '>':
+ case '<':
+ case LE_OP:
+ case GE_OP:
+ case NE_OP:
+ case RRC:
+ case RLC:
+ case GETHBIT:
+ case GETABIT:
+ case GETBYTE:
+ case GETWORD:
+ case RIGHT_OP:
+ case CAST:
+ case ARRAYINIT:
+ return 1;
+ default:
+ return 0;
+ }
+ }
+
+#if 0
+static void
+dumpCseSet(set *cseSet)
+{
+ while (cseSet)
+ {
+ cseDef *item=cseSet->item;
+ printf("->");
+ printOperand (item->sym, NULL);
+ printf(" ");
+ piCode (item->diCode, NULL);
+ cseSet = cseSet->next;
+ }
}
+#endif
/*-----------------------------------------------------------------*/
/* 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,
+ ebbIndex * ebbi)
{
- set *cseSet ;
- iCode *ic ;
- int change = 0 ;
- int i;
- set *ptrSetSet = NULL;
-
- /* if this block is not reachable */
- if (ebb->noPath)
- return change;
-
- /* set of common subexpressions */
- cseSet = setFromSet (ebb->inExprs) ;
-
- /* these will be computed by this routine */
- setToNull ((void **)&ebb->outDefs);
- setToNull ((void **)&ebb->defSet);
- setToNull ((void **)&ebb->usesDefs);
- setToNull ((void **)&ebb->ptrsSet);
- setToNull ((void **)&ebb->addrOf);
- setToNull ((void **)&ebb->ldefs);
-
- ebb->outDefs = bitVectCopy (ebb->inDefs);
- bitVectDefault = iCodeKey;
- ebb->defSet = newBitVect(iCodeKey);
- ebb->usesDefs=newBitVect(iCodeKey);
-
- /* 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);
- /* 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)) {
- 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));
- }
+ eBBlock ** ebbs = ebbi->bbOrder;
+ int count = ebbi->count;
+ set *cseSet;
+ iCode *ic;
+ int change = 0;
+ int i;
+ set *ptrSetSet = NULL;
+ cseDef *expr;
+
+ /* if this block is not reachable */
+ if (ebb->noPath)
+ return 0;
+
+ /* set of common subexpressions */
+ cseSet = setFromSet (ebb->inExprs);
+
+ /* these will be computed by this routine */
+ setToNull ((void *) &ebb->outDefs);
+ setToNull ((void *) &ebb->defSet);
+ setToNull ((void *) &ebb->usesDefs);
+ setToNull ((void *) &ebb->ptrsSet);
+ setToNull ((void *) &ebb->addrOf);
+ setToNull ((void *) &ebb->ldefs);
+
+ ebb->outDefs = bitVectCopy (ebb->inDefs);
+ bitVectDefault = iCodeKey;
+ ebb->defSet = newBitVect (iCodeKey);
+ ebb->usesDefs = newBitVect (iCodeKey);
+
+ /* for all the instructions in this block do */
+ for (ic = ebb->sch; ic; ic = ic->next)
+ {
+ iCode *pdic;
+ operand *pdop;
+ iCode *defic;
+ int checkSign ;
+
+ ic->eBBlockNum = ebb->bbnum;
+
+ if (SKIP_IC2 (ic))
+ continue;
+
+ /* if this is an assignment from true symbol
+ to a temp then do pointer post inc/dec optimization */
+ 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);
+
+ /* and also iTemps derived from globals */
+ deleteItemIf (&cseSet, ifFromGlobal);
+
+ /* Delete iTemps derived from symbols whose address */
+ /* has been taken */
+ deleteItemIf (&cseSet, ifFromAddrTaken);
+
+ /* 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);
+
+ /* can't cache pointer set/get operations across a call */
+ deleteSet (&ptrSetSet);
+ }
+
+ /* 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, 0);
+ if (pdop)
+ ReplaceOpWithCheaperOp(&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)
+ {
+ if (IS_SYMOP (IC_JTCOND (ic)))
+ {
+ 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;
+
+ if (!computeOnly)
+ {
+ /* do some algebraic optimizations if possible */
+ algebraicOpts (ic, ebb);
+ while (constFold (ic, cseSet));
+ }
+
+ /* small kludge */
+ if (POINTER_GET (ic))
+ {
+ if (!IS_PTR (operandType (IC_LEFT (ic))))
+ {
+ setOperandType (IC_LEFT (ic),
+ aggrToPtr (operandType (IC_LEFT (ic)), FALSE));
+ IC_LEFT (ic)->aggr2ptr = 0;
+ fixUpTypes (ic);
+ }
+ else if (IC_LEFT (ic)->aggr2ptr == 1)
+ {/* band aid for kludge */
+ setOperandType (IC_LEFT (ic),
+ aggrToPtr (operandType (IC_LEFT (ic)), TRUE));
+ IC_LEFT (ic)->aggr2ptr++;
+ fixUpTypes (ic);
+ }
+ }
+
+ if (POINTER_SET (ic))
+ {
+ if (!IS_PTR (operandType (IC_RESULT (ic))))
+ {
+ setOperandType (IC_RESULT (ic),
+ aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
+ IC_RESULT (ic)->aggr2ptr = 0;
+ }
+ else if (IC_RESULT (ic)->aggr2ptr == 1)
+ {/* band aid for kludge */
+ setOperandType (IC_RESULT (ic),
+ aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
+ IC_RESULT (ic)->aggr2ptr++;
+ }
+ }
+
+ /* if this is a condition statement then */
+ /* check if the condition can be replaced */
+ if (ic->op == IFX)
+ {
+ ifxOptimize (ic, cseSet, computeOnly,
+ ebb, &change,
+ ebbi);
+ continue;
+ }
+
+ /* if the assignment & result is a temp */
+ /* see if we can replace it */
+ if (!computeOnly && ic->op == '=')
+ {
+
+ /* update the spill location for this */
+ updateSpillLocation (ic,0);
+
+ if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)) &&
+ !(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
+ {
+ pdop = NULL;
+ applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
+ if (pdop && !computeOnly && IS_ITEMP (pdop))
+ {
+ ReplaceOpWithCheaperOp (&IC_RESULT(ic), pdop);
+ if (!IS_PTR (operandType (IC_RESULT (ic))))
+ {
+ setOperandType (IC_RESULT (ic),
+ aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
+ }
+ }
+ }
+ }
+
+ checkSign = isSignedOp(ic);
+
+ /* 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)) &&
+ !IS_BITFIELD (OP_SYM_ETYPE (IC_LEFT (ic))) &&
+ !computeOnly && ic->op != ADDRESS_OF)
+ {
+
+ pdop = NULL;
+ applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
+ if (pdop)
+ {
+ if (POINTER_GET (ic))
+ {
+ if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
+ {
+ /* some non dominating block does POINTER_SET with
+ this variable .. unsafe to remove any POINTER_GETs */
+ if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
+ ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
+ ReplaceOpWithCheaperOp(&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;
+ ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
+ SET_ISADDR (IC_RESULT (ic), 0);
+ }
+
+ }
+ else
+ {
+ ReplaceOpWithCheaperOp(&IC_LEFT(ic), pdop);
+ change = 1;
+ }
+ }
+ }
+
+ /* right operand */
+ if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
+ {
+
+ pdop = NULL;
+ applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
+ if (pdop) {
+ ReplaceOpWithCheaperOp(&IC_RIGHT(ic), pdop);
+ change = 1;
+ }
+ }
+
+ /* if left or right changed then do algebraic */
+ if (!computeOnly && change)
+ {
+ algebraicOpts (ic, ebb);
+ while (constFold (ic, cseSet));
+ }
+
+ /* if after all this it becomes an assignment to self
+ then delete it and continue */
+ if (ASSIGNMENT_TO_SELF (ic) && !isOperandVolatile (IC_RIGHT(ic), FALSE))
+ {
+ 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 && compareType (operandType (IC_RESULT (pdic)),
+ operandType (IC_RESULT (ic))) != 1)
+ pdic = NULL;
+ if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
+ pdic = NULL;
+ }
+
+ /* Alternate code */
+ if (pdic && IS_ITEMP(IC_RESULT(ic))) {
+ if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
+ /* Mmm, found an equivalent pointer get at a lower level.
+ This could be a loop however with the same pointer set
+ later on */
+ } else {
+ /* if previous definition found change this to an assignment */
+ ic->op = '=';
+ IC_LEFT(ic) = NULL;
+ IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
+ SET_ISADDR(IC_RESULT(ic),0);
+ SET_ISADDR(IC_RIGHT (ic),0);
+ }
+ }
+
+ if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
+ cseDef *csed;
+ deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
+ csed = newCseDef (IC_RESULT (ic), ic);
+ updateCseDefAncestors (csed, cseSet);
+ addSetHead (&cseSet, csed);
+ }
+ 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) &&
+ IS_SYMOP (IC_RESULT (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)) && IS_SYMOP (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) && IS_SYMOP (IC_RESULT (ic)))
+ {
+ 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 definition set */
+ if (IS_SYMOP (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->outDefs = bitVectUnion (ebb->outDefs,ebb->defSet);
- ebb->ptrsSet = bitVectUnion (ebb->ptrsSet,ebb->inPtrsSet);
- return change ;
+ for (expr=setFirstItem (ebb->inExprs); expr; expr=setNextItem (ebb->inExprs))
+ if (!isinSetWith (cseSet, expr, isCseDefEqual) &&
+ !isinSetWith (ebb->killedExprs, expr, isCseDefEqual)) {
+ addSetHead (&ebb->killedExprs, expr);
+ }
+ setToNull ((void *) &ebb->outExprs);
+ ebb->outExprs = cseSet;
+ ebb->outDefs = bitVectUnion (ebb->outDefs, ebb->defSet);
+ ebb->ptrsSet = bitVectUnion (ebb->ptrsSet, ebb->inPtrsSet);
+ return change;
}
/*-----------------------------------------------------------------*/
-/* cseAllBlocks - will sequentially go thru & do cse for all blocks*/
+/* cseAllBlocks - will sequentially go thru & do cse for all blocks */
/*-----------------------------------------------------------------*/
-int cseAllBlocks (eBBlock **ebbs,int count)
+int
+cseAllBlocks (ebbIndex * ebbi, int computeOnly)
{
- int i;
- int change = 0 ;
+ eBBlock ** ebbs = ebbi->dfOrder;
+ int count = ebbi->count;
+ int i;
+ int change = 0;
- /* if optimization turned off */
+ /* 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], computeOnly, ebbi);
- return change;
+ return change;
}
-