}
}
+/*-----------------------------------------------------------------*/
+/* isLocalWithoutDef - return 1 if sym might be used without a */
+/* defining iCode */
+/*-----------------------------------------------------------------*/
+static int
+isLocalWithoutDef (symbol * sym)
+{
+ if (!sym->level)
+ return 0;
+
+ if (IS_STATIC (sym->etype))
+ return 0;
+
+ if (IS_VOLATILE (sym->type))
+ return 0;
+
+ if (sym->_isparm)
+ return 0;
+
+ if (IS_AGGREGATE (sym->type))
+ return 0;
+
+ if (sym->addrtaken)
+ return 0;
+
+ return !sym->defs;
+}
+
/*-----------------------------------------------------------------*/
/* replaceRegEqv - replace all local variables with their reqv */
/*-----------------------------------------------------------------*/
{
int i;
+ /* Update the symbols' def bitvector so we know if there is */
+ /* a defining iCode or not. Only replace a local variable */
+ /* with its register equivalent if there is a defining iCode; */
+ /* otherwise, the port's register allocater may choke. */
+ cseAllBlocks (ebbs, count, TRUE);
+
for (i = 0; i < count; i++)
{
if (ic->op == IFX)
{
-
+ if (IC_COND (ic) &&
+ IS_TRUE_SYMOP (IC_COND (ic)) &&
+ isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
+ {
+ werrorfl (ic->filename, ic->lineno,
+ W_LOCAL_NOINIT,
+ OP_SYMBOL (IC_COND (ic))->name);
+ OP_REQV (IC_COND (ic)) = NULL;
+ OP_SYMBOL (IC_COND (ic))->allocreq = 1;
+ }
+
if (IS_TRUE_SYMOP (IC_COND (ic)) &&
OP_REQV (IC_COND (ic)))
IC_COND (ic) = opFromOpWithDU (OP_REQV (IC_COND (ic)),
continue;
}
+
if (ic->op == JUMPTABLE)
{
+ if (IC_JTCOND (ic) &&
+ IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
+ isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
+ {
+ werrorfl (ic->filename, ic->lineno,
+ W_LOCAL_NOINIT,
+ OP_SYMBOL (IC_JTCOND (ic))->name);
+ OP_REQV (IC_JTCOND (ic)) = NULL;
+ OP_SYMBOL (IC_JTCOND (ic))->allocreq = 1;
+ }
+
if (IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
OP_REQV (IC_JTCOND (ic)))
IC_JTCOND (ic) = opFromOpWithDU (OP_REQV (IC_JTCOND (ic)),
OP_SYMBOL (IC_RESULT (ic))->uses);
}
+ if (IC_RIGHT (ic) &&
+ IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
+ isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
+ {
+ werrorfl (ic->filename, ic->lineno,
+ W_LOCAL_NOINIT,
+ OP_SYMBOL (IC_RIGHT (ic))->name);
+ OP_REQV (IC_RIGHT (ic)) = NULL;
+ OP_SYMBOL (IC_RIGHT (ic))->allocreq = 1;
+ }
+
if (IC_RIGHT (ic) &&
IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
OP_REQV (IC_RIGHT (ic)))
IC_RIGHT (ic)->isaddr = 0;
}
+ if (IC_LEFT (ic) &&
+ IS_TRUE_SYMOP (IC_LEFT (ic)) &&
+ isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
+ {
+ werrorfl (ic->filename, ic->lineno,
+ W_LOCAL_NOINIT,
+ OP_SYMBOL (IC_LEFT (ic))->name);
+ OP_REQV (IC_LEFT (ic)) = NULL;
+ OP_SYMBOL (IC_LEFT (ic))->allocreq = 1;
+ }
+
if (IC_LEFT (ic) &&
IS_TRUE_SYMOP (IC_LEFT (ic)) &&
OP_REQV (IC_LEFT (ic)))
if (SKIP_IC (ic) ||
ic->op == IFX ||
ic->op == RETURN ||
- ic->op == DUMMY_READ_VOLATILE)
+ ic->op == DUMMY_READ_VOLATILE ||
+ ic->op == CRITICAL ||
+ ic->op == ENDCRITICAL)
continue;
+ /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
+ /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are */
+ /* valid. */
+
/* if the result is volatile then continue */
if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
continue;
/* kill this one if required */
if (kill)
{
+ bool volLeft = IS_SYMOP (IC_LEFT (ic))
+ && isOperandVolatile (IC_LEFT (ic), FALSE);
+ bool volRight = IS_SYMOP (IC_RIGHT (ic))
+ && isOperandVolatile (IC_RIGHT (ic), FALSE);
+
+
+ if (ic->next && ic->seqPoint == ic->next->seqPoint
+ && (ic->next->op == '+' || ic->next->op == '-'))
+ {
+ if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
+ || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
+ volLeft = FALSE;
+ if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
+ || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
+ volRight = FALSE;
+ }
+
change = 1;
gchange++;
- /* eliminate this */
- remiCodeFromeBBlock (ebbs[i], ic);
-
+
/* now delete from defUseSet */
deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
/* and defset of the block */
bitVectUnSetBit (ebbs[i]->defSet, ic->key);
- /* for the left & right remove the usage */
- if (IS_SYMOP (IC_LEFT (ic)))
- bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+ /* delete the result */
+ IC_RESULT (ic) = NULL;
+
+ if (volLeft || volRight)
+ {
+ /* something is volatile, so keep the iCode */
+ /* and change the operator instead */
+ ic->op = DUMMY_READ_VOLATILE;
+
+ /* keep only the volatile operands */
+ if (!volLeft)
+ IC_LEFT (ic) = NULL;
+ if (!volRight)
+ IC_RIGHT (ic) = NULL;
+ }
+ else
+ {
+ /* nothing is volatile, eliminate the iCode */
+ remiCodeFromeBBlock (ebbs[i], ic);
+
+ /* for the left & right remove the usage */
+ 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 (IS_SYMOP (IC_RIGHT (ic)))
+ bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+ }
}
} /* end of all instructions */
ebbs = iCodeBreakDown (ic, &count);
saveCount = count;
+ /* hash the iCode keys so that we can quickly index */
+ /* them in the rest of the optimization steps */
+ setToNull ((void *) &iCodehTab);
+ iCodehTab = newHashTable (iCodeKey);
+ hashiCodeKeys (ebbs, count);
+
/* compute the control flow */
computeControlFlow (ebbs, count, 0);
bp;
bp=setNextItem(ebbs[saveCount-1]->predList)) {
if (bp->ech->op != RETURN) {
- werror (W_VOID_FUNC, currFunc->name);
+ werrorfl (bp->ech->filename, bp->ech->lineno,
+ W_VOID_FUNC, currFunc->name);
}
}
}