* doc/Makefile: fix install
[fw/sdcc] / src / SDCCopt.c
index 8c12927ab03570b3a5b2104061963ce24d3751dd..a4c7de2261b6a42e56537c9821350e8ce2ef8f14 100644 (file)
@@ -572,6 +572,9 @@ isLocalWithoutDef (symbol * sym)
   if (IS_AGGREGATE (sym->type))
     return 0;
   
+  if (sym->addrtaken)
+    return 0;
+  
   return !sym->defs;
 }
 
@@ -606,9 +609,9 @@ replaceRegEqv (eBBlock ** ebbs, int count)
                  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;
                }
@@ -629,9 +632,9 @@ replaceRegEqv (eBBlock ** ebbs, int count)
                  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;
                }
@@ -672,9 +675,9 @@ replaceRegEqv (eBBlock ** ebbs, int count)
              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;
            }
@@ -693,9 +696,9 @@ replaceRegEqv (eBBlock ** ebbs, int count)
              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;
            }
@@ -760,6 +763,10 @@ killDeadCode (eBBlock ** ebbs, int count)
                   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;
@@ -812,11 +819,26 @@ killDeadCode (eBBlock ** ebbs, int count)
              /* 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);
+
+                 
+                 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);
@@ -824,12 +846,33 @@ killDeadCode (eBBlock ** ebbs, int count)
                  /* 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 */
@@ -926,6 +969,12 @@ eBBlockFromiCode (iCode * ic)
   ebbs = iCodeBreakDown (ic, &count);
   saveCount = count;
 
+  /* hash the iCode keys so that we can quickly index */
+  /* them in the rest of the optimization steps */
+  setToNull ((void *) &iCodehTab);
+  iCodehTab = newHashTable (iCodeKey);
+  hashiCodeKeys (ebbs, count);
+  
   /* compute the control flow */
   computeControlFlow (ebbs, count, 0);
 
@@ -1023,7 +1072,8 @@ eBBlockFromiCode (iCode * ic)
             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);
          }
        }
       }