cseDef *cdp;
assert (sym);
- cdp = Safe_calloc (1, sizeof (cseDef));
+ cdp = Safe_alloc (sizeof (cseDef));
cdp->sym = sym;
cdp->diCode = ic;
cseDef *cdp = item;
V_ARG (operand *, cop);
V_ARG (operand **, opp);
+ V_ARG (int, checkSign);
/* if we have already found it */
if (*opp)
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)) &&
*opp = IC_RESULT (cdp->diCode);
if ((*opp) &&
- (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp))) &&
- (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp))))
- {
+ (isOperandLiteral(*opp) || !checkSign ||
+ (checkSign &&
+ (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
+ (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp)))))))
+ {
if ((isGlobalInNearSpace (cop) &&
!isOperandLiteral (*opp)) ||
if (isiCodeEqual (ic, cdp->diCode) &&
isOperandEqual (cdp->sym, IC_RESULT (cdp->diCode)))
{
- *icp = cdp->diCode;
+ *icp = cdp->diCode;
return 1;
}
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;
+}
+
/*-----------------------------------------------------------------*/
/* ifDefGlobal - if definition is global */
/*-----------------------------------------------------------------*/
IC_LEFT (ic) = NULL;
IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
IC_RESULT (ic)->isaddr = 0;
+ break;
}
/* if this is a division then check if right */
/* is one then change it to an assignment */
if (!computeOnly)
{
pdop = NULL;
- applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop);
+ applyToSetFTrue (cseSet, findCheaperOp, IC_COND (ic), &pdop, 0);
if (pdop)
{
IC_COND (ic) = pdop;
/* too often, if it does happen then the user pays */
/* the price */
computeControlFlow (ebbs, count, 1);
- werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+ if (!options.lessPedantic) {
+ werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+ }
return;
}
remiCodeFromeBBlock (ebb, ic);
computeControlFlow (ebbs, count, 1);
- werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+ if (!options.lessPedantic) {
+ werror (W_CONTROL_FLOW, ic->filename, ic->lineno);
+ }
return;
}
}
}
+/*-----------------------------------------------------------------*/
+/* isSignedOp - will return 1 if sign is important to operation */
+/*-----------------------------------------------------------------*/
+static int isSignedOp (iCode *ic)
+{
+ 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 RIGHT_OP:
+ case CAST:
+ case ARRAYINIT:
+ return 1;
+ default:
+ return 0;
+ }
+ }
/*-----------------------------------------------------------------*/
/* cseBBlock - common subexpression elimination for basic blocks */
/* this is the hackiest kludgiest routine in the whole */
iCode *pdic;
operand *pdop;
iCode *defic;
+ int checkSign ;
+
+ ic->eBBlockNum = ebb->bbnum;
if (SKIP_IC2 (ic))
continue;
/* delete global variables from the cseSet
since they can be modified by the function call */
deleteItemIf (&cseSet, ifDefGlobal);
+
+ /* and also itemps assigned from globals */
+ deleteItemIf (&cseSet, ifAssignedFromGlobal);
+
/* 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 */
if (!computeOnly)
{
pdop = NULL;
- applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop);
+ applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, 0);
if (pdop)
IC_LEFT (ic) = pdop;
}
!(IS_BITFIELD (OP_SYMBOL (IC_RESULT (ic))->etype)))
{
pdop = NULL;
- applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop);
+ applyToSetFTrue (cseSet, findCheaperOp, IC_RESULT (ic), &pdop, 0);
if (pdop && IS_ITEMP (pdop) && !computeOnly)
IC_RESULT (ic) = pdop;
}
}
+ 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 */
{
pdop = NULL;
- applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop);
+ applyToSetFTrue (cseSet, findCheaperOp, IC_LEFT (ic), &pdop, checkSign);
if (pdop)
{
if (POINTER_GET (ic))
{
pdop = NULL;
- applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop);
+ applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop, checkSign);
if (pdop)
{
-
IC_RIGHT (ic) = pdop;
change = 1;
}
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;
+ if (pdic && port->cseOk && (*port->cseOk)(ic,pdic) == 0)
+ 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;
+ /* Alternate code */
+ if (pdic && IS_ITEMP(IC_RESULT(ic))) {
+ /* 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)) {
+ 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