* src/SDCCicode.h,
authorepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 23 Apr 2004 05:42:03 +0000 (05:42 +0000)
committerepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 23 Apr 2004 05:42:03 +0000 (05:42 +0000)
* 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

ChangeLog
src/SDCCicode.c
src/SDCCicode.h
src/SDCCptropt.c
src/SDCCptropt.h
src/ds390/ralloc.c
src/hc08/ralloc.c
src/mcs51/ralloc.c
src/pic/ralloc.c
src/pic16/ralloc.c

index 85309869955619a5675570ebc27c2a80af109dab..7c121627df1bbeac223484e98b03e51ae5feadab 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+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),
index 7e3321fce9c01432d6ff0f31eb91a4c99a112cbd..d75e0e9be143b05b58a47246309b6036a20487f1 100644 (file)
@@ -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                            */
 /*-----------------------------------------------------------------*/
index 1822f79ff548c01c5ae1a28ce6e32fe86d094b88..3dc90c7a480bdc409b3316527f0af475b1546272 100644 (file)
@@ -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 *);
index 3660bb7f1631b88a4edf09fa6a3a35ee36f0425f..85d94709139b748bcd689215eaebcad37d6387c2 100644 (file)
@@ -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
+}
index 9314a8a6fd3738f69ed1de2cb18dfd069cba38ae..8659ae6a1d27221c975ca5a8f7f8eadf74e925c0 100644 (file)
@@ -28,5 +28,8 @@
 
 void ptrPostIncDecOpt (iCode *);
 int ptrAddition (iCode *);
+symbol * ptrBaseRematSym (symbol *);
+int ptrPseudoSymSafe (symbol *, iCode *);
+void ptrPseudoSymConvert (symbol *, iCode *, char *);
 
 #endif
index 3743e964dcf776f0369cdb7aa3971d007aa844e4..afede94d6af3cf9bbbc42b332d629b188844ea3c 100644 (file)
@@ -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;
                }
 
index ee599f19353b95df7c0a021a1dfa297b7062ab6e..e3269f72e8710c3d13b49a123c74a4b0e60e5da2 100644 (file)
@@ -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;
                }
 
index 919ded657f5f71c9b9056e01a9d1997372d01b91..8d7f6556abbf2b2751692400d97f1a6c67851840 100644 (file)
@@ -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;
                }
 
index 7266470d807428f67e2970f7407a1c7e76b6dd71..25c3036959085bdb26ba599793c41aa4e873da9a 100644 (file)
@@ -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;
index 6b8550fb0ab33bcea76866dbeb9a7ebb9413c409..c589bb41b4e50c32a68909b5f4ab559cde865fcc 100644 (file)
@@ -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;