* src/mcs51/gen.c (operandsEqu): fixed bug 1246687
[fw/sdcc] / src / SDCCloop.c
index 1f751594bb52ba54d290f41e66e0f455b6be7343..f12fe1b35f4065a1b1bc699567615304875a88a9 100644 (file)
@@ -302,11 +302,10 @@ DEFSETFUNC (addDefInExprs)
 {
   eBBlock *ebp = item;
   V_ARG (cseDef *, cdp);
-  V_ARG (eBBlock **, ebbs);
-  V_ARG (int, count);
+  V_ARG (ebbIndex *, ebbi);
 
   addSetHead (&ebp->inExprs, cdp);
-  cseBBlock (ebp, optimize.global_cse, ebbs, count);
+  cseBBlock (ebp, optimize.global_cse, ebbi);
   return 0;
 }
 
@@ -417,8 +416,10 @@ DEFSETFUNC (hasNonPtrUse)
 /* loopInvariants - takes loop invariants out of region            */
 /*-----------------------------------------------------------------*/
 int
-loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
+loopInvariants (region * theLoop, ebbIndex * ebbi)
 {
+  eBBlock ** ebbs = ebbi->dfOrder;
+  int count = ebbi->count;
   eBBlock *lBlock;
   set *lInvars = NULL;
 
@@ -568,6 +569,10 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
              for (sBlock = setFirstItem (lSet); sBlock;
                   sBlock = setNextItem (lSet))
                {
+                  iCode *ic2;
+                  int used;
+                  int defDominates;
+
                  /* if this is the block make sure the definition */
                  /* reaches the end of the block */
                  if (sBlock == lBlock)
@@ -578,25 +583,48 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
                  else if (bitVectBitsInCommon (sBlock->defSet, OP_DEFS (IC_RESULT (ic))))
                    break;
 
-                  if (IC_RESULT(ic))
+                  /* Check that this definition is not assigned */
+                  /* any other value in this block. Also check */
+                  /* that any usage in the block is dominated by */
+                  /* by this definition. */
+                  defDominates = bitVectBitValue (sBlock->domVect, lBlock->bbnum);
+                  used = 0;
+                  for (ic2 = sBlock->sch; ic2; ic2 = ic2->next)
                     {
-                      iCode *ic2;
-                      /* check that this definition is not assigned */
-                      /* any other value in this block */
-                      for (ic2 = sBlock->sch; ic2; ic2 = ic2->next)
+                      if (ic2->op == IFX)
+                        {
+                          if (isOperandEqual (IC_RESULT (ic), IC_COND (ic2)))
+                            used = 1;
+                        }
+                      else if (ic2->op == JUMPTABLE)
                         {
+                          if (isOperandEqual (IC_RESULT (ic), IC_JTCOND (ic2)))
+                            used = 1;
+                        }
+                      else
+                        {
+                          if (IC_LEFT (ic2) && isOperandEqual (IC_RESULT (ic), IC_LEFT (ic2)))
+                            used = 1;
+                          if (IC_RIGHT (ic2) && isOperandEqual (IC_RESULT (ic), IC_RIGHT (ic2)))
+                            used = 1;
                           if ((ic != ic2) && (isOperandEqual(IC_RESULT(ic), IC_RESULT(ic2))))
                             break;
+                          /* If used before this definition, might not be invariant */
+                          if ((ic == ic2) && used)
+                            break;
                         }
-                      if (ic2) /* found another definition */
+                      if (used && !defDominates)
                         break;
                     }
+                  if (ic2) /* found another definition or a usage before the definition */
+                    break;
                }
 
              if (sBlock)
                continue;       /* another definition present in the block */
+              
 
-             /* now check if it exists in the in of this block */
+              /* now check if it exists in the in of this block */
              /* if not then it was killed before this instruction */
              if (!bitVectBitValue (lBlock->inDefs, ic->key))
                continue;
@@ -616,7 +644,7 @@ loopInvariants (region * theLoop, eBBlock ** ebbs, int count)
              bitVectUnSetBit (lBlock->defSet, ic->key);
              bitVectUnSetBit (lBlock->ldefs, ic->key);
              ivar = newCseDef (IC_RESULT (ic), ic);
-             applyToSet (theLoop->regBlocks, addDefInExprs, ivar, ebbs, count);
+             applyToSet (theLoop->regBlocks, addDefInExprs, ivar, ebbi);
              addSet (&lInvars, ivar);
            }
        }
@@ -984,8 +1012,10 @@ basicInduction (region * loopReg, eBBlock ** ebbs, int count)
 /* loopInduction - remove induction variables from a loop          */
 /*-----------------------------------------------------------------*/
 int
-loopInduction (region * loopReg, eBBlock ** ebbs, int count)
+loopInduction (region * loopReg, ebbIndex * ebbi)
 {
+  eBBlock ** ebbs = ebbi->dfOrder;
+  int count = ebbi->count;
   int change = 0;
   eBBlock *lBlock, *owner, *lastBlock = NULL;
   set *indVars = NULL;
@@ -1018,7 +1048,6 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count)
        {
          operand *aSym;
          long litVal;
-         int lr = 0;
 
          /* consider only * & / */
          if (ic->op != '*' && ic->op != '/')
@@ -1232,7 +1261,7 @@ DEFSETFUNC (mergeInnerLoops)
 /* createLoopRegions - will detect and create a set of natural loops */
 /*-----------------------------------------------------------------*/
 hTab *
-createLoopRegions (eBBlock ** ebbs, int count)
+createLoopRegions (ebbIndex * ebbi)
 {
   set *allRegion = NULL;       /* set of all loops */
   hTab *orderedLoops = NULL;
@@ -1280,7 +1309,7 @@ createLoopRegions (eBBlock ** ebbs, int count)
 /* loopOptimizations - identify region & remove invariants & ind   */
 /*-----------------------------------------------------------------*/
 int
-loopOptimizations (hTab * orderedLoops, eBBlock ** ebbs, int count)
+loopOptimizations (hTab * orderedLoops, ebbIndex * ebbi)
 {
   region *lp;
   int change = 0;
@@ -1300,10 +1329,10 @@ loopOptimizations (hTab * orderedLoops, eBBlock ** ebbs, int count)
     {
 
       if (optimize.loopInvariant)
-       change += loopInvariants (lp, ebbs, count);
+       change += loopInvariants (lp, ebbi);
 
       if (optimize.loopInduction)
-       change += loopInduction (lp, ebbs, count);
+       change += loopInduction (lp, ebbi);
     }
 
   return change;