Initial import
[fw/sdcc] / src / SDCCloop.c
index 9bb74e335539b7f6c08b133d4e1bddf5f864729e..e68eabf916a3431d769df30bead5152b621140f0 100644 (file)
@@ -1,9 +1,3 @@
-//#define LIVERANGEHUNT
-#ifdef LIVERANGEHUNT
-  #define LRH(x) x
-#else
-  #define LRH(x)
-#endif
 /*-------------------------------------------------------------------------
 
   SDCCloop.c - source file for loop detection & optimizations
@@ -159,7 +153,6 @@ loopInsert (set ** regionSet, eBBlock * block)
 {
   if (!isinSet (*regionSet, block))
     {
-      LRH(printf ("loopInsert: %s\n", block->entryLabel->name));
       addSetHead (regionSet, block);
       STACK_PUSH (regionStack, block);
     }
@@ -236,17 +229,25 @@ DEFSETFUNC (addToExitsMarkDepth)
   V_ARG (set **, exits);
   V_ARG (int, depth);
   V_ARG (region *, lr);
-  LRH(printf ("addToExitsMarkDepth: %s %d\n", ebp->entryLabel->name, depth));
+
   /* mark the loop depth of this block */
   //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 (getenv ("SDCC_LRKLAUS"))
+    {
+      /* put the loop region info in the block */
+      if (!isinSet (ebp->KpartOfLoop, lr))
+        addSetHead (&ebp->KpartOfLoop, lr);
+    }
+  else
+    {
+      /* NOTE: here we will update only the inner most loop
+         that it is a part of */
+      if (!ebp->partOfLoop)
+        ebp->partOfLoop = lr;
+    }
 
   /* if any of the successors go out of the loop then */
   /* we add this one to the exits */
@@ -266,42 +267,16 @@ 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;
 
-  LRH(printf("CreateLoop\n"));
   /* make sure regionStack is empty */
   while (!STACK_EMPTY (regionStack))
     STACK_POP (regionStack);
 
   /* add the entryBlock */
   addSet (&aloop->regBlocks, ep->to);
-#ifdef LIVERANGEHUNT
-  // print regBlocks jwk
-  { 
-    eBBlock *ebp;
-    region *lp=aloop;
-    for (ebp=setFirstItem(lp->regBlocks); ebp; ebp=setNextItem(lp->regBlocks)) {
-      printf ("cl1 %s ", ebp->entryLabel->name);
-    }
-    printf (" %d\n", count);
-  }
-#endif
   loopInsert (&aloop->regBlocks, ep->from);
-#ifdef LIVERANGEHUNT
-  // print regBlocks jwk
-  { 
-    eBBlock *ebp;
-    region *lp=aloop;
-    for (ebp=setFirstItem(lp->regBlocks); ebp; ebp=setNextItem(lp->regBlocks)) {
-      printf ("cl2 %s ", ebp->entryLabel->name);
-    }
-    printf (" %d\n", count);
-  }
-#endif
 
   while (!STACK_EMPTY (regionStack))
     {
@@ -311,61 +286,7 @@ DEFSETFUNC (createLoop)
        applyToSet (block->predList, insertIntoLoop, &aloop->regBlocks);
     }
 
-#ifdef LIVERANGEHUNT
-  // print regBlocks jwk
-  { 
-    eBBlock *ebp;
-    region *lp=aloop;
-    for (ebp=setFirstItem(lp->regBlocks); ebp; ebp=setNextItem(lp->regBlocks)) {
-      printf ("cl3 %s ", ebp->entryLabel->name);
-    }
-    printf (" %d\n", count);
-  }
-#endif
-
   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) {
-#if !defined(LIVERANGEHUNT)
-           ebbs[i]->partOfLoop = aloop;
-#else
-           loopInsert(&aloop->regBlocks,ebbs[i]);
-#endif
-         }
-      }
-  }
-
-#ifdef LIVERANGEHUNT
-  printf ("================\n");
-  printf (" loop with entry -- > ");
-  printEntryLabel (aloop->entry, ap);
-  printf ("\n");
-  printf (" loop body --> ");
-  applyToSet (aloop->regBlocks, printEntryLabel);
-  printf ("\n");
-  printf (" loop exits --> ");
-  applyToSet (aloop->exits, printEntryLabel);
-  printf ("\n");
-#endif
-
-  /* and if this is a conditional block, the other side of the IFX 
-     (if any, that could have a greater dfnum) is too */
-  {
-    // just a burp, but I'm getting close :)
-  }
-  
 
   /* now add it to the set */
   addSetHead (allRegion, aloop);
@@ -394,7 +315,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;
 }
 
@@ -416,7 +337,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);
 
     }
 
@@ -452,9 +373,6 @@ isOperandInvariant (operand * op, region * theLoop, set * lInvars)
               !IS_OP_VOLATILE (op) &&
               assignmentsToSym (theLoop->regBlocks, op) == 0)
        opin = 1;
-      LRH(if (opin && IS_SYMOP(op)) {
-       printf("isOperandInvariant: %s\n", OP_SYMBOL(op)->name);
-      });
     }
   else
     opin++;
@@ -536,7 +454,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 */
@@ -1147,7 +1065,7 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count)
       lastBlock->linds = bitVectUnion(lastBlock->linds,indVect);
     }
 
-  setToNull ((void **) &indVars);
+  setToNull ((void *) &indVars);
   return change;
 }
 
@@ -1175,7 +1093,7 @@ DEFSETFUNC (mergeRegions)
       if (lp->entry == theLoop->entry)
        {
          theLoop->regBlocks = unionSets (theLoop->regBlocks,
-                                         lp->regBlocks, THROW_BOTH);
+                                         lp->regBlocks, THROW_DEST);
          lp->merged = 1;
        }
     }
@@ -1238,26 +1156,13 @@ createLoopRegions (eBBlock ** ebbs, int count)
   int maxDepth = 0;
   region *lp;
 
-  LRH(printf ("createLoopRegions: %p\n", ebbs));
   /* get all the back edges in the graph */
   if (!applyToSet (graphEdges, backEdges, &bEdges))
     return 0;                  /* found no loops */
 
   /* for each of these back edges get the blocks that */
   /* constitute the loops                             */
-  applyToSet (bEdges, createLoop, &allRegion, ebbs,count);
-#ifdef LIVERANGEHUNT
-  // print regBlocks
-  { 
-    eBBlock *ebp;
-    lp=setFirstItem(allRegion);
-    printf ("createLoopRegions: ");
-    for (ebp=setFirstItem(lp->regBlocks); ebp; ebp=setNextItem(lp->regBlocks)) {
-      printf ("%s ", ebp->entryLabel->name);
-    }
-    printf (" %d\n", count);
-  }
-#endif
+  applyToSet (bEdges, createLoop, &allRegion);
 
   /* now we will create regions from these loops               */
   /* loops with the same entry points are considered to be the */
@@ -1319,3 +1224,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]->KpartOfLoop)
+        continue;
+
+      /* for all loops this block belongs to */
+      /* add inner block not already marked as part of this loop */
+      aloop = setFirstItem (ebbs[i]->KpartOfLoop);
+      for (; aloop; aloop = setNextItem (ebbs[i]->KpartOfLoop))
+        {
+
+          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[j]->KpartOfLoop, aloop))
+                   addSetHead (&ebbs[j]->KpartOfLoop, aloop);
+               }
+           }
+       }
+    }
+}