* src/mcs51/ralloc.c (serialRegAssign, fillGaps, allocThisReg): try
authorepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 13 Apr 2004 04:06:32 +0000 (04:06 +0000)
committerepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 13 Apr 2004 04:06:32 +0000 (04:06 +0000)
harder to keep the same registers during a CAST iCode
* src/SDCCopt.c (optimizeCastCast, eBBlockFromiCode): casts of char to
long via int can be done in a single cast, if the signedness is
correct.
* support/regression/tests/bug-927659.c: fixed to avoid conflict with
putchar() in tinibios.c in ds390's library

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3287 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
src/SDCCopt.c
src/mcs51/ralloc.c
support/regression/tests/bug-927659.c

index d133523bb598dd921a88ba9a78dd41fed6e3124d..f63f8f799ad7df287f524a9645543986502cab04 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2004-04-13 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
+
+       * src/mcs51/ralloc.c (serialRegAssign, fillGaps, allocThisReg): try
+       harder to keep the same registers during a CAST iCode
+       * src/SDCCopt.c (optimizeCastCast, eBBlockFromiCode): casts of char to
+       long via int can be done in a single cast, if the signedness is
+       correct.
+       * support/regression/tests/bug-927659.c: fixed to avoid conflict with
+       putchar() in tinibios.c in ds390's library
+       
 2004-04-12 Bernhard Held <bernhard AT bernhardheld.de>
 
        * src/SDCCast.c (decorateType): fixed bug #898889,
index 8ae80be05507bd2c481aa4d08c117b8dbaff05db..cfb416d92d94f93501404ec6cb7c01f54276f4b8 100644 (file)
@@ -995,6 +995,76 @@ discardDeadParamReceives (eBBlock ** ebbs, int count)
     }
 }
 
+/*-----------------------------------------------------------------*/
+/* optimizeCastCast - remove unneeded intermediate casts.          */
+/* Integer promotion may cast (un)signed char to int and then      */
+/* recast the int to (un)signed long. If the signedness of the     */
+/* char and long are the same, the cast can be safely performed in */
+/* a single step.                                                  */
+/*-----------------------------------------------------------------*/
+static void 
+optimizeCastCast (eBBlock ** ebbs, int count)
+{
+  int i;
+  iCode *ic;
+  iCode *uic;
+  sym_link * type1;
+  sym_link * type2;
+  sym_link * type3;
+  symbol * sym;
+
+  for (i = 0; i < count; i++)
+    {
+      for (ic = ebbs[i]->sch; ic; ic = ic->next)
+       {
+         
+         if (ic->op == CAST && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
+           {
+             type1 = operandType (IC_RIGHT (ic));
+             type2 = operandType (IC_RESULT (ic));
+
+             /* Look only for a cast from an integer type to an */
+             /* integer type that has no loss of bits */
+             if (!IS_INTEGRAL (type1) || !IS_INTEGRAL (type2))
+               continue;
+             if (getSize (type2) < getSize (type1))
+               continue;
+             
+             /* There must be only one use of this first result */
+             if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
+               continue;
+             
+             /* This use must be a second cast */
+             uic = hTabItemWithKey (iCodehTab,
+                       bitVectFirstBit (OP_USES (IC_RESULT (ic))));
+             if (!uic || uic->op != CAST)
+               continue;
+  
+             /* It must be a cast to another integer type that */
+             /* has no loss of bits */
+             type3 = operandType (IC_RESULT (uic));
+             if (!IS_INTEGRAL (type3))
+                continue;
+             if (getSize (type3) < getSize (type2))
+                continue;
+             
+             /* The signedness between the first and last types */
+             /* must match */
+             if (SPEC_USIGN (type3) != SPEC_USIGN (type1))
+                continue;
+
+             /* Change the first cast to a simple assignment and */
+             /* let the second cast do all the work */
+             ic->op = '=';
+             IC_LEFT (ic) = NULL;
+             sym = OP_SYMBOL (IC_RESULT (ic));
+             sym->type = copyLinkChain (type1);
+             sym->etype = getSpec (sym->type);
+           }
+       }
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* eBBlockFromiCode - creates extended basic blocks from iCode     */
 /*                    will return an array of eBBlock pointers     */
@@ -1052,6 +1122,8 @@ eBBlockFromiCode (iCode * ic)
   if (options.dump_raw)
     dumpEbbsToFileExt (DUMP_RAW1, ebbs, count);
 
+  optimizeCastCast (ebbs, saveCount);
+    
   /* do common subexpression elimination for each block */
   change = cseAllBlocks (ebbs, saveCount, FALSE);
 
index c81c2158f936d2bedde3858c3a8e060df9f9ac66..d7708eae6bc2cda6bd8df3615d15d88cb8b53be6 100644 (file)
@@ -121,6 +121,23 @@ allocReg (short type)
   return NULL;
 }
 
+/*-----------------------------------------------------------------*/
+/* allocThisReg - allocates a particular register (if free)        */
+/*-----------------------------------------------------------------*/
+static regs *
+allocThisReg (regs * reg)
+{
+  if (!reg->isFree)
+    return NULL;
+
+  reg->isFree = 0;
+  if (currFunc)
+    currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
+  
+  return reg;
+}
+
+
 /*-----------------------------------------------------------------*/
 /* mcs51_regWithIdx - returns pointer to register wit index number       */
 /*-----------------------------------------------------------------*/
@@ -1162,7 +1179,6 @@ serialRegAssign (eBBlock ** ebbs, int count)
              }
            }
 #endif
-
            /* if this is an ipop that means some live
               range will have to be assigned again */
            if (ic->op == IPOP)
@@ -1267,18 +1283,32 @@ serialRegAssign (eBBlock ** ebbs, int count)
                _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key);
 
                for (j = 0; j < sym->nRegs; j++) {
+                   sym->regs[j] = NULL;
                    if (sym->regType == REG_PTR)
                        sym->regs[j] = getRegPtr (ic, ebbs[i], sym);
                    else
-                       sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
+                     { /*
+                       if (ic->op == CAST && IS_SYMOP (IC_RIGHT (ic)))
+                         {
+                           symbol * right = OP_SYMBOL (IC_RIGHT (ic));
+                           
+                           if (right->regs[j])
+                             sym->regs[j] = allocThisReg (right->regs[j]);
+                         }
+                       if (!sym->regs[j]) */
+                         sym->regs[j] = getRegGpr (ic, ebbs[i], sym);
+                     }
 
                    /* if the allocation failed which means
                       this was spilt then break */
-                   if (!sym->regs[j]) {
-                     break;
-                   }
+                   if (!sym->regs[j])
+                     {
+                       for (i=0; i < sym->nRegs ; i++ )
+                         sym->regs[i] = NULL;
+                       break;
+                     }
                }
-
+               
                if (!POINTER_SET(ic) && !POINTER_GET(ic)) {
                     /* if it shares registers with operands make sure
                       that they are in the same position */
@@ -1346,6 +1376,7 @@ static void fillGaps()
     symbol *sym =NULL;
     int key =0;
     int pass;
+    iCode *ic = NULL;
     
     if (getenv("DISABLE_FILL_GAPS")) return;
     
@@ -1370,7 +1401,7 @@ static void fillGaps()
 
                clr = hTabItemWithKey(liveRanges,i);
            assert(clr);
-        
+
            /* mark these registers as used */
            for (k = 0 ; k < clr->nRegs ; k++ ) 
                useReg(clr->regs[k]);
@@ -1382,13 +1413,36 @@ static void fillGaps()
            continue ;
        }
 
+       ic = NULL;          
+       for (i = 0 ; i < sym->defs->size ; i++ )
+          {
+           if (bitVectBitValue(sym->defs,i))
+             {
+               if (!(ic = hTabItemWithKey(iCodehTab,i)))
+                 continue;
+               if (ic->op == CAST)
+                 break;
+             }
+         }
+
         D(printf("Atemping fillGaps on %s: [",sym->name));
        /* THERE IS HOPE !!!! */
        for (i=0; i < sym->nRegs ; i++ ) {
            if (sym->regType == REG_PTR)
                sym->regs[i] = getRegPtrNoSpil ();
            else
-               sym->regs[i] = getRegGprNoSpil ();                
+             {
+               sym->regs[i] = NULL;
+               if (ic && ic->op == CAST && IS_SYMOP (IC_RIGHT (ic)))
+                 {
+                   symbol * right = OP_SYMBOL (IC_RIGHT (ic));
+                   
+                   if (right->regs[i])
+                     sym->regs[i] = allocThisReg (right->regs[i]);
+                 }
+               if (!sym->regs[i])
+                 sym->regs[i] = getRegGprNoSpil ();
+             }
             D(printf("%s ", sym->regs[i]->name));
        }
         D(printf("]\n"));
@@ -1407,7 +1461,6 @@ static void fillGaps()
             D(printf(" checking definitions\n"));
            for (i = 0 ; i < sym->defs->size ; i++ ) {
                if (bitVectBitValue(sym->defs,i)) {
-                   iCode *ic;
                    if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
                     D(printf("  ic->seq = %d\n", ic->seq));
                    if (SKIP_IC(ic)) continue;
@@ -1477,6 +1530,7 @@ static void fillGaps()
            continue ;      
        }
        D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"));
+       
        _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key);
        sym->isspilt = sym->spillA = 0 ;
        sym->usl.spillLoc->allocreq--;
index dde1e77d78716b38c0133278fb0d1d5deedd7019..dac64e04f91a37785cae7f19701a2d42da087bc6 100644 (file)
@@ -34,7 +34,7 @@ testReverse(void)
 
 /*************************************************************/
 
-#ifndef PORT_HOST
+#if !defined(PORT_HOST) && !defined(SDCC_ds390)
 void putchar (char c)
 {
   c;