From: epetrich Date: Fri, 23 Apr 2004 05:42:03 +0000 (+0000) Subject: * src/SDCCicode.h, X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=8d152321714246e8d25b7c02b803eb2e49350c7f;p=fw%2Fsdcc * 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) git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3297 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 85309869..7c121627 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2004-04-23 Erik Petrich + + * 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 * link/z80/lkmain.c (afile), diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 7e3321fc..d75e0e9b 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -2322,6 +2322,19 @@ aggrToPtr (sym_link * type, bool force) 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 */ /*-----------------------------------------------------------------*/ diff --git a/src/SDCCicode.h b/src/SDCCicode.h index 1822f79f..3dc90c7a 100644 --- a/src/SDCCicode.h +++ b/src/SDCCicode.h @@ -313,6 +313,7 @@ operand *operandFromValue (value *); 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 *); diff --git a/src/SDCCptropt.c b/src/SDCCptropt.c index 3660bb7f..85d94709 100644 --- a/src/SDCCptropt.c +++ b/src/SDCCptropt.c @@ -218,3 +218,178 @@ int ptrAddition (iCode *sic) 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 +} diff --git a/src/SDCCptropt.h b/src/SDCCptropt.h index 9314a8a6..8659ae6a 100644 --- a/src/SDCCptropt.h +++ b/src/SDCCptropt.h @@ -28,5 +28,8 @@ void ptrPostIncDecOpt (iCode *); int ptrAddition (iCode *); +symbol * ptrBaseRematSym (symbol *); +int ptrPseudoSymSafe (symbol *, iCode *); +void ptrPseudoSymConvert (symbol *, iCode *, char *); #endif diff --git a/src/ds390/ralloc.c b/src/ds390/ralloc.c index 3743e964..afede94d 100644 --- a/src/ds390/ralloc.c +++ b/src/ds390/ralloc.c @@ -1853,23 +1853,13 @@ regTypeNum () (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; } diff --git a/src/hc08/ralloc.c b/src/hc08/ralloc.c index ee599f19..e3269f72 100644 --- a/src/hc08/ralloc.c +++ b/src/hc08/ralloc.c @@ -1739,34 +1739,13 @@ regTypeNum (eBBlock *ebbs) (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; } diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 919ded65..8d7f6556 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -1762,35 +1762,13 @@ regTypeNum (eBBlock *ebbs) (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; } diff --git a/src/pic/ralloc.c b/src/pic/ralloc.c index 7266470d..25c30369 100644 --- a/src/pic/ralloc.c +++ b/src/pic/ralloc.c @@ -2726,24 +2726,22 @@ regTypeNum () 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; diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index 6b8550fb..c589bb41 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -2577,21 +2577,19 @@ regTypeNum () (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;