Applied liferange patch from Klaus Flittner <klaus_flittner@gmx.de>
[fw/sdcc] / src / SDCCloop.c
index 87523a21978a29a4c3b6e241cc0fe3dfe4b9a9d6..6e6b26a6af37db57247cf217246bcd0b015d0cf7 100644 (file)
@@ -231,14 +231,13 @@ DEFSETFUNC (addToExitsMarkDepth)
   V_ARG (region *, lr);
 
   /* mark the loop depth of this block */
-  if (!ebp->depth)
+  //if (!ebp->depth)
+  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)
-    ebp->partOfLoop = lr;
+  if (!isinSet (ebp->partOfLoop, lr))
+    addSetHead (&ebp->partOfLoop, lr);
 
   /* if any of the successors go out of the loop then */
   /* we add this one to the exits */
@@ -306,7 +305,7 @@ DEFSETFUNC (addDefInExprs)
   V_ARG (int, count);
 
   addSetHead (&ebp->inExprs, cdp);
-  cseBBlock (ebp, 0, ebbs, count);
+  cseBBlock (ebp, optimize.global_cse, ebbs, count);
   return 0;
 }
 
@@ -445,11 +444,21 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
          int lin, rin;
          cseDef *ivar;
 
-         /* if there are function calls in this block and this
-            is a pointer get, the function could have changed it
-            so skip, ISO-C99 according to David A. Long */
-         if (fCallsInBlock && POINTER_GET(ic)) {
-           continue;
+         /* 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 */
+         if (fCallsInBlock) {
+
+           /* if this is a pointer get */
+           if (POINTER_GET(ic)) {
+             continue;
+           }
+
+           /* if this is an assignment from a global */
+           if (ic->op=='=' && isOperandGlobal(IC_RIGHT(ic))) {
+             continue;
+           }
          }
 
          if (SKIP_IC (ic) || POINTER_SET (ic) || ic->op == IFX)
@@ -798,13 +807,6 @@ basicInduction (region * loopReg, eBBlock ** ebbs, int count)
          OP_SYMBOL (IC_RESULT (indIc))->isind = 1;
          ip = newInduction (IC_RIGHT (ic), dic->op, litValue, indIc, NULL);
 
-         if (0) {
-           fprintf (stderr, "%s:%d: stupid way to avoid bug #467035, but\n"
-                    "this will keep the regressions tests going.\n",
-                    __FILE__, __LINE__);
-           continue;
-         } continue;
-
          /* replace the inducted variable by the iTemp */
          replaceSymBySym (loopReg->regBlocks, IC_RESULT (ic), IC_RIGHT (ic));
 
@@ -864,9 +866,9 @@ basicInduction (region * loopReg, eBBlock ** ebbs, int count)
                              iCode *newic = newiCode ('=', NULL,
                                        operandFromOperand (IC_RIGHT (ic)));
                              IC_RESULT (newic) = operandFromOperand (IC_RESULT (ic));
-                             OP_DEFS (IC_RESULT (newic)) =
+                             OP_DEFS(IC_RESULT (newic))=
                                bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key);
-                             OP_USES (IC_RIGHT (newic)) =
+                             OP_USES(IC_RIGHT (newic))=
                                bitVectSetBit (OP_USES (IC_RIGHT (newic)), newic->key);
                              /* and add it */
                              if (eblock->sch && eblock->sch->op == LABEL)
@@ -1050,7 +1052,7 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count)
       /* add the induction variable vector to the last
          block in the loop */
       lastBlock->isLastInLoop = 1;
-      lastBlock->linds = indVect;
+      lastBlock->linds = bitVectUnion(lastBlock->linds,indVect);
     }
 
   setToNull ((void **) &indVars);
@@ -1081,7 +1083,7 @@ DEFSETFUNC (mergeRegions)
       if (lp->entry == theLoop->entry)
        {
          theLoop->regBlocks = unionSets (theLoop->regBlocks,
-                                         lp->regBlocks, THROW_BOTH);
+                                         lp->regBlocks, THROW_DEST);
          lp->merged = 1;
        }
     }
@@ -1164,6 +1166,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 */
@@ -1211,3 +1214,57 @@ loopOptimizations (hTab * orderedLoops, eBBlock ** ebbs, int count)
 
   return change;
 }
+
+/*-----------------------------------------------------------------*/
+/* addLoopBlocks - will add all blocks inside a loop to this loop  */
+/* this should fix most of the liverange problems                  */
+/*-----------------------------------------------------------------*/
+void
+addLoopBlocks (eBBlock ** ebbs, int count)
+{
+  region *aloop;
+  struct eBBlock *block;
+  int seqMin, seqMax;
+  int i, j;
+
+  for (i = 0; i < count; i++)
+    {
+      if (!ebbs[i]->partOfLoop)
+        continue;
+
+      /* for all loops this block belongs to */
+      /* add inner block not already marked as part of this loop */
+      aloop = setFirstItem (ebbs[i]->partOfLoop);
+      for (; aloop; aloop = setNextItem (ebbs[i]->partOfLoop))
+        {
+
+          if (aloop->visited)
+            continue;
+
+          aloop->visited = 1;
+
+          /* set max & min Seq for loopRegion */
+          block = setFirstItem (aloop->regBlocks);
+          seqMax = block->lSeq;
+          seqMin = block->fSeq;
+          for (; block; block = setNextItem (aloop->regBlocks))
+           {
+              if (block->lSeq > seqMax)
+                seqMax = block->lSeq;
+              if (block->fSeq < seqMin)
+                seqMin = block->fSeq;
+            }
+
+          /* add all blocks between seqMin, seqMax to loop */
+          for (j = 0; j < count; j++)
+           {
+              if (ebbs[j]->fSeq > seqMin && ebbs[j]->lSeq < seqMax &&
+                  !isinSet (aloop->regBlocks, ebbs[j]))
+               {
+                  if (!isinSet (ebbs[i]->partOfLoop, aloop))
+                   addSetHead (&ebbs[j]->partOfLoop, aloop);
+               }
+           }
+       }
+    }
+}