* device/include/pic16/pic18f*.h: add bit aliases in INTCONbits_t
[fw/sdcc] / src / SDCCBBlock.c
index d1f1ebef447ccde2645340818449e73dd16f8b95..e7f0fe9e7cdc9c55b539d5a04f966389ee027a7f 100644 (file)
@@ -26,7 +26,7 @@
 #include "common.h"
 
 int eBBNum = 0;
-set *graphEdges = NULL;                /* list of edges in this flow graph */
+set *graphEdges = NULL;         /* list of edges in this flow graph */
 
 struct _dumpFiles dumpFiles[] = {
   {DUMP_RAW0, ".dumpraw0", NULL},
@@ -84,10 +84,12 @@ newEdge (eBBlock * from, eBBlock * to)
 }
 
 /*-----------------------------------------------------------------*/
-/* appendDumpFile - if not already created, create the dump file   */
+/* createDumpFile - create the dump file                           */
 /*-----------------------------------------------------------------*/
-FILE *appendDumpFile (int id) {
+FILE *createDumpFile (int id) {
   struct _dumpFiles *dumpFilesPtr=dumpFiles;
+  static int dumpIndex=0;
+  static char dumpIndexStr[32];
 
   while (dumpFilesPtr->id) {
     if (dumpFilesPtr->id==id)
@@ -96,19 +98,30 @@ FILE *appendDumpFile (int id) {
   }
 
   if (!dumpFilesPtr->id) {
-    fprintf (stdout, "internal error: appendDumpFile: unknown dump file.\n");
+    fprintf (stdout, "internal error: createDumpFile: unknown dump file.\n");
     exit (1);
   }
 
+  sprintf(dumpIndexStr, ".%d", dumpIndex);
+  dumpIndex++;
+
   if (!dumpFilesPtr->filePtr) {
     // not used before, create it
     strncpyz (scratchFileName, dstFileName, PATH_MAX);
+#if 0
+    strncatz (scratchFileName, dumpIndexStr, PATH_MAX);
+#endif
     strncatz (scratchFileName, dumpFilesPtr->ext, PATH_MAX);
     if (!(dumpFilesPtr->filePtr = fopen (scratchFileName, "w"))) {
       werror (E_FILE_OPEN_ERR, scratchFileName);
       exit (1);
     }
-  } 
+  }
+
+#if 0
+  fprintf(dumpFilesPtr->filePtr, "Dump file index: %d\n", dumpIndex);
+#endif
+
   return dumpFilesPtr->filePtr;
 }
 
@@ -121,7 +134,6 @@ void closeDumpFiles() {
   for (dumpFilesPtr=dumpFiles; dumpFilesPtr->id; dumpFilesPtr++) {
     if (dumpFilesPtr->filePtr) {
       fclose (dumpFilesPtr->filePtr);
-      //dprintf ("closed %s\n", dumpFilesPtr->ext);
     }
   }
 }
@@ -129,7 +141,7 @@ void closeDumpFiles() {
 /*-----------------------------------------------------------------*/
 /* dumpLiveRanges - dump liverange information into a file         */
 /*-----------------------------------------------------------------*/
-void 
+void
 dumpLiveRanges (int id, hTab * liveRanges)
 {
   FILE *file;
@@ -137,31 +149,31 @@ dumpLiveRanges (int id, hTab * liveRanges)
   int k;
 
   if (id) {
-    file=appendDumpFile(id);
+    file=createDumpFile(id);
   } else {
     file = stdout;
   }
-  
-  if (currFunc) 
+
+  if (currFunc)
       fprintf(file,"------------- Func %s -------------\n",currFunc->name);
   for (sym = hTabFirstItem (liveRanges, &k); sym;
        sym = hTabNextItem (liveRanges, &k))
     {
 
       fprintf (file, "%s [k%d lr%d:%d so:%d]{ re%d rm%d}",
-              (sym->rname[0] ? sym->rname : sym->name),
-              sym->key,
-              sym->liveFrom, sym->liveTo,
-              sym->stack,
-              sym->isreqv, sym->remat
-       );
+               (sym->rname[0] ? sym->rname : sym->name),
+               sym->key,
+               sym->liveFrom, sym->liveTo,
+               sym->stack,
+               sym->isreqv, sym->remat
+        );
 
       fprintf (file, "{");
       printTypeChain (sym->type, file);
       if (sym->usl.spillLoc)
-       {
-         fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname);
-       }
+        {
+          fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname);
+        }
       fprintf (file, "} clashes with ");
       bitVectDebugOn(sym->clashes,file);
       fprintf (file, "\n");
@@ -170,17 +182,22 @@ dumpLiveRanges (int id, hTab * liveRanges)
   fflush(file);
 }
 
+
 /*-----------------------------------------------------------------*/
 /* dumpEbbsToFileExt - writeall the basic blocks to a file         */
 /*-----------------------------------------------------------------*/
-void 
-dumpEbbsToFileExt (int id, eBBlock ** ebbs, int count)
+void
+dumpEbbsToFileExt (int id, ebbIndex * ebbi)
 {
   FILE *of;
   int i;
+  eBBlock *bb;
+  set *cseSet;
+  eBBlock ** ebbs = ebbi->dfOrder ? ebbi->dfOrder : ebbi->bbOrder;
+  int count = ebbi->count;
 
   if (id) {
-    of=appendDumpFile(id);
+    of=createDumpFile(id);
   } else {
     of = stdout;
   }
@@ -188,21 +205,80 @@ dumpEbbsToFileExt (int id, eBBlock ** ebbs, int count)
   for (i = 0; i < count; i++)
     {
       fprintf (of, "\n----------------------------------------------------------------\n");
-      fprintf (of, "Basic Block %s : loop Depth = %d noPath = %d , lastinLoop = %d\n",
-              ebbs[i]->entryLabel->name,
-              ebbs[i]->depth,
-              ebbs[i]->noPath,
-              ebbs[i]->isLastInLoop);
+      fprintf (of, "Basic Block %s (df:%d bb:%d lvl:%d): loopDepth=%d%s%s%s\n",
+               ebbs[i]->entryLabel->name,
+               ebbs[i]->dfnum, ebbs[i]->bbnum, ebbs[i]->entryLabel->level,
+               ebbs[i]->depth,
+               ebbs[i]->noPath ? " noPath" : "",
+               ebbs[i]->partOfLoop ? " partOfLoop" : "",
+               ebbs[i]->isLastInLoop ? " isLastInLoop" : "");
+
+      // a --nolabelopt makes this more readable
+      fprintf (of, "\nsuccessors: ");
+      for (bb=setFirstItem(ebbs[i]->succList);
+           bb;
+           bb=setNextItem(ebbs[i]->succList)) {
+        fprintf (of, "%s ", bb->entryLabel->name);
+      }
+      fprintf (of, "\npredecessors: ");
+      for (bb=setFirstItem(ebbs[i]->predList);
+           bb;
+           bb=setNextItem(ebbs[i]->predList)) {
+        fprintf (of, "%s ", bb->entryLabel->name);
+      }
+      {
+        int d;
+        fprintf (of, "\ndominators: ");
+        for (d=0; d<ebbs[i]->domVect->size; d++) {
+          if (bitVectBitValue(ebbs[i]->domVect, d)) {
+            fprintf (of, "%s ", ebbi->bbOrder[d]->entryLabel->name); //ebbs[d]->entryLabel->name);
+          }
+        }
+      }
+      fprintf (of, "\n");
+
       fprintf (of, "\ndefines bitVector :");
       bitVectDebugOn (ebbs[i]->defSet, of);
       fprintf (of, "\nlocal defines bitVector :");
       bitVectDebugOn (ebbs[i]->ldefs, of);
       fprintf (of, "\npointers Set bitvector :");
       bitVectDebugOn (ebbs[i]->ptrsSet, of);
+#if 0
+      fprintf (of, "\nin coming definitions :");
+      bitVectDebugOn (ebbs[i]->inDefs, of);
+      fprintf (of, "\nout going definitions :");
+      bitVectDebugOn (ebbs[i]->outDefs, of);
+      fprintf (of, "\ndefines used :");
+      bitVectDebugOn (ebbs[i]->usesDefs, of);
+#endif
+
       if (ebbs[i]->isLastInLoop) {
-             fprintf (of, "\nInductions Set bitvector :");
-             bitVectDebugOn (ebbs[i]->linds, of);
+              fprintf (of, "\nInductions Set bitvector :");
+              bitVectDebugOn (ebbs[i]->linds, of);
       }
+
+      fprintf (of, "\ninExprs:");
+      for (cseSet = ebbs[i]->inExprs; cseSet; cseSet=cseSet->next) {
+        cseDef *item=cseSet->item;
+        fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
+        if (item->fromGlobal)
+          fprintf (of, "g");
+      }
+      fprintf (of, "\noutExprs:");
+      for (cseSet = ebbs[i]->outExprs; cseSet; cseSet=cseSet->next) {
+        cseDef *item=cseSet->item;
+        fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
+        if (item->fromGlobal)
+          fprintf (of, "g");
+      }
+      fprintf (of, "\nkilledExprs:");
+      for (cseSet = ebbs[i]->killedExprs; cseSet; cseSet=cseSet->next) {
+        cseDef *item=cseSet->item;
+        fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
+        if (item->fromGlobal)
+          fprintf (of, "g");
+      }
+
       fprintf (of, "\n----------------------------------------------------------------\n");
       printiCChain (ebbs[i]->sch, of);
     }
@@ -216,17 +292,17 @@ eBBlock *
 iCode2eBBlock (iCode * ic)
 {
   iCode *loop;
-  eBBlock *ebb = neweBBlock ();        /* a llocate an entry */
+  eBBlock *ebb = neweBBlock (); /* allocate an entry */
 
   /* put the first one unconditionally */
   ebb->sch = ic;
 
   /* if this is a label then */
   if (ic->op == LABEL)
-    ebb->entryLabel = ic->argLabel.label;
+    ebb->entryLabel = ic->label;
   else
     {
-      sprintf (buffer, "_eBBlock%d", eBBNum++);
+      SNPRINTF (buffer, sizeof(buffer), "_eBBlock%d", eBBNum++);
       ebb->entryLabel = newSymbol (buffer, 1);
       ebb->entryLabel->key = labelKey++;
     }
@@ -240,6 +316,14 @@ iCode2eBBlock (iCode * ic)
       return ebb;
     }
 
+  /* if this is a function call */
+  if (ic->op == CALL || ic->op == PCALL)
+    {
+      ebb->hasFcall = 1;
+      if (currFunc)
+        FUNC_HASFCALL(currFunc->type) = 1;
+    }
+
   if ((ic->next && ic->next->op == LABEL) ||
       !ic->next)
     {
@@ -253,22 +337,22 @@ iCode2eBBlock (iCode * ic)
 
       /* if this is the last one */
       if (!loop->next)
-       break;
+        break;
       /* if this is a function call */
       if (loop->op == CALL || loop->op == PCALL)
-       {
-         ebb->hasFcall = 1;
-         if (currFunc)
-           FUNC_HASFCALL(currFunc->type) = 1;
-       }
+        {
+          ebb->hasFcall = 1;
+          if (currFunc)
+            FUNC_HASFCALL(currFunc->type) = 1;
+        }
 
       /* if the next one is a label */
       /* if this is a goto or ifx */
       if (loop->next->op == LABEL ||
-         loop->op == GOTO ||
-         loop->op == JUMPTABLE ||
-         loop->op == IFX)
-       break;
+          loop->op == GOTO ||
+          loop->op == JUMPTABLE ||
+          loop->op == IFX)
+        break;
     }
 
   /* mark the end of the chain */
@@ -281,14 +365,16 @@ iCode2eBBlock (iCode * ic)
 /* eBBWithEntryLabel - finds the basic block with the entry label  */
 /*-----------------------------------------------------------------*/
 eBBlock *
-eBBWithEntryLabel (eBBlock ** ebbs, symbol * eLabel, int count)
+eBBWithEntryLabel (ebbIndex * ebbi, symbol * eLabel)
 {
+  eBBlock ** ebbs = ebbi->bbOrder;
+  int count = ebbi->count;
   int i;
 
   for (i = 0; i < count; i++)
     {
       if (isSymbolEqual (ebbs[i]->entryLabel, eLabel))
-       return ebbs[i];
+        return ebbs[i];
     }
 
   return NULL;
@@ -330,21 +416,22 @@ edgesTo (eBBlock * to)
 /*-----------------------------------------------------------------*/
 /* addiCodeToeBBlock - will add an iCode to the end of a block     */
 /*-----------------------------------------------------------------*/
-void 
+void
 addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip)
 {
   ic->prev = ic->next = NULL;
   /* if the insert point is given */
   if (ip)
     {
+      ic->filename = ip->filename;
       ic->lineno = ip->lineno;
       ic->prev = ip->prev;
       ip->prev = ic;
       ic->next = ip;
       if (!ic->prev)
-       ebp->sch = ic;
+        ebp->sch = ic;
       else
-       ic->prev->next = ic;
+        ic->prev->next = ic;
       return;
     }
 
@@ -361,14 +448,15 @@ addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip)
   if (ebp->ech->op == GOTO || ebp->ech->op == JUMPTABLE
       || ebp->ech->op == RETURN)
     {
+      ic->filename = ebp->ech->filename;
       ic->lineno = ebp->ech->lineno;
       ic->prev = ebp->ech->prev;
       ebp->ech->prev = ic;
       ic->next = ebp->ech;
-      if (!ic->prev)           /* was the last only on in the block */
-       ebp->sch = ic;
+      if (!ic->prev)            /* was the last only on in the block */
+        ebp->sch = ic;
       else
-       ic->prev->next = ic;
+        ic->prev->next = ic;
       return;
     }
 
@@ -377,7 +465,10 @@ addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip)
   /* if this is true then we put it before the condition else */
   /* we put it before if, this is to reduce register pressure, */
   /* we don't have to hold  condition too long in a register  */
-  if (ebp->ech->op == IFX)
+
+  /* loop induction sometimes appends a GOTO instruction, */
+  /* it must be at the very end */
+  if (ebp->ech->op == IFX && ic->op != GOTO)
     {
       iCode *ipoint;
 
@@ -392,14 +483,15 @@ addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip)
 /*    else */
 /*        ipoint = ebp->ech ; */
       ipoint = ebp->ech;
+      ic->filename = ipoint->filename;
       ic->lineno = ipoint->lineno;
       ic->prev = ipoint->prev;
       ipoint->prev = ic;
       ic->next = ipoint;
       if (!ic->prev)
-       ebp->sch = ic;
+        ebp->sch = ic;
       else
-       ic->prev->next = ic;
+        ic->prev->next = ic;
       return;
     }
 
@@ -416,7 +508,7 @@ addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip)
 /*-----------------------------------------------------------------*/
 /* remiCodeFromeBBlock - remove an iCode from BBlock               */
 /*-----------------------------------------------------------------*/
-void 
+void
 remiCodeFromeBBlock (eBBlock * ebb, iCode * ic)
 {
   wassert (ic->seq>=ebb->fSeq && ic->seq<=ebb->lSeq);
@@ -434,17 +526,21 @@ remiCodeFromeBBlock (eBBlock * ebb, iCode * ic)
 /*-----------------------------------------------------------------*/
 /* iCodeBreakDown : breakDown iCode chain to blocks                */
 /*-----------------------------------------------------------------*/
-eBBlock **
-iCodeBreakDown (iCode * ic, int *count)
+ebbIndex *
+iCodeBreakDown (iCode * ic)
 {
   eBBlock **ebbs = NULL;
   iCode *loop = ic;
+  ebbIndex *ebbi;
 
-  *count = 0;
+  ebbi = Safe_alloc (sizeof (ebbIndex));
+  ebbi->count = 0;
+  ebbi->dfOrder = NULL; /* no depth first order information yet */
 
   /* allocate for the first entry */
 
-  ebbs = Safe_alloc (sizeof (eBBlock **));
+  ebbs = Safe_alloc (sizeof (eBBlock *));
+  ebbi->bbOrder = ebbs;
 
   while (loop)
     {
@@ -453,96 +549,99 @@ iCodeBreakDown (iCode * ic, int *count)
       eBBlock *ebb = iCode2eBBlock (loop);
       loop = ebb->ech->next;
 
-      ebb->ech->next = NULL;   /* mark the end of this chain */
+      ebb->ech->next = NULL;    /* mark the end of this chain */
       if (loop)
-       loop->prev = NULL;
-      ebb->bbnum = *count;     /* save this block number     */
+        loop->prev = NULL;
+      ebb->bbnum = ebbi->count; /* save this block number     */
       /* put it in the array */
-      ebbs[(*count)++] = ebb;
+      ebbs[(ebbi->count)++] = ebb;
 
       /* allocate for the next one. Remember to clear the new */
       /*  pointer at the end, that was created by realloc. */
 
-      ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **));
+      ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *));
+      ebbi->bbOrder = ebbs;
 
-      ebbs[*count] = 0;
+      ebbs[ebbi->count] = 0;
 
       /* if this one ends in a goto or a conditional */
       /* branch then check if the block it is going  */
       /* to already exists, if yes then this could   */
       /* be a loop, add a preheader to the block it  */
       /* goes to  if it does not already have one    */
-      if (ebbs[(*count) - 1]->ech &&
-         (ebbs[(*count) - 1]->ech->op == GOTO ||
-          ebbs[(*count) - 1]->ech->op == IFX))
-       {
-
-         symbol *label;
-         eBBlock *destBlock;
-
-         if (ebbs[(*count) - 1]->ech->op == GOTO)
-           label = IC_LABEL (ebbs[(*count) - 1]->ech);
-         else if (!(label = IC_TRUE (ebbs[(*count) - 1]->ech)))
-           label = IC_FALSE (ebbs[(*count) - 1]->ech);
-
-         if ((destBlock = eBBWithEntryLabel (ebbs, label, (*count))) &&
-             destBlock->preHeader == NULL &&
-             otherPathsPresent (ebbs, destBlock))
-           {
-
-             symbol *preHeaderLabel = newiTempPreheaderLabel ();
-             int i, j;
-             eBBlock *pBlock;
-
-             /* go thru all block replacing the entryLabel with new label */
-             /* till we reach the block , then we insert a new ebblock    */
-             for (i = 0; i < (*count); i++)
-               {
-                 if (ebbs[i] == destBlock)
-                   break;
-                 replaceLabel (ebbs[i], label, preHeaderLabel);
-               }
-
-             (*count)++;
-
-             /* if we have stopped at the block , allocate for an extra one */
-
-             ebbs = Safe_realloc (ebbs, (*count + 1) * sizeof (eBBlock **));
-
-             ebbs[*count] = 0;
-
-             /* then move the block down one count */
-             pBlock = ebbs[j = i];
-             for (i += 1; i < (*count); i++)
-               {
-                 eBBlock *xBlock;
-
-                 xBlock = ebbs[i];
-                 ebbs[i] = pBlock;
-                 ebbs[i]->bbnum = i;
-                 pBlock = xBlock;
-               }
-
-             destBlock->preHeader = ebbs[j] = neweBBlock ();
-             ebbs[j]->bbnum = j;
-             ebbs[j]->entryLabel = preHeaderLabel;
-             ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel);
-             ebbs[j]->sch->lineno = destBlock->sch->lineno;
-           }
-       }
+      if (ebbs[(ebbi->count) - 1]->ech &&
+          (ebbs[(ebbi->count) - 1]->ech->op == GOTO ||
+           ebbs[(ebbi->count) - 1]->ech->op == IFX))
+        {
+
+          symbol *label;
+          eBBlock *destBlock;
+
+          if (ebbs[(ebbi->count) - 1]->ech->op == GOTO)
+            label = IC_LABEL (ebbs[(ebbi->count) - 1]->ech);
+          else if (!(label = IC_TRUE (ebbs[(ebbi->count) - 1]->ech)))
+            label = IC_FALSE (ebbs[(ebbi->count) - 1]->ech);
+
+          if ((destBlock = eBBWithEntryLabel (ebbi, label)) &&
+              destBlock->preHeader == NULL &&
+              otherPathsPresent (ebbs, destBlock))
+            {
+
+              symbol *preHeaderLabel  = newiTempLoopHeaderLabel (1);
+              int i, j;
+              eBBlock *pBlock;
+
+              /* go thru all block replacing the entryLabel with new label */
+              /* till we reach the block , then we insert a new ebblock    */
+              for (i = 0; i < (ebbi->count); i++)
+                {
+                  if (ebbs[i] == destBlock)
+                    break;
+                  replaceLabel (ebbs[i], label, preHeaderLabel);
+                }
+
+              (ebbi->count)++;
+
+              /* if we have stopped at the block , allocate for an extra one */
+
+              ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *));
+              ebbi->bbOrder = ebbs;
+
+              ebbs[ebbi->count] = 0;
+
+              /* then move the block down one count */
+              pBlock = ebbs[j = i];
+              for (i += 1; i < (ebbi->count); i++)
+                {
+                  eBBlock *xBlock;
+
+                  xBlock = ebbs[i];
+                  ebbs[i] = pBlock;
+                  ebbs[i]->bbnum = i;
+                  pBlock = xBlock;
+                }
+
+              destBlock->preHeader = ebbs[j] = neweBBlock ();
+              ebbs[j]->bbnum = j;
+              ebbs[j]->entryLabel = preHeaderLabel;
+              ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel);
+              ebbs[j]->sch->filename = destBlock->sch->filename;
+              ebbs[j]->sch->lineno = destBlock->sch->lineno;
+            }
+        }
     }
 
   /* mark the end */
-  ebbs[*count] = NULL;
+  ebbs[ebbi->count] = NULL;
 
-  return ebbs;
+  return ebbi;
 }
 
 /*-----------------------------------------------------------------*/
 /* replaceSymBySym : - replace operand by operand in blocks        */
 /*                     replaces only left & right in blocks        */
 /*-----------------------------------------------------------------*/
-void 
+void
 replaceSymBySym (set * sset, operand * src, operand * dest)
 {
   set *loop;
@@ -556,58 +655,58 @@ replaceSymBySym (set * sset, operand * src, operand * dest)
       rBlock = loop->item;
       /* for all instructions in this block do */
       for (ic = rBlock->sch; ic; ic = ic->next)
-       {
-
-         /* if we find usage */
-         if (ic->op == IFX && isOperandEqual (src, IC_COND (ic)))
-           {
-             bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
-             IC_COND (ic) = operandFromOperand (dest);
-             OP_USES_SET ((dest), bitVectSetBit (OP_USES (dest), ic->key));
-             continue;
-           }
-
-         if (isOperandEqual (IC_RIGHT (ic), src))
-           {
-             bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
-             IC_RIGHT (ic) = operandFromOperand (dest);
-             IC_RIGHT (ic)->isaddr = 0;
-             OP_USES_SET ((dest), bitVectSetBit (OP_USES (dest), ic->key));
-           }
-
-         if (isOperandEqual (IC_LEFT (ic), src))
-           {
-             bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
-             if (POINTER_GET (ic) && IS_ITEMP (dest))
-               {
-                 IC_LEFT (ic) = operandFromOperand (dest);
-                 IC_LEFT (ic)->isaddr = 1;
-               }
-             else
-               {
-                 IC_LEFT (ic) = operandFromOperand (dest);
-                 IC_LEFT (ic)->isaddr = 0;
-               }
-             OP_USES_SET ((dest), bitVectSetBit (OP_USES (dest), ic->key));
-           }
-
-         /* special case for pointer sets */
-         if (POINTER_SET (ic) &&
-             isOperandEqual (IC_RESULT (ic), src))
-           {
-             bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
-             IC_RESULT (ic) = operandFromOperand (dest);
-             IC_RESULT (ic)->isaddr = 1;
-             OP_USES_SET ((dest), bitVectSetBit (OP_USES (dest), ic->key));
-           }
-       }
+        {
+
+          /* if we find usage */
+          if (ic->op == IFX && isOperandEqual (src, IC_COND (ic)))
+            {
+              bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
+              IC_COND (ic) = operandFromOperand (dest);
+              OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
+              continue;
+            }
+
+          if (isOperandEqual (IC_RIGHT (ic), src))
+            {
+              bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+              IC_RIGHT (ic) = operandFromOperand (dest);
+              IC_RIGHT (ic)->isaddr = 0;
+              OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
+            }
+
+          if (isOperandEqual (IC_LEFT (ic), src))
+            {
+              bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+              if (POINTER_GET (ic) && IS_ITEMP (dest))
+                {
+                  IC_LEFT (ic) = operandFromOperand (dest);
+                  IC_LEFT (ic)->isaddr = 1;
+                }
+              else
+                {
+                  IC_LEFT (ic) = operandFromOperand (dest);
+                  IC_LEFT (ic)->isaddr = 0;
+                }
+              OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
+            }
+
+          /* special case for pointer sets */
+          if (POINTER_SET (ic) &&
+              isOperandEqual (IC_RESULT (ic), src))
+            {
+              bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
+              IC_RESULT (ic) = operandFromOperand (dest);
+              IC_RESULT (ic)->isaddr = 1;
+              OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
+            }
+        }
     }
 }
 
 /*-----------------------------------------------------------------*/
 /* replaceLabel - replace reference to one label by another        */
 /*-----------------------------------------------------------------*/
-void 
+void
 replaceLabel (eBBlock * ebp, symbol * fromLbl, symbol * toLbl)
 {
   iCode *ic;
@@ -618,20 +717,20 @@ replaceLabel (eBBlock * ebp, symbol * fromLbl, symbol * toLbl)
   for (ic = ebp->sch; ic; ic = ic->next)
     {
       switch (ic->op)
-       {
-
-       case GOTO:
-         if (isSymbolEqual (IC_LABEL (ic), fromLbl))
-           IC_LABEL (ic) = toLbl;
-         break;
-
-       case IFX:
-         if (IC_TRUE (ic) && isSymbolEqual (IC_TRUE (ic), fromLbl))
-           IC_TRUE (ic) = toLbl;
-         else if (isSymbolEqual (IC_FALSE (ic), fromLbl))
-           IC_FALSE (ic) = toLbl;
-         break;
-       }
+        {
+
+        case GOTO:
+          if (isSymbolEqual (IC_LABEL (ic), fromLbl))
+            IC_LABEL (ic) = toLbl;
+          break;
+
+        case IFX:
+          if (IC_TRUE (ic) && isSymbolEqual (IC_TRUE (ic), fromLbl))
+            IC_TRUE (ic) = toLbl;
+          else if (isSymbolEqual (IC_FALSE (ic), fromLbl))
+            IC_FALSE (ic) = toLbl;
+          break;
+        }
     }
 
   return;
@@ -652,19 +751,38 @@ iCodeFromeBBlock (eBBlock ** ebbs, int count)
   for (; i < count; i++)
     {
       if (ebbs[i]->sch == NULL)
-       continue;
+        continue;
 
       if (ebbs[i]->noPath &&
-         (ebbs[i]->entryLabel != entryLabel &&
-          ebbs[i]->entryLabel != returnLabel))
-       {
-         werror (W_CODE_UNREACH, ebbs[i]->sch->filename, ebbs[i]->sch->lineno);
-         continue;
-       }
+          (ebbs[i]->entryLabel != entryLabel &&
+           ebbs[i]->entryLabel != returnLabel))
+        {
+          iCode *ic = NULL;
+          bool foundNonlabel = 0;
+          ic=ebbs[i]->sch;
+          do
+            {
+              if (ic->op != LABEL)
+                {
+                  foundNonlabel = 1;
+                  break;
+                }
+              if (ic==ebbs[i]->ech)
+                break;
+              ic = ic->next;
+            }
+          while (ic);
+          if (foundNonlabel && ic)
+            {
+              werrorfl (ic->filename, ic->lineno, W_CODE_UNREACH);
+              continue;
+            }
+        }
 
       lic->next = ebbs[i]->sch;
       lic->next->prev = lic;
       lic = ebbs[i]->ech;
+
     }
 
   return ric;
@@ -674,7 +792,7 @@ iCodeFromeBBlock (eBBlock ** ebbs, int count)
 /* otherPathsPresent - determines if there is a path from _entry   */
 /*      to this block in a half constructed set of blocks          */
 /*-----------------------------------------------------------------*/
-int 
+int
 otherPathsPresent (eBBlock ** ebbs, eBBlock * this)
 {
   int i;
@@ -686,25 +804,25 @@ otherPathsPresent (eBBlock ** ebbs, eBBlock * this)
 
       /* if there is a reference to the entry label of this block */
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
-       {
-         switch (ic->op)
-           {
-           case GOTO:
-             if (IC_LABEL (ic)->key == this->entryLabel->key)
-               return 1;
-             break;
-
-           case IFX:
-             if (IC_TRUE (ic))
-               {
-                 if (IC_TRUE (ic)->key == this->entryLabel->key)
-                   return 1;
-               }
-             else if (IC_FALSE (ic)->key == this->entryLabel->key)
-               return 1;
-             break;
-           }
-       }
+        {
+          switch (ic->op)
+            {
+            case GOTO:
+              if (IC_LABEL (ic)->key == this->entryLabel->key)
+                return 1;
+              break;
+
+            case IFX:
+              if (IC_TRUE (ic))
+                {
+                  if (IC_TRUE (ic)->key == this->entryLabel->key)
+                    return 1;
+                }
+              else if (IC_FALSE (ic)->key == this->entryLabel->key)
+                return 1;
+              break;
+            }
+        }
     }
 
   /* comes here means we have not found it yet */