#include "common.h"
#include "newalloc.h"
+#include "dbuf_string.h"
/*-----------------------------------------------------------------*/
{
cseDef *cdp = item;
iCodeTable *icTab;
+ struct dbuf_s dbuf;
(void) ap;
fprintf (stdout, "**null op**");
printOperand (cdp->sym, stdout);
icTab = getTableEntry (cdp->diCode->op);
- icTab->iCodePrint (stdout, cdp->diCode, icTab->printName);
+ 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 %s with %s: ",
- IS_SYMOP((*op)) ? OP_SYMBOL((*op))->name : "!SYM",
- IS_SYMOP(cop) ? OP_SYMBOL(cop)->name : "!SYM");
+ printf ("ReplaceOpWithCheaperOp\n\t");
+ printOperand (*op, stdout);
+ printf ("\nwith\t");
+ printOperand (cop, stdout);
+
// if op is a register equivalent
- if (IS_ITEMP(cop) && OP_SYMBOL((*op))->isreqv) {
+ 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");
{
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 siaddr;
+ int isaddr;
/* do the special cases first */
if (lic->op == IFX)
bitVectUnSetBit (OP_USES (from), lic->key);
OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
- siaddr = IC_COND (lic)->isaddr;
+ isaddr = IC_COND (lic)->isaddr;
IC_COND (lic) = operandFromOperand (to);
- IC_COND (lic)->isaddr = siaddr;
+ IC_COND (lic)->isaddr = isaddr;
}
continue;
bitVectUnSetBit (OP_USES (from), lic->key);
OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
- siaddr = IC_COND (lic)->isaddr;
+ isaddr = IC_COND (lic)->isaddr;
IC_JTCOND (lic) = operandFromOperand (to);
- IC_JTCOND (lic)->isaddr = siaddr;
+ IC_JTCOND (lic)->isaddr = isaddr;
}
continue;
bitVectUnSetBit (OP_DEFS (from), lic->key);
OP_DEFS(to)=bitVectSetBit (OP_DEFS (to), lic->key);
}
- siaddr = IC_RESULT (lic)->isaddr;
+ isaddr = IC_RESULT (lic)->isaddr;
IC_RESULT (lic) = operandFromOperand (to);
- IC_RESULT (lic)->isaddr = siaddr;
+ IC_RESULT (lic)->isaddr = isaddr;
}
if (IS_SYMOP (to) &&
{
bitVectUnSetBit (OP_USES (from), lic->key);
OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
- siaddr = IC_RIGHT (lic)->isaddr;
+ isaddr = IC_RIGHT (lic)->isaddr;
IC_RIGHT (lic) = operandFromOperand (to);
- IC_RIGHT (lic)->isaddr = siaddr;
+ IC_RIGHT (lic)->isaddr = isaddr;
}
if (IS_SYMOP (to) &&
{
bitVectUnSetBit (OP_USES (from), lic->key);
OP_USES(to)=bitVectSetBit (OP_USES (to), lic->key);
- siaddr = IC_LEFT (lic)->isaddr;
+ isaddr = IC_LEFT (lic)->isaddr;
IC_LEFT (lic) = operandFromOperand (to);
- IC_LEFT (lic)->isaddr = siaddr;
+ IC_LEFT (lic)->isaddr = isaddr;
}
}
}
IS_TRUE_SYMOP (IC_RIGHT (cdp->diCode)))
*opp = IC_RESULT (cdp->diCode);
else {
- /* if straight assignement && and both
+ /* 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
- an induction variable
+ is an induction variable
*/
if (!POINTER_SET (cdp->diCode) &&
IS_ITEMP (IC_RESULT (cdp->diCode)) &&
(*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)))
{
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;
}
/* if addition then check if one of them is a zero */
- /* if yes turn it into assignmnt or cast */
+ /* 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)
+ if ((typematch<0) || (IS_TRUE_SYMOP (IC_RIGHT (ic))))
{
ic->op = CAST;
IC_LEFT (ic) = operandFromLink (operandType (IC_RESULT (ic)));
int typematch;
typematch = compareType (operandType (IC_RESULT (ic)),
operandType (IC_LEFT (ic)));
- if (typematch<0)
+ if ((typematch<0) || (IS_TRUE_SYMOP (IC_LEFT (ic))))
{
ic->op = CAST;
IC_RIGHT (ic) = IC_LEFT (ic);
}
break;
case '-':
- /* if subtracting the the same thing then zero */
+ /* if subtracting the same thing then zero */
if (IC_LEFT (ic)->key == IC_RIGHT (ic)->key)
{
ic->op = '=';
case '*':
if (IS_OP_LITERAL (IC_LEFT (ic)))
{
+ double leftValue = operandLitValue (IC_LEFT (ic));
- if (operandLitValue (IC_LEFT (ic)) == 0.0)
+ if (leftValue == 0.0)
{
ic->op = '=';
IC_RIGHT (ic) = IC_LEFT (ic);
SET_RESULT_RIGHT (ic);
return;
}
- if (operandLitValue (IC_LEFT (ic)) == 1.0)
+ if (leftValue == 1.0)
{
/* '*' can have two unsigned chars as operands */
/* and an unsigned int as result. */
}
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 (operandLitValue (IC_RIGHT (ic)) == 0.0)
+ if (rightValue == 0.0)
{
ic->op = '=';
IC_LEFT (ic) = NULL;
return;
}
- if (operandLitValue (IC_RIGHT (ic)) == 1.0)
+ if (rightValue == 1.0)
{
/* '*' can have two unsigned chars as operands */
/* and an unsigned int as result. */
}
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 '/':
IC_LEFT (ic) = NULL;
IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
IC_RESULT (ic)->isaddr = 0;
- break;
+ 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)) &&
- operandLitValue (IC_RIGHT (ic)) == 1.0)
+ /* 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:
}
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))))
{
- 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);
- }
+ 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;
+ }
+ break;
case '!':
if (IS_OP_LITERAL (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);
}
{
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);
}
default:
return;
}
- if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
+ if (((unsigned) double2ul (operandLitValue (IC_RIGHT (ic))) & val) == val)
{
ic->op = '=';
IC_RIGHT (ic) = 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);
}
default:
return;
}
- if (((unsigned) operandLitValue (IC_RIGHT (ic)) & val) == val)
+ 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);
}
{
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;
+ 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)))
/* 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
{
/* 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);
- }
+ if (!options.lessPedantic)
+ {
+ werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
+ }
return;
}
if (elementsInSet (ebb->succList) == 1 &&
isinSet (ebb->succList, eBBWithEntryLabel (ebbi, label)))
{
-
- if (!options.lessPedantic) {
- werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
- }
+ if (!options.lessPedantic)
+ {
+ werrorfl (ic->filename, ic->lineno, W_CONTROL_FLOW);
+ }
if (IS_OP_VOLATILE (IC_COND (ic)))
{
IC_RIGHT (ic) = IC_COND (ic);
}
}
-
- /* if it remains an IFX the update the use Set */
+ /* 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);
continue;
/* if this is an assignment from true symbol
- to a temp then do pointer post inc/dec optimzation */
+ to a temp then do pointer post inc/dec optimization */
if (ic->op == '=' && !POINTER_SET (ic) &&
IS_PTR (operandType (IC_RESULT (ic))))
{
/* and also iTemps derived from globals */
deleteItemIf (&cseSet, ifFromGlobal);
-
+
/* Delete iTemps derived from symbols whose address */
/* has been taken */
deleteItemIf (&cseSet, ifFromAddrTaken);
IC_LEFT (ic)->aggr2ptr = 0;
fixUpTypes (ic);
}
- else if (IC_LEFT (ic)->aggr2ptr)
+ 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 = 0;
+ IC_LEFT (ic)->aggr2ptr++;
fixUpTypes (ic);
}
}
aggrToPtr (operandType (IC_RESULT (ic)), FALSE));
IC_RESULT (ic)->aggr2ptr = 0;
}
- else if (IC_RESULT (ic)->aggr2ptr)
+ 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 = 0;
+ IC_RESULT (ic)->aggr2ptr++;
}
}
/* update the spill location for this */
updateSpillLocation (ic,0);
- if (POINTER_SET (ic) &&
+ if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic)) &&
!(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
{
pdop = NULL;
}
}
- /*right operand */
+ /* right operand */
if (IS_SYMOP (IC_RIGHT (ic)) && !computeOnly)
{
IS_ITEMP (IC_RESULT (ic)) &&
!computeOnly)
{
- applyToSet (cseSet, findPrevIc, ic, &pdic);
+ applyToSet (cseSet, findPrevIc, ic, &pdic);
if (pdic && compareType (operandType (IC_RESULT (pdic)),
operandType (IC_RESULT (ic))) != 1)
pdic = NULL;
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))))
{
/* 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))
+ 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 */
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))
+ if (POINTER_SET (defic) && IS_SYMOP (IC_RESULT (ic)))
{
OP_USES(IC_RESULT (ic))=
bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
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);
+ /* 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 */