Added heap support functions
[fw/sdcc] / src / SDCCcse.c
index f3c27a55d521356f4bfe78a6a8c21be52135a95c..18ca4ea6e50376b63322d57ae775607cb9ae08cf 100644 (file)
@@ -301,8 +301,9 @@ DEFSETFUNC (findCheaperOp)
     *opp = IC_RESULT (cdp->diCode);
 
   if ((*opp) && 
-      (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp))) &&
-      (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp))))
+      (isOperandLiteral(*opp) ||
+       (SPEC_USIGN(operandType (cop))==SPEC_USIGN(operandType (*opp)) &&
+       (SPEC_LONG(operandType (cop))==SPEC_LONG(operandType (*opp))))))
     {
 
       if ((isGlobalInNearSpace (cop) &&
@@ -393,6 +394,20 @@ DEFSETFUNC (findPrevIc)
   return 0;
 }
 
+/*-------------------------------------------------------------------*/
+/* ifAssignedFromGlobal - if definition is an assignment from global */
+/*-------------------------------------------------------------------*/
+DEFSETFUNC (ifAssignedFromGlobal)
+{
+  cseDef *cdp = item;
+  iCode *dic=cdp->diCode;
+
+  if (dic->op=='=' && isOperandGlobal(IC_RIGHT(dic))) {
+    return 1;
+  }
+  return 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* ifDefGlobal - if definition is global                           */
 /*-----------------------------------------------------------------*/
@@ -1316,6 +1331,10 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          /* delete global variables from the cseSet
             since they can be modified by the function call */
          deleteItemIf (&cseSet, ifDefGlobal);
+
+         /* and also itemps assigned from globals */
+         deleteItemIf (&cseSet, ifAssignedFromGlobal);
+
          /* delete all getpointer iCodes from cseSet, this should
             be done only for global arrays & pointers but at this
             point we don't know if globals, so to be safe do all */
@@ -1473,7 +1492,6 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          applyToSetFTrue (cseSet, findCheaperOp, IC_RIGHT (ic), &pdop);
          if (pdop)
            {
-
              IC_RIGHT (ic) = pdop;
              change = 1;
            }
@@ -1513,15 +1531,9 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          if (pdic && compareType (operandType (IC_RESULT (pdic)),
                                 operandType (IC_RESULT (ic))) != 1)
            pdic = NULL;
-
-         // TODO: this must go, a weak fix for bug #467035
-         if (pdic && (pdic->level > ic->level)) {
-           // pdic was inside an inner loop
-           pdic = NULL;
-         }
-         
        }
 
+#if 0
       /* if found then eliminate this and add to */
       /* to cseSet an element containing result */
       /* of this with previous opcode           */
@@ -1578,7 +1590,23 @@ cseBBlock (eBBlock * ebb, int computeOnly,
          defic = ic;
 
        }
+#else
+      /* Alternate code */
+      if (pdic && IS_ITEMP(IC_RESULT(ic))) {
+         /* 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)) {
+         deleteItemIf (&cseSet, ifDefSymIsX, IC_RESULT (ic));
+         addSetHead (&cseSet, newCseDef (IC_RESULT (ic), ic));
+      }
+      defic = ic;
+#endif
       /* if assignment to a parameter which is not
          mine and type is a pointer then delete
          pointerGets to take care of aliasing */