+2004-04-23 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
+
+ * src/SDCCicode.h,
+ * src/SDCCicode.c (aggrToPtrDclType),
+ * src/SDCCptropt.h,
+ * src/SDCCptropt.c (ptrBaseRematSym, ptrPseudoSymSafe,
+ ptrPseudoSymConvert),
+ * src/pic/ralloc.c (regTypeNum),
+ * src/pic16/ralloc.c (regTypeNum),
+ * src/hc08/ralloc.c (regTypeNum),
+ * src/ds390/ralloc.c (regTypeNum),
+ * src/mcs51/ralloc.c (regTypeNum): check for dependancy hazards before
+ creating pseudo symbols (fixed bugs #777768 and #933966)
+
2004-04-22 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
* link/z80/lkmain.c (afile),
return ptype;
}
+/*------------------------------------------------------------------*/
+/* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
+/*------------------------------------------------------------------*/
+int
+aggrToPtrDclType (sym_link * type, bool force)
+{
+ if (IS_PTR (type) && !force)
+ return DCL_TYPE (type);
+
+ /* return the pointer depending on the storage class */
+ return PTR_TYPE (SPEC_OCLS (getSpec (type)));
+}
+
/*-----------------------------------------------------------------*/
/* geniCodeArray2Ptr - array to pointer */
/*-----------------------------------------------------------------*/
operand *operandFromSymbol (symbol *);
operand *operandFromLink (sym_link *);
sym_link *aggrToPtr (sym_link *, bool);
+int aggrToPtrDclType (sym_link *, bool);
int piCode (void *, FILE *);
int printOperand (operand *, FILE *);
void setOperandType (operand *, sym_link *);
if (addPattern1(sic)) return 1;
return 0;
}
+
+/*--------------------------------------------------------------------*/
+/* ptrBaseRematSym - find the base symbol of a remat. pointer */
+/*--------------------------------------------------------------------*/
+symbol *
+ptrBaseRematSym (symbol *ptrsym)
+{
+ iCode * ric;
+
+ if (!ptrsym->remat)
+ return NULL;
+
+ ric = ptrsym->rematiCode;
+ while (ric)
+ {
+ if (ric->op == '+' || ric->op == '-')
+ ric = OP_SYMBOL (IC_LEFT (ric))->rematiCode;
+ else if (IS_CAST_ICODE (ric))
+ ric = OP_SYMBOL (IC_RIGHT (ric))->rematiCode;
+ else
+ break;
+ }
+
+ if (ric && IS_SYMOP (IC_LEFT (ric)))
+ return OP_SYMBOL (IC_LEFT (ric));
+ else
+ return NULL;
+}
+
+
+/*--------------------------------------------------------------------*/
+/* ptrPseudoSymSafe - check to see if the convertion of the result of */
+/* a pointerGet of a rematerializable pointer to a pseudo symbol is */
+/* safe. Returns true if safe, or false if hazards were detected. */
+/*--------------------------------------------------------------------*/
+int
+ptrPseudoSymSafe (symbol *sym, iCode *dic)
+{
+ symbol * ptrsym;
+ symbol * basesym;
+ iCode * ric;
+ iCode * ic;
+ int ptrsymDclType;
+ //int isGlobal;
+
+ assert(POINTER_GET (dic));
+
+ /* Can't if spills to this symbol are prohibited */
+ if (sym->noSpilLoc)
+ return 0;
+
+ /* Get the pointer */
+ if (!IS_SYMOP (IC_LEFT (dic)))
+ return 0;
+ ptrsym = OP_SYMBOL (IC_LEFT (dic));
+
+ /* Must be a rematerializable pointer */
+ if (!ptrsym->remat)
+ return 0;
+
+ /* The pointer type must be uncasted */
+ if (IS_CAST_ICODE (ptrsym->rematiCode))
+ return 0;
+
+ /* The symbol's live range must not preceed its definition */
+ if (dic->seq > sym->liveFrom)
+ return 0;
+
+ /* Ok, this is a good candidate for a pseudo symbol. */
+ /* However, we must check for two hazards: */
+ /* 1) The symbol's live range must not include a CALL */
+ /* or PCALL iCode. */
+ /* 2) The symbol's live range must not include any */
+ /* writes to the variable the pointer rematerializes */
+ /* within (to avoid aliasing problems) */
+
+ /* Find the base symbol the rematerialization is based on */
+ ric = ptrsym->rematiCode;
+ while (ric->op == '+' || ric->op == '-')
+ ric = OP_SYMBOL (IC_LEFT (ric))->rematiCode;
+ if (IS_CAST_ICODE(ric))
+ return 0;
+ basesym = OP_SYMBOL (IC_LEFT (ric));
+
+ //isGlobal = !basesym->islocal && !basesym->ismyparm;
+ ptrsymDclType = aggrToPtrDclType (ptrsym->type, FALSE);
+
+ ic = dic->next;
+ while (ic && ic->seq <= sym->liveTo)
+ {
+ if (!(SKIP_IC3 (ic) || ic->op == IFX))
+ {
+ /* Check for hazard #1 */
+ if ((ic->op == CALL || ic->op == PCALL) /* && isGlobal */ )
+ {
+ if (ic->seq <= sym->liveTo)
+ return 0;
+ }
+ /* Check for hazard #2 */
+ else if (POINTER_SET (ic))
+ {
+ symbol * ptrsym2 = OP_SYMBOL (IC_RESULT (ic));
+
+ if (ptrsym2->remat)
+ {
+ /* Must not be the same base symbol */
+ if (basesym == ptrBaseRematSym (ptrsym2))
+ return 0;
+ }
+ else
+ {
+ int ptrsym2DclType = aggrToPtrDclType (ptrsym2->type, FALSE);
+
+ /* Pointer must have no memory space in common */
+ if (ptrsym2DclType == ptrsymDclType
+ || ptrsym2DclType == GPOINTER
+ || ptrsymDclType == GPOINTER)
+ return 0;
+ }
+ }
+ else if (IC_RESULT (ic))
+ {
+ symbol * rsym = OP_SYMBOL (IC_RESULT (ic));
+
+ /* Make sure there is no conflict with another pseudo symbol */
+ if (rsym->psbase == basesym)
+ return 0;
+ if (rsym->isspilt && rsym->usl.spillLoc)
+ rsym = rsym->usl.spillLoc;
+ if (rsym->psbase == basesym)
+ return 0;
+ }
+ }
+
+ if (ic->seq == sym->liveTo)
+ break;
+ ic = ic->next;
+ }
+
+ /* If the live range went past the end of the defining basic */
+ /* block, then a full analysis is too complicated to attempt */
+ /* here. To be safe, we must assume the worst. */
+ if (!ic)
+ return 0;
+
+ /* Ok, looks safe */
+ return 1;
+}
+
+/*--------------------------------------------------------------------*/
+/* ptrPseudoSymConvert - convert the result of a pointerGet to a */
+/* pseudo symbol. The pointer must be rematerializable. */
+/*--------------------------------------------------------------------*/
+void
+ptrPseudoSymConvert (symbol *sym, iCode *dic, char *name)
+{
+ symbol *psym = newSymbol (name, 1);
+ psym->type = sym->type;
+ psym->etype = sym->etype;
+ psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (dic)));
+
+ strcpy (psym->rname, psym->name);
+ sym->isspilt = 1;
+ sym->usl.spillLoc = psym;
+#if 0 // an alternative fix for bug #480076
+ /* now this is a useless assignment to itself */
+ remiCodeFromeBBlock (ebbs, dic);
+#else
+ /* now this really is an assignment to itself, make it so;
+ it will be optimized out later */
+ dic->op='=';
+ ReplaceOpWithCheaperOp(&IC_RIGHT(dic), IC_RESULT(dic));
+ IC_LEFT(dic)=NULL;
+#endif
+}
void ptrPostIncDecOpt (iCode *);
int ptrAddition (iCode *);
+symbol * ptrBaseRematSym (symbol *);
+int ptrPseudoSymSafe (symbol *, iCode *);
+void ptrPseudoSymConvert (symbol *, iCode *, char *);
#endif
(ic = hTabItemWithKey (iCodehTab,
bitVectFirstBit (sym->defs))) &&
POINTER_GET (ic) &&
- !sym->noSpilLoc &&
- !IS_BITVAR (sym->etype))
+ !IS_BITVAR (sym->etype) &&
+ (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER))
{
- /* and that pointer is remat in data space */
- if (IS_SYMOP (IC_LEFT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->remat &&
- !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
- DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
- {
- /* create a psuedo symbol & force a spil */
- symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
- psym->type = sym->type;
- psym->etype = sym->etype;
- strncpyz (psym->rname, psym->name, sizeof(psym->rname));
- sym->isspilt = 1;
- sym->usl.spillLoc = psym;
+ if (ptrPseudoSymSafe (sym, ic))
+ {
+ ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
continue;
}
(ic = hTabItemWithKey (iCodehTab,
bitVectFirstBit (sym->defs))) &&
POINTER_GET (ic) &&
- !sym->noSpilLoc &&
!IS_BITVAR (sym->etype))
{
- /* and that pointer is remat in data space */
- if (IS_SYMOP (IC_LEFT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->remat &&
- !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
- DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
+ if (ptrPseudoSymSafe (sym, ic))
{
- /* create a psuedo symbol & force a spil */
- symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
- psym->type = sym->type;
- psym->etype = sym->etype;
- strcpy (psym->rname, psym->name);
- sym->isspilt = 1;
- sym->usl.spillLoc = psym;
-#if 0 // an alternative fix for bug #480076
- /* now this is a useless assignment to itself */
- remiCodeFromeBBlock (ebbs, ic);
-#else
- /* now this really is an assignment to itself, make it so;
- it will be optimized out later */
- ic->op='=';
- ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic));
- IC_LEFT(ic)=NULL;
-#endif
+ ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
continue;
}
(ic = hTabItemWithKey (iCodehTab,
bitVectFirstBit (sym->defs))) &&
POINTER_GET (ic) &&
- !sym->noSpilLoc &&
- !IS_BITVAR (sym->etype))
+ !IS_BITVAR (sym->etype) &&
+ (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER))
{
-
- /* and that pointer is remat in data space */
- if (IS_SYMOP (IC_LEFT (ic)) &&
- OP_SYMBOL (IC_LEFT (ic))->remat &&
- !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) &&
- DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER)
+ if (ptrPseudoSymSafe (sym, ic))
{
- /* create a psuedo symbol & force a spil */
- symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
- psym->type = sym->type;
- psym->etype = sym->etype;
-
- strcpy (psym->rname, psym->name);
- sym->isspilt = 1;
- sym->usl.spillLoc = psym;
-#if 0 // an alternative fix for bug #480076
- /* now this is a useless assignment to itself */
- remiCodeFromeBBlock (ebbs, ic);
-#else
- /* now this really is an assignment to itself, make it so;
- it will be optimized out later */
- ic->op='=';
- ReplaceOpWithCheaperOp(&IC_RIGHT(ic), IC_RESULT(ic));
- IC_LEFT(ic)=NULL;
-#endif
+ ptrPseudoSymConvert (sym, ic, rematStr (OP_SYMBOL (IC_LEFT (ic))));
continue;
}
in "data" space */
if (bitVectnBitsOn (sym->defs) == 1 &&
- (ic = hTabItemWithKey (iCodehTab,
- bitVectFirstBit (sym->defs))) &&
- POINTER_GET (ic) &&
- !sym->noSpilLoc &&
- !IS_BITVAR (sym->etype)) {
-
-
- debugLog (" %d - \n", __LINE__);
+ (ic = hTabItemWithKey (iCodehTab,
+ bitVectFirstBit (sym->defs))) &&
+ POINTER_GET (ic) &&
+ !IS_BITVAR (sym->etype) &&
+ (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
+
+ if (ptrPseudoSymSafe (sym, ic)) {
+
+ debugLog (" %d - \n", __LINE__);
- /* if remat in data space */
- if (OP_SYMBOL (IC_LEFT (ic))->remat &&
- DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
-
/* create a psuedo symbol & force a spil */
//X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
psym->type = sym->type;
psym->etype = sym->etype;
+ psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
strcpy (psym->rname, psym->name);
sym->isspilt = 1;
sym->usl.spillLoc = psym;
(ic = hTabItemWithKey (iCodehTab,
bitVectFirstBit (sym->defs))) &&
POINTER_GET (ic) &&
- !sym->noSpilLoc &&
- !IS_BITVAR (sym->etype)) {
-
-
- debugLog (" %d - \n", __LINE__);
-
- /* if remat in data space */
- if (OP_SYMBOL (IC_LEFT (ic))->remat &&
- DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) {
+ !IS_BITVAR (sym->etype) &&
+ (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) {
+ if (ptrPseudoSymSafe (sym, ic)) {
+
+ debugLog (" %d - \n", __LINE__);
+
/* create a psuedo symbol & force a spil */
//X symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1);
symbol *psym = rematStr (OP_SYMBOL (IC_LEFT (ic)));
psym->type = sym->type;
psym->etype = sym->etype;
+ psym->psbase = ptrBaseRematSym (OP_SYMBOL (IC_LEFT (ic)));
strcpy (psym->rname, psym->name);
sym->isspilt = 1;
sym->usl.spillLoc = psym;