* device/include/pic16/pic18f*.h: add bit aliases in INTCONbits_t
[fw/sdcc] / src / SDCCloop.c
index c3e2f7e86be8960b46c8e8f73a2e6f24ee3db83b..6400d1a4f411f7b92dae13451ab6cf31d93bb52a 100644 (file)
@@ -35,7 +35,7 @@ STACK_DCL (regionStack, eBBlock *, MAX_NEST_LEVEL * 10);
 /*-----------------------------------------------------------------*/
 static induction *
 newInduction (operand * sym, unsigned int op,
-             long constVal, iCode * ic, operand * asym)
+              long constVal, iCode * ic, operand * asym)
 {
   induction *ip;
 
@@ -143,7 +143,7 @@ intersectLoopSucc (set * lexits, eBBlock ** ebbs)
        exit = setNextItem (lexits))
     {
       succVect = bitVectIntersect (succVect,
-                                  exit->succVect);
+                                   exit->succVect);
     }
 
   return succVect;
@@ -219,7 +219,7 @@ findLoopEndSeq (region * lreg)
        block = setNextItem (lreg->regBlocks))
     {
       if (block != lblock && block->lSeq > lblock->lSeq)
-       lblock = block;
+        lblock = block;
     }
 
   return lblock->lSeq;
@@ -284,7 +284,7 @@ DEFSETFUNC (createLoop)
       block = STACK_POP (regionStack);
       /* if block != entry */
       if (block != ep->to)
-       applyToSet (block->predList, insertIntoLoop, &aloop->regBlocks);
+        applyToSet (block->predList, insertIntoLoop, &aloop->regBlocks);
     }
 
   aloop->entry = ep->to;
@@ -360,19 +360,19 @@ isOperandInvariant (operand * op, region * theLoop, set * lInvars)
   if (op)
     {
       if (IS_OP_LITERAL (op))
-       opin = 1;
+        opin = 1;
       else if (IS_SYMOP (op) &&
-              OP_SYMBOL (op)->addrtaken)
-       opin = 0;
+               OP_SYMBOL (op)->addrtaken)
+        opin = 0;
       else if (ifDefSymIs (theLoop->entry->inExprs, op))
-       opin = 1;
+        opin = 1;
       else if (ifDefSymIs (lInvars, op))
-       opin = 1;
+        opin = 1;
       else if (IS_SYMOP (op) &&
-              !IS_OP_GLOBAL (op) &&
-              !IS_OP_VOLATILE (op) &&
-              assignmentsToSym (theLoop->regBlocks, op) == 0)
-       opin = 1;
+               !IS_OP_GLOBAL (op) &&
+               !IS_OP_VOLATILE (op) &&
+               assignmentsToSym (theLoop->regBlocks, op) == 0)
+        opin = 1;
     }
   else
     opin++;
@@ -456,144 +456,159 @@ loopInvariants (region * theLoop, ebbIndex * ebbi)
 
       /* mark the dominates all exits flag */
       domsAllExits = (applyToSet (theLoop->exits, dominatedBy, lBlock) ==
-                     elementsInSet (theLoop->exits));
+                      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++;
-       }
-      }
+      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 */
       for (ic = lBlock->sch; ic; ic = ic->next)
-       {
-
-         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;
-
-         /* iTemp assignment from a literal may be invariant, but it
-            will needlessly increase register pressure if the
-            iCode(s) that use this iTemp are not also invariant */
-         if (ic->op=='=' && IS_ITEMP (IC_RESULT (ic))
-             && IS_OP_LITERAL (IC_RIGHT (ic)))
-           continue;
-
-         /* if result is volatile then skip */
-         if (IC_RESULT (ic) &&
-             (isOperandVolatile (IC_RESULT (ic), TRUE) ||
-              IS_OP_PARM (IC_RESULT (ic))))
-           continue;
-
-         /* if result depends on a volatile then skip */
-         if ((IC_LEFT(ic) && isOperandVolatile(IC_LEFT(ic), TRUE)) ||
-             (IC_RIGHT(ic) && isOperandVolatile(IC_RIGHT(ic), TRUE)))
-           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 {
-           /* 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;
-         }
-
-         /* 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
-            could then be passed as a parameter */
-         if (POINTER_GET (ic) &&
-             applyToSet (theLoop->regBlocks, hasNonPtrUse, IC_LEFT (ic)))
-           continue;
+        {
+
+          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;
+                }
+
+              /* Bug 1717943, 
+               * if this is an assignment to a global */
+              if (ic->op=='=' && isOperandGlobal(IC_RESULT(ic)))
+                {
+                  continue;
+                }
+            }
+
+          if (SKIP_IC (ic) || POINTER_SET (ic) || ic->op == IFX)
+            continue;
+
+          /* iTemp assignment from a literal may be invariant, but it
+             will needlessly increase register pressure if the
+             iCode(s) that use this iTemp are not also invariant */
+          if (ic->op=='=' && IS_ITEMP (IC_RESULT (ic))
+              && IS_OP_LITERAL (IC_RIGHT (ic)))
+            continue;
+
+          /* if result is volatile then skip */
+          if (IC_RESULT (ic) &&
+              (isOperandVolatile (IC_RESULT (ic), TRUE) ||
+               IS_OP_PARM (IC_RESULT (ic))))
+            continue;
+
+          /* if result depends on a volatile then skip */
+          if ((IC_LEFT(ic) && isOperandVolatile(IC_LEFT(ic), TRUE)) ||
+              (IC_RIGHT(ic) && isOperandVolatile(IC_RIGHT(ic), TRUE)))
+            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
+            {
+              /* 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 */
+                  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
+             could then be passed as a parameter */
+          if (POINTER_GET (ic) &&
+              applyToSet (theLoop->regBlocks, hasNonPtrUse, IC_LEFT (ic)))
+            continue;
 
 
           /* if both the left & right are invariants : then check that */
-         /* this definition exists in the out definition of all the   */
-         /* blocks, this will ensure that this is not assigned any    */
-         /* other value in the loop, and not used in this block       */
-         /* prior to this definition which means only this definition */
-         /* is used in this loop                                      */
-         if (lin && rin && IC_RESULT (ic))
-           {
-             eBBlock *sBlock;
-             set *lSet = setFromSet (theLoop->regBlocks);
-
-             /* if this block does not dominate all exits */
-             /* make sure this defintion is not used anywhere else */
-             if (!domsAllExits)
-               {
-
-                 if (isOperandGlobal (IC_RESULT (ic)))
-                   continue;
-                 /* for successors for all exits */
-                 for (sBlock = setFirstItem (theLoop->exits); sBlock;
-                      sBlock = setNextItem (theLoop->exits))
-                   {
-
-                     for (i = 0; i < count; ebbs[i++]->visited = 0);
-                     lBlock->visited = 1;
-                     if (applyToSet (sBlock->succList, isDefAlive, ic))
-                       break;
-                   }
-
-                 /* we have found usage */
-                 if (sBlock)
-                   continue;
-               }
-
-             /* now make sure this is the only definition */
-             for (sBlock = setFirstItem (lSet); sBlock;
-                  sBlock = setNextItem (lSet))
-               {
+          /* this definition exists in the out definition of all the   */
+          /* blocks, this will ensure that this is not assigned any    */
+          /* other value in the loop, and not used in this block       */
+          /* prior to this definition which means only this definition */
+          /* is used in this loop                                      */
+          if (lin && rin && IC_RESULT (ic))
+            {
+              eBBlock *sBlock;
+              set *lSet = setFromSet (theLoop->regBlocks);
+
+              /* if this block does not dominate all exits */
+              /* make sure this defintion is not used anywhere else */
+              if (!domsAllExits)
+                {
+
+                  if (isOperandGlobal (IC_RESULT (ic)))
+                    continue;
+                  /* for successors for all exits */
+                  for (sBlock = setFirstItem (theLoop->exits); sBlock;
+                       sBlock = setNextItem (theLoop->exits))
+                    {
+
+                      for (i = 0; i < count; ebbs[i++]->visited = 0);
+                      lBlock->visited = 1;
+                      if (applyToSet (sBlock->succList, isDefAlive, ic))
+                        break;
+                    }
+
+                  /* we have found usage */
+                  if (sBlock)
+                    continue;
+                }
+
+              /* now make sure this is the only definition */
+              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)
-                   {
-                     if (!ifDiCodeIs (sBlock->outExprs, ic))
-                       break;
-                   }
-                 else if (bitVectBitsInCommon (sBlock->defSet, OP_DEFS (IC_RESULT (ic))))
-                   break;
+                  /* if this is the block make sure the definition */
+                  /* reaches the end of the block */
+                  if (sBlock == lBlock)
+                    {
+                      if (!ifDiCodeIs (sBlock->outExprs, ic))
+                        break;
+                    }
+                  else if (bitVectBitsInCommon (sBlock->defSet, OP_DEFS (IC_RESULT (ic))))
+                    break;
 
                   /* Check that this definition is not assigned */
                   /* any other value in this block. Also check */
@@ -630,37 +645,37 @@ loopInvariants (region * theLoop, ebbIndex * ebbi)
                     }
                   if (ic2) /* found another definition or a usage before the definition */
                     break;
-               }
+                }
+
+              if (sBlock)
+                continue;       /* another definition present in the block */
 
-             if (sBlock)
-               continue;       /* another definition present in the 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;
+              /* if not then it was killed before this instruction */
+              if (!bitVectBitValue (lBlock->inDefs, ic->key))
+                continue;
 
-             /* now we know it is a true invariant */
-             /* remove it from the insts chain & put */
-             /* in the invariant set                */
+              /* now we know it is a true invariant */
+              /* remove it from the insts chain & put */
+              /* in the invariant set                */
 
               OP_SYMBOL (IC_RESULT (ic))->isinvariant = 1;
               SPIL_LOC (IC_RESULT (ic)) = NULL;
-             remiCodeFromeBBlock (lBlock, ic);
-
-             /* maintain the data flow */
-             /* this means removing from definition from the */
-             /* defset of this block and adding it to the    */
-             /* inexpressions of all blocks within the loop  */
-             bitVectUnSetBit (lBlock->defSet, ic->key);
-             bitVectUnSetBit (lBlock->ldefs, ic->key);
-             ivar = newCseDef (IC_RESULT (ic), ic);
-             applyToSet (theLoop->regBlocks, addDefInExprs, ivar, ebbi);
-             addSet (&lInvars, ivar);
-           }
-       }
-    }                          /* for all loop blocks */
+              remiCodeFromeBBlock (lBlock, ic);
+
+              /* maintain the data flow */
+              /* this means removing from definition from the */
+              /* defset of this block and adding it to the    */
+              /* inexpressions of all blocks within the loop  */
+              bitVectUnSetBit (lBlock->defSet, ic->key);
+              bitVectUnSetBit (lBlock->ldefs, ic->key);
+              ivar = newCseDef (IC_RESULT (ic), ic);
+              applyToSet (theLoop->regBlocks, addDefInExprs, ivar, ebbi);
+              addSet (&lInvars, ivar);
+            }
+        }
+    }                           /* for all loop blocks */
 
   /* if we have some invariants then */
   if (lInvars)
@@ -671,28 +686,29 @@ loopInvariants (region * theLoop, ebbIndex * ebbi)
 
       /* create an iCode chain from it */
       for (cdp = setFirstItem (lInvars); cdp; cdp = setNextItem (lInvars))
-       {
-
-         /* maintain data flow .. add it to the */
-         /* ldefs defSet & outExprs of the preheader  */
-         preHdr->defSet = bitVectSetBit (preHdr->defSet, cdp->diCode->key);
-         preHdr->ldefs = bitVectSetBit (preHdr->ldefs, cdp->diCode->key);
-         cdp->diCode->lineno = preHdr->ech->lineno;
-         addSetHead (&preHdr->outExprs, cdp);
-
-
-         if (!icFirst)
-           icFirst = cdp->diCode;
-         if (icLast)
-           {
-             icLast->next = cdp->diCode;
-             cdp->diCode->prev = icLast;
-             icLast = cdp->diCode;
-           }
-         else
-           icLast = cdp->diCode;
-         change++;
-       }
+        {
+
+          /* maintain data flow .. add it to the */
+          /* ldefs defSet & outExprs of the preheader  */
+          preHdr->defSet = bitVectSetBit (preHdr->defSet, cdp->diCode->key);
+          preHdr->ldefs = bitVectSetBit (preHdr->ldefs, cdp->diCode->key);
+          cdp->diCode->filename = preHdr->ech->filename;
+          cdp->diCode->lineno = preHdr->ech->lineno;
+          addSetHead (&preHdr->outExprs, cdp);
+
+
+          if (!icFirst)
+            icFirst = cdp->diCode;
+          if (icLast)
+            {
+              icLast->next = cdp->diCode;
+              cdp->diCode->prev = icLast;
+              icLast = cdp->diCode;
+            }
+          else
+            icLast = cdp->diCode;
+          change++;
+        }
 
       /* add the instruction chain to the end of the
          preheader for this loop, preheaders will always
@@ -721,11 +737,11 @@ addressTaken (set * sset, operand * sym)
       ebp = loop->item;
       loop2 = ebp->addrOf;
       while (loop2)
-       {
-         if (isOperandEqual ((operand *) loop2->item, sym))
-           return 1;
-         loop2 = loop2->next;
-       }
+        {
+          if (isOperandEqual ((operand *) loop2->item, sym))
+            return 1;
+          loop2 = loop2->next;
+        }
     }
 
   return 0;
@@ -766,18 +782,18 @@ findDefInRegion (set * regBlocks, operand * defOp, eBBlock ** owner)
 
       /* if a definition for this exists */
       if (bitVectBitsInCommon (lBlock->defSet, OP_DEFS (defOp)))
-       {
-         iCode *ic;
-
-         /* go thru the instruction chain to find it */
-         for (ic = lBlock->sch; ic; ic = ic->next)
-           if (bitVectBitValue (OP_DEFS (defOp), ic->key))
-             {
-               if (owner)
-                 *owner = lBlock;
-               return ic;
-             }
-       }
+        {
+          iCode *ic;
+
+          /* go thru the instruction chain to find it */
+          for (ic = lBlock->sch; ic; ic = ic->next)
+            if (bitVectBitValue (OP_DEFS (defOp), ic->key))
+              {
+                if (owner)
+                  *owner = lBlock;
+                return ic;
+              }
+        }
     }
 
   return NULL;
@@ -793,7 +809,7 @@ addPostLoopBlock (region *loopReg, ebbIndex *ebbi, iCode *ic)
   bitVect *loopSuccs;
   int i;
 
-  /* if the number of exits is greater than one then 
+  /* if the number of exits is greater than one then
      we use another trick: we will create an intersection
      of succesors of the exits, then take those that are not
      part of the loop and have dfNumber greater loop entry (eblock),
@@ -950,6 +966,8 @@ addPostLoopBlock (region *loopReg, ebbIndex *ebbi, iCode *ic)
 
       /* and add it */
       addiCodeToeBBlock (postLoopBlk, newic, NULL);
+      postLoopBlk->sch->filename =
+      postLoopBlk->ech->filename = eblock->sch->filename;
       postLoopBlk->sch->lineno =
       postLoopBlk->ech->lineno = eblock->sch->lineno;
 
@@ -982,17 +1000,17 @@ basicInduction (region * loopReg, ebbIndex * ebbi)
 
       /* for all instructions in the blocks do */
       for (ic = lBlock->sch; ic; ic = ic->next)
-       {
-
-         operand *aSym;
-         long litValue;
-         induction *ip;
-         iCode *indIc;
-         eBBlock *owner = NULL;
-         int nexits;
+        {
+
+          operand *aSym;
+          long litValue;
+          induction *ip;
+          iCode *indIc;
+          eBBlock *owner = NULL;
+          int nexits;
           sym_link *optype;
 
-         /* To find an induction variable, we need to */
+          /* To find an induction variable, we need to */
           /* find within the loop three iCodes in this */
           /* general form:                             */
           /*                                           */
@@ -1004,29 +1022,29 @@ basicInduction (region * loopReg, ebbIndex * ebbi)
           /*                                           */
           /* (symbolVar may also be an iTemp if it is  */
           /*  register equivalent)                     */
-          
+
           /* look for assignments of the form */
-         /*   symbolVar := iTempNN */
-         if (ic->op != '=')
-           continue;
+          /*   symbolVar := iTempNN */
+          if (ic->op != '=')
+            continue;
 
-         if (!IS_TRUE_SYMOP (IC_RESULT (ic)) &&
-             !OP_SYMBOL (IC_RESULT (ic))->isreqv)
-           continue;
+          if (!IS_TRUE_SYMOP (IC_RESULT (ic)) &&
+              !OP_SYMBOL (IC_RESULT (ic))->isreqv)
+            continue;
 
-         if (isOperandGlobal (IC_RESULT (ic)))
-           continue;
+          if (isOperandGlobal (IC_RESULT (ic)))
+            continue;
 
-         if (!IS_ITEMP (IC_RIGHT (ic)))
-           continue;
+          if (!IS_ITEMP (IC_RIGHT (ic)))
+            continue;
 
-         /* if it has multiple assignments within the loop then skip */
-         if (assignmentsToSym (loopReg->regBlocks, IC_RESULT (ic)) > 1)
-           continue;
+          /* if it has multiple assignments within the loop then skip */
+          if (assignmentsToSym (loopReg->regBlocks, IC_RESULT (ic)) > 1)
+            continue;
 
-         /* if the address of this was taken inside the loop then continue */
-         if (addressTaken (loopReg->regBlocks, IC_RESULT (ic)))
-           continue;
+          /* if the address of this was taken inside the loop then continue */
+          if (addressTaken (loopReg->regBlocks, IC_RESULT (ic)))
+            continue;
 
           /* Only consider variables with integral type. */
           /* (2004/12/06 - EEP - ds390 fails regression tests unless */
@@ -1037,24 +1055,24 @@ basicInduction (region * loopReg, ebbIndex * ebbi)
           if (!IS_INTEGRAL (optype) && !IS_PTR (optype))
             continue;
 
-         /* find the definition for the result in the block */
-         if (!(dic = findDefInRegion (setFromSet (loopReg->regBlocks),
-                                      IC_RIGHT (ic), &owner)))
-           continue;
-
-         /* if not +/- continue */
-         if (dic->op != '+' && dic->op != '-')
-           continue;
-         
-         /* make sure definition is of the form  a +/- c */
-         if (!IS_OP_LITERAL (IC_LEFT (dic)) && !IS_OP_LITERAL (IC_RIGHT (dic)))
-           continue;
-          
+          /* find the definition for the result in the block */
+          if (!(dic = findDefInRegion (setFromSet (loopReg->regBlocks),
+                                       IC_RIGHT (ic), &owner)))
+            continue;
+
+          /* if not +/- continue */
+          if (dic->op != '+' && dic->op != '-')
+            continue;
+
+          /* make sure definition is of the form  a +/- c */
+          if (!IS_OP_LITERAL (IC_LEFT (dic)) && !IS_OP_LITERAL (IC_RIGHT (dic)))
+            continue;
+
           /* make sure the definition found is the only one */
           if (assignmentsToSym (loopReg->regBlocks, IC_RIGHT (ic)) > 1)
-           continue;
+            continue;
 
-         if (IS_OP_LITERAL (IC_RIGHT (dic)))
+          if (IS_OP_LITERAL (IC_RIGHT (dic)))
             {
               aSym = IC_LEFT (dic);
               litValue = (long) operandLitValue (IC_RIGHT (dic));
@@ -1070,45 +1088,46 @@ basicInduction (region * loopReg, ebbIndex * ebbi)
               litValue = (long) operandLitValue (IC_LEFT (dic));
             }
 
-         if (!isOperandEqual (IC_RESULT (ic), aSym) &&
-             !isOperandEqual (IC_RIGHT (ic), aSym))
-           {
-             iCode *ddic;
-             /* find the definition for this and check */
-             if (!(ddic = findDefInRegion (setFromSet (loopReg->regBlocks),
-                                           aSym, &owner)))
-               continue;
-
-             if (ddic->op != '=')
-               continue;
-
-             if (!isOperandEqual (IC_RESULT (ddic), aSym) ||
-                 !isOperandEqual (IC_RIGHT (ddic), IC_RESULT (ic)))
-               continue;
-           }
-
-         /* if the right hand side has more than one usage then
-            don't make it an induction (will have to think some more) */
-         if (bitVectnBitsOn (OP_USES (IC_RIGHT (ic))) > 1)
-           continue;
-
-         /* if the definition is volatile then it cannot be
-            an induction object */
-         if (isOperandVolatile (IC_RIGHT (ic), FALSE) ||
-             isOperandVolatile (IC_RESULT (ic), FALSE))
-           continue;
-
-         /* whew !! that was a lot of work to find the definition */
-         /* create an induction object */
-         indIc = newiCode ('=', NULL, IC_RESULT (ic));
-         indIc->lineno = ic->lineno;
-         IC_RESULT (indIc) = operandFromOperand (IC_RIGHT (ic));
-         IC_RESULT (indIc)->isaddr = 0;
-         OP_SYMBOL (IC_RESULT (indIc))->isind = 1;
-         ip = newInduction (IC_RIGHT (ic), dic->op, litValue, indIc, NULL);
-
-         /* replace the inducted variable by the iTemp */
-         replaceSymBySym (loopReg->regBlocks, IC_RESULT (ic), IC_RIGHT (ic));
+          if (!isOperandEqual (IC_RESULT (ic), aSym) &&
+              !isOperandEqual (IC_RIGHT (ic), aSym))
+            {
+              iCode *ddic;
+              /* find the definition for this and check */
+              if (!(ddic = findDefInRegion (setFromSet (loopReg->regBlocks),
+                                            aSym, &owner)))
+                continue;
+
+              if (ddic->op != '=')
+                continue;
+
+              if (!isOperandEqual (IC_RESULT (ddic), aSym) ||
+                  !isOperandEqual (IC_RIGHT (ddic), IC_RESULT (ic)))
+                continue;
+            }
+
+          /* if the right hand side has more than one usage then
+             don't make it an induction (will have to think some more) */
+          if (bitVectnBitsOn (OP_USES (IC_RIGHT (ic))) > 1)
+            continue;
+
+          /* if the definition is volatile then it cannot be
+             an induction object */
+          if (isOperandVolatile (IC_RIGHT (ic), FALSE) ||
+              isOperandVolatile (IC_RESULT (ic), FALSE))
+            continue;
+
+          /* whew !! that was a lot of work to find the definition */
+          /* create an induction object */
+          indIc = newiCode ('=', NULL, IC_RESULT (ic));
+          indIc->filename = ic->filename;
+          indIc->lineno = ic->lineno;
+          IC_RESULT (indIc) = operandFromOperand (IC_RIGHT (ic));
+          IC_RESULT (indIc)->isaddr = 0;
+          OP_SYMBOL (IC_RESULT (indIc))->isind = 1;
+          ip = newInduction (IC_RIGHT (ic), dic->op, litValue, indIc, NULL);
+
+          /* replace the inducted variable by the iTemp */
+          replaceSymBySym (loopReg->regBlocks, IC_RESULT (ic), IC_RIGHT (ic));
           /* ic should now be moved to the exit block(s) */
 
           nexits = elementsInSet (loopReg->exits);
@@ -1166,32 +1185,32 @@ loopInduction (region * loopReg, ebbIndex * ebbi)
       /* last block is the one with the highest block
          number */
       if (lastBlock->bbnum < lBlock->bbnum)
-       lastBlock = lBlock;
+        lastBlock = lBlock;
 
       for (ic = lBlock->sch; ic; ic = ic->next)
-       {
-         operand *aSym;
-         long litVal;
+        {
+          operand *aSym;
+          long litVal;
 
-         /* consider only * & / */
-         if (ic->op != '*' && ic->op != '/')
-           continue;
+          /* consider only * & / */
+          if (ic->op != '*' && ic->op != '/')
+            continue;
 
           /* only consider variables with integral type */
           if (!IS_INTEGRAL (operandType (IC_RESULT (ic))))
             continue;
-         
+
           /* if the result has more definitions then */
-         if (assignmentsToSym (loopReg->regBlocks, IC_RESULT (ic)) > 1)
-           continue;
+          if (assignmentsToSym (loopReg->regBlocks, IC_RESULT (ic)) > 1)
+            continue;
 
-         /* check if the operands are what we want */
-         /* i.e. one of them an symbol the other a literal */
-         if (!((IS_SYMOP (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic))) ||
-               (IS_OP_LITERAL (IC_LEFT (ic)) && IS_SYMOP (IC_RIGHT (ic)))))
-           continue;
+          /* check if the operands are what we want */
+          /* i.e. one of them an symbol the other a literal */
+          if (!((IS_SYMOP (IC_LEFT (ic)) && IS_OP_LITERAL (IC_RIGHT (ic))) ||
+                (IS_OP_LITERAL (IC_LEFT (ic)) && IS_SYMOP (IC_RIGHT (ic)))))
+            continue;
 
-         if (IS_SYMOP (IC_LEFT (ic)))
+          if (IS_SYMOP (IC_LEFT (ic)))
             {
               aSym = IC_LEFT (ic);
               litVal = (long) operandLitValue (IC_RIGHT (ic));
@@ -1205,42 +1224,43 @@ loopInduction (region * loopReg, ebbIndex * ebbi)
               litVal = (long) operandLitValue (IC_LEFT (ic));
             }
 
-         ip = NULL;
-         /* check if this is an induction variable */
-         if (!applyToSetFTrue (basicInd, findInduction, aSym, &ip))
-           continue;
-
-         /* ask port for size not worth if native instruction
-            exist for multiply & divide */
-         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
-            for it to be inducted */
-         if (ic->op == '/' && (ip->cval % litVal))
-           continue;
-
-         /* create the iCode to be placed in the loop header */
-         /* and create the induction object */
-
-         /* create an instruction */
-         /* this will be put on the loop header */
-         indIc = newiCode (ic->op,
-                           operandFromOperand (aSym),
-                           operandFromLit (litVal));
-         indIc->lineno = ic->lineno;
-         IC_RESULT (indIc) = operandFromOperand (IC_RESULT (ic));
-         OP_SYMBOL (IC_RESULT (indIc))->isind = 1;
-
-         /* keep track of the inductions */
-         litVal = (ic->op == '*' ? (litVal * ip->cval) :
-                   (ip->cval / litVal));
-
-         addSet (&indVars,
-               newInduction (IC_RESULT (ic), ip->op, litVal, indIc, NULL));
-
-         /* Replace mul/div with assignment to self; killDeadCode() will */
+          ip = NULL;
+          /* check if this is an induction variable */
+          if (!applyToSetFTrue (basicInd, findInduction, aSym, &ip))
+            continue;
+
+          /* ask port for size not worth if native instruction
+             exist for multiply & divide */
+          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
+             for it to be inducted */
+          if (ic->op == '/' && (ip->cval % litVal))
+            continue;
+
+          /* create the iCode to be placed in the loop header */
+          /* and create the induction object */
+
+          /* create an instruction */
+          /* this will be put on the loop header */
+          indIc = newiCode (ic->op,
+                            operandFromOperand (aSym),
+                            operandFromLit (litVal));
+          indIc->filename = ic->filename;
+          indIc->lineno = ic->lineno;
+          IC_RESULT (indIc) = operandFromOperand (IC_RESULT (ic));
+          OP_SYMBOL (IC_RESULT (indIc))->isind = 1;
+
+          /* keep track of the inductions */
+          litVal = (ic->op == '*' ? (litVal * ip->cval) :
+                    (ip->cval / litVal));
+
+          addSet (&indVars,
+                newInduction (IC_RESULT (ic), ip->op, litVal, indIc, NULL));
+
+          /* Replace mul/div with assignment to self; killDeadCode() will */
           /* clean this up since we can't use remiCodeFromeBBlock() here. */
           ic->op = '=';
           IC_LEFT (ic) = NULL;
@@ -1252,12 +1272,12 @@ loopInduction (region * loopReg, ebbIndex * ebbi)
                             operandFromOperand (IC_RESULT (ic)),
                             operandFromLit (litVal));
           IC_RESULT (indIc) = operandFromOperand (IC_RESULT (ic));
-         owner = NULL;
+          owner = NULL;
           dic = findDefInRegion (setFromSet (loopReg->regBlocks), aSym, &owner);
           assert (dic);
-         addiCodeToeBBlock (owner, indIc, dic);
+          addiCodeToeBBlock (owner, indIc, dic);
 
-       }
+        }
     }
 
   /* if we have some induction variables then */
@@ -1270,23 +1290,24 @@ loopInduction (region * loopReg, ebbIndex * ebbi)
 
       /* create an iCode chain from it */
       for (ip = setFirstItem (indVars);
-          ip;
-          ip = setNextItem (indVars))
-       {
-         indVect = bitVectSetBit (indVect, ip->ic->key);
-         ip->ic->lineno = preHdr->ech->lineno;
-         if (!icFirst)
-           icFirst = ip->ic;
-         if (icLast)
-           {
-             icLast->next = ip->ic;
-             ip->ic->prev = icLast;
-             icLast = ip->ic;
-           }
-         else
-           icLast = ip->ic;
-         change++;
-       }
+           ip;
+           ip = setNextItem (indVars))
+        {
+          indVect = bitVectSetBit (indVect, ip->ic->key);
+          ip->ic->filename = preHdr->ech->filename;
+          ip->ic->lineno = preHdr->ech->lineno;
+          if (!icFirst)
+            icFirst = ip->ic;
+          if (icLast)
+            {
+              icLast->next = ip->ic;
+              ip->ic->prev = icLast;
+              icLast = ip->ic;
+            }
+          else
+            icLast = ip->ic;
+          change++;
+        }
 
       /* add the instruction chain to the end of the */
       /* preheader for this loop                     */
@@ -1325,14 +1346,14 @@ DEFSETFUNC (mergeRegions)
     {
 
       if (lp == theLoop)
-       continue;
+        continue;
 
       if (lp->entry == theLoop->entry)
-       {
-         theLoop->regBlocks = unionSets (theLoop->regBlocks,
-                                         lp->regBlocks, THROW_DEST);
-         lp->merged = 1;
-       }
+        {
+          theLoop->regBlocks = unionSets (theLoop->regBlocks,
+                                          lp->regBlocks, THROW_DEST);
+          lp->merged = 1;
+        }
     }
 
   return 1;
@@ -1366,17 +1387,17 @@ DEFSETFUNC (mergeInnerLoops)
     {
 
       if (lp == theLoop)
-       continue;
+        continue;
 
       if (isinSet (lp->regBlocks, theLoop->entry))
-       {
-         lp->containsLoops += theLoop->containsLoops + 1;
-         if (lp->containsLoops > (*maxDepth))
-           *maxDepth = lp->containsLoops;
-
-         lp->regBlocks = unionSets (lp->regBlocks,
-                                    theLoop->regBlocks, THROW_DEST);
-       }
+        {
+          lp->containsLoops += theLoop->containsLoops + 1;
+          if (lp->containsLoops > (*maxDepth))
+            *maxDepth = lp->containsLoops;
+
+          lp->regBlocks = unionSets (lp->regBlocks,
+                                     theLoop->regBlocks, THROW_DEST);
+        }
     }
 
   return 1;
@@ -1389,7 +1410,7 @@ DEFSETFUNC (mergeInnerLoops)
 hTab *
 createLoopRegions (ebbIndex * ebbi)
 {
-  set *allRegion = NULL;       /* set of all loops */
+  set *allRegion = NULL;        /* set of all loops */
   hTab *orderedLoops = NULL;
   set *bEdges = NULL;
   int maxDepth = 0;
@@ -1397,7 +1418,7 @@ createLoopRegions (ebbIndex * ebbi)
 
   /* get all the back edges in the graph */
   if (!applyToSet (graphEdges, backEdges, &bEdges))
-    return 0;                  /* found no loops */
+    return 0;                   /* found no loops */
 
   /* for each of these back edges get the blocks that */
   /* constitute the loops                             */
@@ -1422,8 +1443,8 @@ createLoopRegions (ebbIndex * ebbi)
   for (lp = setFirstItem (allRegion); lp; lp = setNextItem (allRegion))
     {
       applyToSet (lp->regBlocks, addToExitsMarkDepth,
-                 lp->regBlocks, &lp->exits,
-                 (maxDepth - lp->containsLoops), lp);
+                  lp->regBlocks, &lp->exits,
+                  (maxDepth - lp->containsLoops), lp);
 
       hTabAddItem (&orderedLoops, lp->containsLoops, lp);
 
@@ -1455,10 +1476,10 @@ loopOptimizations (hTab * orderedLoops, ebbIndex * ebbi)
     {
 
       if (optimize.loopInvariant)
-       change += loopInvariants (lp, ebbi);
+        change += loopInvariants (lp, ebbi);
 
       if (optimize.loopInduction)
-       change += loopInduction (lp, ebbi);
+        change += loopInduction (lp, ebbi);
     }
 
   return change;