* as/xa51/xa_version.h,
[fw/sdcc] / src / SDCCloop.c
index 2819c859dcbf689953057e3b814b12baf14dfbef..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)
@@ -259,11 +258,8 @@ DEFSETFUNC (createLoop)
 {
   edge *ep = item;
   V_ARG (set **, allRegion);
-  V_ARG (eBBlock **,ebbs);
-  V_ARG (int,count);
   region *aloop = newRegion ();
   eBBlock *block;
-  int dfMin = count ,dfMax =0, i;
 
   /* make sure regionStack is empty */
   while (!STACK_EMPTY (regionStack))
@@ -282,22 +278,6 @@ DEFSETFUNC (createLoop)
     }
 
   aloop->entry = ep->to;
-  /* set max & min dfNum for loopRegion */
-  for ( block = setFirstItem(aloop->regBlocks); block; 
-       block = setNextItem(aloop->regBlocks)) {
-      if (block->dfnum > dfMax) dfMax = block->dfnum;
-      if (block->dfnum < dfMin) dfMin = block->dfnum;
-  }
-
-  /* all blocks that have dfnumbers between dfMin & dfMax are also
-     part of loop */
-  for (i = 0 ; i < count ; i++) {
-      if (ebbs[i]->dfnum > dfMin && 
-         ebbs[i]->dfnum < dfMax &&
-         !isinSet(aloop->regBlocks,ebbs[i])) {
-         if (!ebbs[i]->partOfLoop) ebbs[i]->partOfLoop = aloop;
-      }
-  }
 
   /* now add it to the set */
   addSetHead (allRegion, aloop);
@@ -326,14 +306,14 @@ DEFSETFUNC (addDefInExprs)
   V_ARG (int, count);
 
   addSetHead (&ebp->inExprs, cdp);
-  cseBBlock (ebp, 0, ebbs, count);
+  cseBBlock (ebp, optimize.global_cse, ebbs, count);
   return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* assignmentsToSym - for a set of blocks determine # time assigned */
 /*-----------------------------------------------------------------*/
-int 
+int
 assignmentsToSym (set * sset, operand * sym)
 {
   eBBlock *ebp;
@@ -348,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);
 
     }
 
@@ -359,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;
@@ -399,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;
 }
 
 /*-----------------------------------------------------------------*/
@@ -421,7 +416,7 @@ DEFSETFUNC (hasNonPtrUse)
 /*-----------------------------------------------------------------*/
 /* loopInvariants - takes loop invariants out of region            */
 /*-----------------------------------------------------------------*/
-int 
+int
 loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
 {
   eBBlock *lBlock;
@@ -436,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))
     {
@@ -465,7 +460,7 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
          int lin, rin;
          cseDef *ivar;
 
-         /* jwk: TODO this is only needed if the call is between
+         /* TODO this is only needed if the call is between
             here and the definition, but I am too lazy to do that now */
 
          /* if there are function calls in this block */
@@ -485,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) ||
@@ -497,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 &&
@@ -511,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
@@ -527,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)
                {
@@ -574,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)
@@ -587,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 */
@@ -650,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;
@@ -837,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)
@@ -875,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
@@ -887,10 +916,10 @@ basicInduction (region * loopReg, eBBlock ** ebbs, int count)
                              iCode *newic = newiCode ('=', NULL,
                                        operandFromOperand (IC_RIGHT (ic)));
                              IC_RESULT (newic) = operandFromOperand (IC_RESULT (ic));
-                             OP_DEFS_SET ((IC_RESULT (newic)),
-                               bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key));
-                             OP_USES_SET ((IC_RIGHT (newic)),
-                               bitVectSetBit (OP_USES (IC_RIGHT (newic)), newic->key));
+                             OP_DEFS(IC_RESULT (newic))=
+                               bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key);
+                             OP_USES(IC_RIGHT (newic))=
+                               bitVectSetBit (OP_USES (IC_RIGHT (newic)), newic->key);
                              /* and add it */
                              if (eblock->sch && eblock->sch->op == LABEL)
                                addiCodeToeBBlock (eblock, newic, eblock->sch->next);
@@ -915,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;
@@ -1076,7 +1105,7 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count)
       lastBlock->linds = bitVectUnion(lastBlock->linds,indVect);
     }
 
-  setToNull ((void **) &indVars);
+  setToNull ((void *) &indVars);
   return change;
 }
 
@@ -1104,7 +1133,7 @@ DEFSETFUNC (mergeRegions)
       if (lp->entry == theLoop->entry)
        {
          theLoop->regBlocks = unionSets (theLoop->regBlocks,
-                                         lp->regBlocks, THROW_BOTH);
+                                         lp->regBlocks, THROW_DEST);
          lp->merged = 1;
        }
     }
@@ -1173,7 +1202,7 @@ createLoopRegions (eBBlock ** ebbs, int count)
 
   /* for each of these back edges get the blocks that */
   /* constitute the loops                             */
-  applyToSet (bEdges, createLoop, &allRegion, ebbs,count);
+  applyToSet (bEdges, createLoop, &allRegion);
 
   /* now we will create regions from these loops               */
   /* loops with the same entry points are considered to be the */
@@ -1187,6 +1216,7 @@ createLoopRegions (eBBlock ** ebbs, int count)
 
   applyToSet (allRegion, mergeInnerLoops, allRegion, &maxDepth);
   maxDepth++;
+
   /* now create all the exits .. also */
   /* create an ordered set of loops   */
   /* i.e. we process loops in the inner to outer order */
@@ -1205,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;