See Changelog 1.204
[fw/sdcc] / src / SDCCloop.c
index ca70d4b338eb52bb9bbbee8e7492d54a12002163..9bb74e335539b7f6c08b133d4e1bddf5f864729e 100644 (file)
@@ -1,3 +1,9 @@
+//#define LIVERANGEHUNT
+#ifdef LIVERANGEHUNT
+  #define LRH(x) x
+#else
+  #define LRH(x)
+#endif
 /*-------------------------------------------------------------------------
 
   SDCCloop.c - source file for loop detection & optimizations
@@ -39,14 +45,14 @@ newInduction (operand * sym, unsigned int op,
 {
   induction *ip;
 
-  ip = Safe_calloc (1, sizeof (induction));
+  ip = Safe_alloc ( sizeof (induction));
 
   ip->sym = sym;
   ip->asym = asym;
   ip->op = op;
   ip->cval = constVal;
   ip->ic = ic;
-
+  updateSpillLocation(ic,1);
   return ip;
 }
 
@@ -58,7 +64,7 @@ newRegion ()
 {
   region *lp;
 
-  lp = Safe_calloc (1, sizeof (region));
+  lp = Safe_alloc ( sizeof (region));
 
   return lp;
 }
@@ -153,6 +159,7 @@ loopInsert (set ** regionSet, eBBlock * block)
 {
   if (!isinSet (*regionSet, block))
     {
+      LRH(printf ("loopInsert: %s\n", block->entryLabel->name));
       addSetHead (regionSet, block);
       STACK_PUSH (regionStack, block);
     }
@@ -229,9 +236,10 @@ 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)
+  if (ebp->depth<depth)
     ebp->depth = depth;
 
   /* put the loop region info in the block */
@@ -258,16 +266,42 @@ 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))
     {
@@ -277,7 +311,61 @@ 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);
@@ -364,6 +452,9 @@ 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++;
@@ -445,11 +536,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;
+         /* jwk: 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)
@@ -857,9 +958,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)
@@ -947,8 +1048,8 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count)
 
          /* ask port for size not worth if native instruction
             exist for multiply & divide */
-         if (getSize (operandType (IC_LEFT (ic))) <= (unsigned long) port->muldiv.native_below ||
-         getSize (operandType (IC_RIGHT (ic))) <= (unsigned long) port->muldiv.native_below)
+         if (getSize (operandType (IC_LEFT (ic))) <= (unsigned long) port->support.muldiv ||
+         getSize (operandType (IC_RIGHT (ic))) <= (unsigned long) port->support.muldiv)
            continue;
 
          /* if this is a division then the remainder should be zero
@@ -1043,7 +1144,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);
@@ -1137,13 +1238,26 @@ 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);
+  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
 
   /* now we will create regions from these loops               */
   /* loops with the same entry points are considered to be the */
@@ -1157,6 +1271,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 */