Applied liferange patch from Klaus Flittner <klaus_flittner@gmx.de>
[fw/sdcc] / src / SDCCloop.c
index d04b717c2c759dafc3514958d14c7f74312360a0..6e6b26a6af37db57247cf217246bcd0b015d0cf7 100644 (file)
@@ -236,10 +236,8 @@ DEFSETFUNC (addToExitsMarkDepth)
     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 */
@@ -1216,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);
+               }
+           }
+       }
+    }
+}