cleaned up the mess I left behind
[fw/sdcc] / src / SDCCloop.c
index ef79a6b90a0df3a210ef3fb3bf002723343ff1c8..55021f34798aa1a0d80e920e8a9a29bd86e22f6a 100644 (file)
@@ -39,14 +39,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 +58,7 @@ newRegion ()
 {
   region *lp;
 
-  lp = Safe_calloc (1, sizeof (region));
+  lp = Safe_alloc ( sizeof (region));
 
   return lp;
 }
@@ -231,7 +231,8 @@ 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 */
@@ -258,8 +259,11 @@ 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))
@@ -279,6 +283,32 @@ 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;
+         }
+      }
+  }
+
+  /* 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);
   return 0;
@@ -408,6 +438,7 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
   set *lInvars = NULL;
 
   int change = 0;
+  int fCallsInBlock;
 
   /* if the preHeader does not exist then do nothing */
   /* or no exits then do nothing ( have to think about this situation */
@@ -429,6 +460,12 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
       domsAllExits = (applyToSet (theLoop->exits, dominatedBy, lBlock) ==
                      elementsInSet (theLoop->exits));
 
+      /* find out if we have a function call in this block */
+      for (ic = lBlock->sch, fCallsInBlock=0; ic; ic = ic->next) {
+       if (SKIP_IC(ic)) {
+         fCallsInBlock++;
+       }
+      }
 
       /* now we go thru the instructions of this block and */
       /* collect those instructions with invariant operands */
@@ -438,6 +475,23 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
          int lin, rin;
          cseDef *ivar;
 
+         /* 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)
            continue;
 
@@ -453,26 +507,28 @@ 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 &&
              IS_SYMOP (IC_LEFT (ic)) &&
              IS_AGGREGATE (operandType (IC_LEFT (ic))))
            lin++;
-         else
+         else {
            /* check if left operand is an invariant */
-         if ((lin = isOperandInvariant (IC_LEFT (ic), theLoop, lInvars)))
-           /* if this is a pointer get then make sure
-              that the pointer set does not exist in
-              any of the blocks */
-           if (POINTER_GET (ic) &&
-           (applyToSet (theLoop->regBlocks, pointerAssigned, IC_LEFT (ic))))
-             lin = 0;
-
+           if ((lin = isOperandInvariant (IC_LEFT (ic), theLoop, lInvars)))
+             /* if this is a pointer get then make sure
+                that the pointer set does not exist in
+                any of the blocks */
+             if (POINTER_GET (ic) &&
+                 (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
@@ -742,8 +798,8 @@ basicInduction (region * loopReg, eBBlock ** ebbs, int count)
            continue;
 
          aSym = (IS_OP_LITERAL (IC_RIGHT (dic)) ?
-             (litValue = operandLitValue (IC_RIGHT (dic)), IC_LEFT (dic)) :
-             (litValue = operandLitValue (IC_LEFT (dic)), IC_RIGHT (dic)));
+             (litValue = (unsigned long) operandLitValue (IC_RIGHT (dic)), IC_LEFT (dic)) :
+             (litValue = (unsigned long) operandLitValue (IC_LEFT (dic)), IC_RIGHT (dic)));
 
          if (!isOperandEqual (IC_RESULT (ic), aSym) &&
              !isOperandEqual (IC_RIGHT (ic), aSym))
@@ -841,9 +897,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)
@@ -921,8 +977,8 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count)
            continue;
 
          aSym = (IS_SYMOP (IC_LEFT (ic)) ?
-         (lr = 1, litVal = operandLitValue (IC_RIGHT (ic)), IC_LEFT (ic)) :
-                 (litVal = operandLitValue (IC_LEFT (ic)), IC_RIGHT (ic)));
+         (lr = 1, litVal = (unsigned long) operandLitValue (IC_RIGHT (ic)), IC_LEFT (ic)) :
+                 (litVal = (unsigned long) operandLitValue (IC_LEFT (ic)), IC_RIGHT (ic)));
 
          ip = NULL;
          /* check if this is an induction variable */
@@ -931,8 +987,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))) <= port->muldiv.native_below ||
-         getSize (operandType (IC_RIGHT (ic))) <= 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
@@ -1027,7 +1083,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);
@@ -1058,7 +1114,7 @@ DEFSETFUNC (mergeRegions)
       if (lp->entry == theLoop->entry)
        {
          theLoop->regBlocks = unionSets (theLoop->regBlocks,
-                                         lp->regBlocks, THROW_BOTH);
+                                         lp->regBlocks, THROW_DEST);
          lp->merged = 1;
        }
     }
@@ -1127,7 +1183,7 @@ createLoopRegions (eBBlock ** ebbs, int count)
 
   /* for each of these back edges get the blocks that */
   /* constitute the loops                             */
-  applyToSet (bEdges, createLoop, &allRegion);
+  applyToSet (bEdges, createLoop, &allRegion, ebbs,count);
 
   /* now we will create regions from these loops               */
   /* loops with the same entry points are considered to be the */
@@ -1141,6 +1197,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 */