fixed bug #628025
[fw/sdcc] / src / SDCCcse.c
index 435bff7507c8a0aee97c74322c076328e16512cd..4c92f75a7b9efcbeebac1c8f5626188c71c9430e 100644 (file)
@@ -102,7 +102,7 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
            {
 
              bitVectUnSetBit (OP_USES (from), lic->key);
-             OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key);
+             OP_USES_SET ((to), bitVectSetBit (OP_USES (to), lic->key));
              siaddr = IC_COND (lic)->isaddr;
              IC_COND (lic) = operandFromOperand (to);
              IC_COND (lic)->isaddr = siaddr;
@@ -118,7 +118,7 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
            {
 
              bitVectUnSetBit (OP_USES (from), lic->key);
-             OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key);
+             OP_USES_SET ((to), bitVectSetBit (OP_USES (to), lic->key));
              siaddr = IC_COND (lic)->isaddr;
              IC_JTCOND (lic) = operandFromOperand (to);
              IC_JTCOND (lic)->isaddr = siaddr;
@@ -133,7 +133,7 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
          if (POINTER_SET (lic))
            {
              bitVectUnSetBit (OP_USES (from), lic->key);
-             OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key);
+             OP_USES_SET ((to), bitVectSetBit (OP_USES (to), lic->key));
 
              /* also check if the "from" was in the non-dominating
                 pointer sets and replace it with "to" in the bitVector */
@@ -147,7 +147,7 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
          else
            {
              bitVectUnSetBit (OP_DEFS (from), lic->key);
-             OP_DEFS (to) = bitVectSetBit (OP_DEFS (to), lic->key);
+             OP_DEFS_SET ((to), bitVectSetBit (OP_DEFS (to), lic->key));
            }
          siaddr = IC_RESULT (lic)->isaddr;
          IC_RESULT (lic) = operandFromOperand (to);
@@ -158,7 +158,7 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
          IC_RIGHT (lic) && IC_RIGHT (lic)->key == from->key)
        {
          bitVectUnSetBit (OP_USES (from), lic->key);
-         OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key);
+         OP_USES_SET ((to), bitVectSetBit (OP_USES (to), lic->key));
          siaddr = IC_RIGHT (lic)->isaddr;
          IC_RIGHT (lic) = operandFromOperand (to);
          IC_RIGHT (lic)->isaddr = siaddr;
@@ -168,7 +168,7 @@ replaceAllSymBySym (iCode * ic, operand * from, operand * to, bitVect ** ndpset)
          IC_LEFT (lic) && IC_LEFT (lic)->key == from->key)
        {
          bitVectUnSetBit (OP_USES (from), lic->key);
-         OP_USES (to) = bitVectSetBit (OP_USES (to), lic->key);
+         OP_USES_SET ((to), bitVectSetBit (OP_USES (to), lic->key));
          siaddr = IC_LEFT (lic)->isaddr;
          IC_LEFT (lic) = operandFromOperand (to);
          IC_LEFT (lic)->isaddr = siaddr;
@@ -571,6 +571,20 @@ DEFSETFUNC (ifDiCodeIsX)
 
 }
 
+/*-----------------------------------------------------------------*/
+/* findBackwardDef - scan backwards to find deinition of operand   */
+/*-----------------------------------------------------------------*/
+iCode *findBackwardDef(operand *op,iCode *ic)
+{
+    iCode *lic;
+
+    for (lic = ic; lic ; lic = lic->prev) {
+       if (IC_RESULT(lic) && isOperandEqual(op,IC_RESULT(lic))) 
+           return lic;
+    }
+    return NULL;
+}
+
 /*-----------------------------------------------------------------*/
 /* algebraicOpts - does some algebraic optimizations               */
 /*-----------------------------------------------------------------*/
@@ -790,6 +804,7 @@ algebraicOpts (iCode * ic)
          IC_LEFT (ic) = NULL;
          IC_RESULT (ic) = operandFromOperand (IC_RESULT (ic));
          IC_RESULT (ic)->isaddr = 0;
+         break;
        }
       /* if this is a division then check if right */
       /* is one then change it to an assignment    */
@@ -895,6 +910,14 @@ updateSpillLocation (iCode * ic, int induction)
                                IC_RESULT (ic)->operand.symOperand;
        }
 
+#if 0 /* this needs furthur investigation can save a lot of code */
+       if (ASSIGN_SYM_TO_ITEMP(ic) &&
+           !SPIL_LOC(IC_RESULT(ic))) {
+           if (!OTHERS_PARM (OP_SYMBOL (IC_RIGHT (ic))))
+               SPIL_LOC (IC_RESULT (ic)) =
+                   IC_RIGHT (ic)->operand.symOperand;
+       }
+#endif
        if (ASSIGN_ITEMP_TO_ITEMP (ic)) {
          
                if (!SPIL_LOC (IC_RIGHT (ic)) &&
@@ -1058,7 +1081,7 @@ ifxOptimize (iCode * ic, set * cseSet,
 
 
   /* if it remains an IFX the update the use Set */
-  OP_USES (IC_COND (ic)) = bitVectSetBit (OP_USES (IC_COND (ic)), ic->key);
+  OP_USES_SET ((IC_COND (ic)), bitVectSetBit (OP_USES (IC_COND (ic)), ic->key));
   setUsesDefs (IC_COND (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
   return;
 }
@@ -1108,7 +1131,7 @@ constFold (iCode * ic, set * cseSet)
   /* this check is a hueristic to prevent live ranges
      from becoming too long */
   if (IS_PTR (operandType (IC_RESULT (ic))))
-    return 0;
+      return 0;
 
   /* check if operation with a literal */
   if (!IS_OP_LITERAL (IC_RIGHT (ic)))
@@ -1376,8 +1399,8 @@ cseBBlock (eBBlock * ebb, int computeOnly,
       if (ic->op == PCALL || ic->op == CALL || ic->op == RECEIVE)
        {
          /* add to defSet of the symbol */
-         OP_DEFS (IC_RESULT (ic)) =
-           bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
+         OP_DEFS_SET ((IC_RESULT (ic)),
+           bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key));
          /* add to the definition set of this block */
          ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
          ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);
@@ -1415,8 +1438,8 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          /* the lookup could have changed it */
          if (IS_SYMOP (IC_LEFT (ic)))
            {
-             OP_USES (IC_LEFT (ic)) =
-               bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+             OP_USES_SET ((IC_LEFT (ic)),
+               bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key));
              setUsesDefs (IC_LEFT (ic), ebb->defSet,
                           ebb->outDefs, &ebb->usesDefs);
            }
@@ -1440,8 +1463,8 @@ cseBBlock (eBBlock * ebb, int computeOnly,
       /* if jumptable then mark the usage */
       if (ic->op == JUMPTABLE)
        {
-         OP_USES (IC_JTCOND (ic)) =
-           bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key);
+         OP_USES_SET ((IC_JTCOND (ic)),
+           bitVectSetBit (OP_USES (IC_JTCOND (ic)), ic->key));
          setUsesDefs (IC_JTCOND (ic), ebb->defSet,
                       ebb->outDefs, &ebb->usesDefs);
          continue;
@@ -1516,6 +1539,10 @@ cseBBlock (eBBlock * ebb, int computeOnly,
                {
                  if (IS_ITEMP (pdop) || IS_OP_LITERAL (pdop))
                    {
+                       /* some non dominating block does POINTER_SET with
+                          this variable .. unsafe to remove any POINTER_GETs */
+                       if (bitVectBitValue(ebb->ndompset,IC_LEFT(ic)->key))
+                           ebb->ptrsSet = bitVectSetBit(ebb->ptrsSet,pdop->key);
                      IC_LEFT (ic) = pdop;
                      change = 1;
                    }
@@ -1563,7 +1590,7 @@ cseBBlock (eBBlock * ebb, int computeOnly,
 
       /* if after all this it becomes a assignment to self
          then delete it and continue */
-      if (ASSIGNMENT_TO_SELF (ic))
+      if (ASSIGNMENT_TO_SELF (ic) && !OTHERS_PARM(OP_SYMBOL(IC_RESULT(ic))))
        {
          remiCodeFromeBBlock (ebb, ic);
          continue;
@@ -1594,12 +1621,18 @@ cseBBlock (eBBlock * ebb, int computeOnly,
 
       /* Alternate code */
       if (pdic && IS_ITEMP(IC_RESULT(ic))) {
+       if (POINTER_GET(ic) && bitVectBitValue(ebb->ptrsSet,IC_LEFT(ic)->key)) {
+         /* Mmm, found an equivalent pointer get at a lower level. 
+            This could be a loop however with the same pointer set 
+            later on */
+       } else {
          /* if previous definition found change this to an assignment */
          ic->op = '=';
          IC_LEFT(ic) = NULL;
          IC_RIGHT(ic) = operandFromOperand(IC_RESULT(pdic));
          SET_ISADDR(IC_RESULT(ic),0);
          SET_ISADDR(IC_RIGHT (ic),0);    
+       }
       }
 
       if (!(POINTER_SET (ic)) && IC_RESULT (ic)) {
@@ -1651,16 +1684,16 @@ cseBBlock (eBBlock * ebb, int computeOnly,
       /* add the left & right to the defUse set */
       if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)))
        {
-         OP_USES (IC_LEFT (ic)) =
-           bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+         OP_USES_SET ((IC_LEFT (ic)),
+           bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key));
          setUsesDefs (IC_LEFT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
 
        }
 
       if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)))
        {
-         OP_USES (IC_RIGHT (ic)) =
-           bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+         OP_USES_SET ((IC_RIGHT (ic)),
+           bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key));
          setUsesDefs (IC_RIGHT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
 
        }
@@ -1669,8 +1702,8 @@ cseBBlock (eBBlock * ebb, int computeOnly,
       /* in the defuseSet if it a pointer or array access  */
       if (POINTER_SET (defic))
        {
-         OP_USES (IC_RESULT (ic)) =
-           bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key);
+         OP_USES_SET ((IC_RESULT (ic)),
+           bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key));
          setUsesDefs (IC_RESULT (ic), ebb->defSet, ebb->outDefs, &ebb->usesDefs);
          deleteItemIf (&cseSet, ifPointerGet, IC_RESULT (ic));
          ebb->ptrsSet = bitVectSetBit (ebb->ptrsSet, IC_RESULT (ic)->key);
@@ -1688,8 +1721,8 @@ cseBBlock (eBBlock * ebb, int computeOnly,
       else
        /* add the result to defintion set */ if (IC_RESULT (ic))
        {
-         OP_DEFS (IC_RESULT (ic)) =
-           bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
+         OP_DEFS_SET ((IC_RESULT (ic)),
+           bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key));
          ebb->defSet = bitVectSetBit (ebb->defSet, ic->key);
          ebb->outDefs = bitVectCplAnd (ebb->outDefs, OP_DEFS (IC_RESULT (ic)));
          ebb->ldefs = bitVectSetBit (ebb->ldefs, ic->key);