IC_RESULT (newic) = IC_RESULT (ic);
newic->lineno = lineno;
newic->parmBytes+=bytesPushed;
+
+ if(TARGET_IS_PIC16) {
+ /* normally these functions aren't marked external, so we can use their
+ * _extern field to marked as already added to symbol table */
+
+ if(!SPEC_EXTR(func->etype)) {
+ memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+ SPEC_EXTR(func->etype) = 1;
+ seg = SPEC_OCLS( func->etype );
+ addSet(&seg->syms, func);
+ }
+ }
+
addiCodeToeBBlock (ebp, newic, ip);
}
newic = newiCode (CALL, operandFromSymbol (func), NULL);
IC_RESULT (newic) = IC_RESULT (ic);
newic->parmBytes+=bytesPushed;
+
+ if(TARGET_IS_PIC16) {
+ /* normally these functions aren't marked external, so we can use their
+ * _extern field to marked as already added to symbol table */
+
+ if(!SPEC_EXTR(func->etype)) {
+ memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+ SPEC_EXTR(func->etype) = 1;
+ seg = SPEC_OCLS( func->etype );
+ addSet(&seg->syms, func);
+ }
+ }
+
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = linenno;
-
}
/*-----------------------------------------------------------------*/
newic = newiCode (CALL, operandFromSymbol (func), NULL);
IC_RESULT (newic) = IC_RESULT (ic);
newic->parmBytes+=bytesPushed;
+
+ if(TARGET_IS_PIC16) {
+ /* normally these functions aren't marked external, so we can use their
+ * _extern field to marked as already added to symbol table */
+
+ if(!SPEC_EXTR(func->etype)) {
+ memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+ SPEC_EXTR(func->etype) = 1;
+ seg = SPEC_OCLS( func->etype );
+ addSet(&seg->syms, func);
+ }
+ }
+
addiCodeToeBBlock (ebp, newic, ip);
newic->lineno = lineno;
-
}
extern operand *geniCodeRValue (operand *, bool);
IC_RESULT (newic) = IC_RESULT (ic);
newic->lineno = lineno;
newic->parmBytes+=bytesPushed; // to clear the stack after the call
+
+ if(TARGET_IS_PIC16) {
+ /* normally these functions aren't marked external, so we can use their
+ * _extern field to marked as already added to symbol table */
+
+ if(!SPEC_EXTR(func->etype)) {
+ memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
+
+ SPEC_EXTR(func->etype) = 1;
+ seg = SPEC_OCLS( func->etype );
+ addSet(&seg->syms, func);
+ }
+ }
+
addiCodeToeBBlock (ebp, newic, ip);
}
if (IS_AGGREGATE (sym->type))
return 0;
+ if (sym->addrtaken)
+ return 0;
+
return !sym->defs;
}
IS_TRUE_SYMOP (IC_COND (ic)) &&
isLocalWithoutDef (OP_SYMBOL (IC_COND (ic))))
{
- werror (W_LOCAL_NOINIT,
- OP_SYMBOL (IC_COND (ic))->name,
- ic->filename, ic->lineno);
+ 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;
}
IS_TRUE_SYMOP (IC_JTCOND (ic)) &&
isLocalWithoutDef (OP_SYMBOL (IC_JTCOND (ic))))
{
- werror (W_LOCAL_NOINIT,
- OP_SYMBOL (IC_JTCOND (ic))->name,
- ic->filename, ic->lineno);
+ 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;
}
IS_TRUE_SYMOP (IC_RIGHT (ic)) &&
isLocalWithoutDef (OP_SYMBOL (IC_RIGHT (ic))))
{
- werror (W_LOCAL_NOINIT,
- OP_SYMBOL (IC_RIGHT (ic))->name,
- ic->filename, ic->lineno);
+ 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;
}
IS_TRUE_SYMOP (IC_LEFT (ic)) &&
isLocalWithoutDef (OP_SYMBOL (IC_LEFT (ic))))
{
- werror (W_LOCAL_NOINIT,
- OP_SYMBOL (IC_LEFT (ic))->name,
- ic->filename, ic->lineno);
+ 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;
}
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);
+
+ /* a dead address-of operation should die, even if volatile */
+ if (ic->op == ADDRESS_OF)
+ volLeft = 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);
- if (IS_SYMOP (IC_RIGHT (ic)))
- bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+ /* 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);
+ }
}
} /* end of all instructions */
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);
}
}
}