* as/xa51/xa_version.h,
[fw/sdcc] / src / SDCCloop.c
index d04b717c2c759dafc3514958d14c7f74312360a0..556f452ea2289a1625b7586a9536cab55ab2be64 100644 (file)
@@ -46,7 +46,7 @@ newInduction (operand * sym, unsigned int op,
   ip->op = op;
   ip->cval = constVal;
   ip->ic = ic;
-  updateSpillLocation(ic,1);
+//updateSpillLocation(ic,1);
   return ip;
 }
 
@@ -148,7 +148,7 @@ intersectLoopSucc (set * lexits, eBBlock ** ebbs)
 /*-----------------------------------------------------------------*/
 /* loopInsert will insert a block into the loop set                */
 /*-----------------------------------------------------------------*/
-static void 
+static void
 loopInsert (set ** regionSet, eBBlock * block)
 {
   if (!isinSet (*regionSet, block))
@@ -188,7 +188,7 @@ DEFSETFUNC (isNotInBlocks)
 /* hasIncomingDefs - has definitions coming into the loop. i.e.    */
 /* check to see if the preheaders outDefs has any definitions      */
 /*-----------------------------------------------------------------*/
-int 
+int
 hasIncomingDefs (region * lreg, operand * op)
 {
   eBBlock *preHdr = lreg->entry->preHeader;
@@ -202,7 +202,7 @@ hasIncomingDefs (region * lreg, operand * op)
 /* findLoopEndSeq - will return the sequence number of the last    */
 /* iCode with the maximum dfNumber in the region                   */
 /*-----------------------------------------------------------------*/
-int 
+int
 findLoopEndSeq (region * lreg)
 {
   eBBlock *block;
@@ -235,7 +235,6 @@ DEFSETFUNC (addToExitsMarkDepth)
   if (ebp->depth<depth)
     ebp->depth = depth;
 
-  /* put the loop region info in the block */
   /* NOTE: here we will update only the inner most loop
      that it is a part of */
   if (!ebp->partOfLoop)
@@ -314,7 +313,7 @@ DEFSETFUNC (addDefInExprs)
 /*-----------------------------------------------------------------*/
 /* assignmentsToSym - for a set of blocks determine # time assigned */
 /*-----------------------------------------------------------------*/
-int 
+int
 assignmentsToSym (set * sset, operand * sym)
 {
   eBBlock *ebp;
@@ -329,7 +328,7 @@ assignmentsToSym (set * sset, operand * sym)
          in this block */
       bitVect *defs = bitVectIntersect (ebp->ldefs, OP_DEFS (sym));
       assigns += bitVectnBitsOn (defs);
-      setToNull ((void **) &defs);
+      setToNull ((void *) &defs);
 
     }
 
@@ -340,7 +339,7 @@ assignmentsToSym (set * sset, operand * sym)
 /*-----------------------------------------------------------------*/
 /* isOperandInvariant - determines if an operand is an invariant   */
 /*-----------------------------------------------------------------*/
-int 
+int
 isOperandInvariant (operand * op, region * theLoop, set * lInvars)
 {
   int opin = 0;
@@ -380,7 +379,22 @@ DEFSETFUNC (pointerAssigned)
   eBBlock *ebp = item;
   V_ARG (operand *, op);
 
-  return ebp->hasFcall || bitVectBitValue (ebp->ptrsSet, op->key);
+  if (ebp->hasFcall)
+    return 1;
+
+  if (bitVectBitValue (ebp->ptrsSet, op->key))
+    return 1;
+
+  /* Unfortunately, one of the other pointer set operations  */
+  /* may be using an alias of this operand, and the above    */
+  /* test would miss it. To be thorough, some aliasing       */
+  /* analysis should be done here. In the meantime, be       */
+  /* conservative and assume any other pointer set operation */
+  /* is dangerous                                            */
+  if (!bitVectIsZero (ebp->ptrsSet))
+    return 1;
+
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
@@ -402,7 +416,7 @@ DEFSETFUNC (hasNonPtrUse)
 /*-----------------------------------------------------------------*/
 /* loopInvariants - takes loop invariants out of region            */
 /*-----------------------------------------------------------------*/
-int 
+int
 loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
 {
   eBBlock *lBlock;
@@ -417,8 +431,8 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
       theLoop->exits == NULL)
     return 0;
 
-  /* we will do the elimination for those blocks        */
-  /* in the loop that dominates all exits from the loop */
+  /* we will do the elimination for those blocks       */
+  /* in the loop that dominate all exits from the loop */
   for (lBlock = setFirstItem (theLoop->regBlocks); lBlock;
        lBlock = setNextItem (theLoop->regBlocks))
     {
@@ -466,6 +480,13 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
          if (SKIP_IC (ic) || POINTER_SET (ic) || ic->op == IFX)
            continue;
 
+         /* iTemp assignment from a literal may be invariant, but it
+            will needlessly increase register pressure if the
+            iCode(s) that use this iTemp are not also invariant */
+         if (ic->op=='=' && IS_ITEMP (IC_RESULT (ic))
+             && IS_OP_LITERAL (IC_RIGHT (ic)))
+           continue;
+
          /* if result is volatile then skip */
          if (IC_RESULT (ic) &&
              (isOperandVolatile (IC_RESULT (ic), TRUE) ||
@@ -478,7 +499,7 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
            continue;
 
          lin = rin = 0;
-         
+
          /* special case */
          /* if address of then it is an invariant */
          if (ic->op == ADDRESS_OF &&
@@ -492,14 +513,14 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
                 that the pointer set does not exist in
                 any of the blocks */
              if (POINTER_GET (ic) &&
-                 (applyToSet (theLoop->regBlocks, 
+                 (applyToSet (theLoop->regBlocks,
                               pointerAssigned, IC_LEFT (ic))))
                lin = 0;
          }
-         
+
          /* do the same for right */
          rin = isOperandInvariant (IC_RIGHT (ic), theLoop, lInvars);
-         
+
          /* if this is a POINTER_GET then special case, make sure all
             usages within the loop are POINTER_GET any other usage
             would mean that this is not an invariant , since the pointer
@@ -508,18 +529,19 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
              applyToSet (theLoop->regBlocks, hasNonPtrUse, IC_LEFT (ic)))
            continue;
 
-         /* if both the left & right are invariants : then check that */
-         /* this definition exists in the out definition of all the  */
-         /* blocks, this will ensure that this is not assigned any   */
-         /* other value in the loop , and not used in this block     */
+
+          /* if both the left & right are invariants : then check that */
+         /* this definition exists in the out definition of all the   */
+         /* blocks, this will ensure that this is not assigned any    */
+         /* other value in the loop, and not used in this block       */
          /* prior to this definition which means only this definition */
-         /* is used in this loop                                     */
+         /* is used in this loop                                      */
          if (lin && rin && IC_RESULT (ic))
            {
              eBBlock *sBlock;
              set *lSet = setFromSet (theLoop->regBlocks);
 
-             /* if this block does not dominate all exists */
+             /* if this block does not dominate all exits */
              /* make sure this defintion is not used anywhere else */
              if (!domsAllExits)
                {
@@ -555,6 +577,20 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
                    }
                  else if (bitVectBitsInCommon (sBlock->defSet, OP_DEFS (IC_RESULT (ic))))
                    break;
+
+                  if (IC_RESULT(ic))
+                    {
+                      iCode *ic2;
+                      /* check that this definition is not assigned */
+                      /* any other value in this block */
+                      for (ic2 = sBlock->sch; ic2; ic2 = ic2->next)
+                        {
+                          if ((ic != ic2) && (isOperandEqual(IC_RESULT(ic), IC_RESULT(ic2))))
+                            break;
+                        }
+                      if (ic2) /* found another definition */
+                        break;
+                    }
                }
 
              if (sBlock)
@@ -568,7 +604,9 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
              /* now we know it is a true invariant */
              /* remove it from the insts chain & put */
              /* in the invariant set                */
-             OP_SYMBOL (IC_RESULT (ic))->isinvariant = 1;
+
+              OP_SYMBOL (IC_RESULT (ic))->isinvariant = 1;
+              SPIL_LOC (IC_RESULT (ic)) = NULL;
              remiCodeFromeBBlock (lBlock, ic);
 
              /* maintain the data flow */
@@ -631,7 +669,7 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
 /*-----------------------------------------------------------------*/
 /* addressTaken - returns true if the symbol is found in the addrof */
 /*-----------------------------------------------------------------*/
-int 
+int
 addressTaken (set * sset, operand * sym)
 {
   set *loop;
@@ -818,7 +856,6 @@ basicInduction (region * loopReg, eBBlock ** ebbs, int count)
          if (nexits == 1)
            {
              eBBlock *exit = setFirstItem (loopReg->exits);
-
              /* if it is the same block then there is no
                 need to move it about */
              if (exit != lBlock)
@@ -856,7 +893,18 @@ basicInduction (region * loopReg, eBBlock ** ebbs, int count)
                      if (bitVectBitValue (loopSuccs, i))
                        {
 
-                         eBBlock *eblock = ebbs[i];
+                         eBBlock *eblock = NULL;
+                         int j;
+
+                         /* Need to search for bbnum == i since ebbs is  */
+                         /* sorted by dfnum; a direct index won't do.  */
+                         for (j=0; j<count; j++)
+                           if (ebbs[j]->bbnum == i)
+                             {
+                               eblock = ebbs[j];
+                               break;
+                             }
+                         assert(eblock);
 
                          /* if the successor does not belong to the loop
                             and will be executed after the loop : then
@@ -896,7 +944,7 @@ basicInduction (region * loopReg, eBBlock ** ebbs, int count)
 /*-----------------------------------------------------------------*/
 /* loopInduction - remove induction variables from a loop          */
 /*-----------------------------------------------------------------*/
-int 
+int
 loopInduction (region * loopReg, eBBlock ** ebbs, int count)
 {
   int change = 0;
@@ -1057,7 +1105,7 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count)
       lastBlock->linds = bitVectUnion(lastBlock->linds,indVect);
     }
 
-  setToNull ((void **) &indVars);
+  setToNull ((void *) &indVars);
   return change;
 }
 
@@ -1187,7 +1235,7 @@ createLoopRegions (eBBlock ** ebbs, int count)
 /*-----------------------------------------------------------------*/
 /* loopOptimizations - identify region & remove invariants & ind   */
 /*-----------------------------------------------------------------*/
-int 
+int
 loopOptimizations (hTab * orderedLoops, eBBlock ** ebbs, int count)
 {
   region *lp;