* src/SDCCsymt.c: fixed (hopeful properly) bug
[fw/sdcc] / src / SDCCBBlock.c
index 15470f19ac039f8081e05f7f3fd48a4e418ee25b..28d56e5a99645bc66c2e046bb167573cb1a65a5c 100644 (file)
@@ -24,7 +24,6 @@
 -------------------------------------------------------------------------*/
 
 #include "common.h"
-#include "newalloc.h"
 
 int eBBNum = 0;
 set *graphEdges = NULL;                /* list of edges in this flow graph */
@@ -65,7 +64,7 @@ neweBBlock ()
 {
   eBBlock *ebb;
 
-  ebb = Safe_calloc (1, sizeof (eBBlock));
+  ebb = Safe_alloc (sizeof (eBBlock));
   return ebb;
 }
 
@@ -77,7 +76,7 @@ newEdge (eBBlock * from, eBBlock * to)
 {
   edge *ep;
 
-  ep = Safe_calloc (1, sizeof (edge));
+  ep = Safe_alloc (sizeof (edge));
 
   ep->from = from;
   ep->to = to;
@@ -85,11 +84,13 @@ 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)
       break;
@@ -97,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
-    strcpy (scratchFileName, srcFileName);
-    strcat (scratchFileName, dumpFilesPtr->ext);
+    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;
 }
 
@@ -122,7 +134,6 @@ void closeDumpFiles() {
   for (dumpFilesPtr=dumpFiles; dumpFilesPtr->id; dumpFilesPtr++) {
     if (dumpFilesPtr->filePtr) {
       fclose (dumpFilesPtr->filePtr);
-      //dprintf ("closed %s\n", dumpFilesPtr->ext);
     }
   }
 }
@@ -138,11 +149,13 @@ dumpLiveRanges (int id, hTab * liveRanges)
   int k;
 
   if (id) {
-    file=appendDumpFile(id);
+    file=createDumpFile(id);
   } else {
     file = stdout;
   }
-
+  
+  if (currFunc) 
+      fprintf(file,"------------- Func %s -------------\n",currFunc->name);
   for (sym = hTabFirstItem (liveRanges, &k); sym;
        sym = hTabNextItem (liveRanges, &k))
     {
@@ -161,49 +174,30 @@ dumpLiveRanges (int id, hTab * liveRanges)
        {
          fprintf (file, "}{ sir@ %s", sym->usl.spillLoc->rname);
        }
-      fprintf (file, "}");
-
-      /* if assigned to registers */
-      if (sym->nRegs)
-       {
-         if (sym->isspilt)
-           {
-             if (!sym->remat)
-               if (sym->usl.spillLoc)
-                 fprintf (file, "[%s]", (sym->usl.spillLoc->rname[0] ?
-                                         sym->usl.spillLoc->rname :
-                                         sym->usl.spillLoc->name));
-               else
-                 fprintf (file, "[err]");
-             else
-               fprintf (file, "[remat]");
-           }
-         else
-           {
-             int i;
-             fprintf (file, "[");
-             for (i = 0; i < sym->nRegs; i++)
-               fprintf (file, "%s ", port->getRegName (sym->regs[i]));
-             fprintf (file, "]");
-           }
-       }
+      fprintf (file, "} clashes with ");
+      bitVectDebugOn(sym->clashes,file);
       fprintf (file, "\n");
     }
 
   fflush(file);
 }
 
+
 /*-----------------------------------------------------------------*/
 /* dumpEbbsToFileExt - writeall the basic blocks to a file         */
 /*-----------------------------------------------------------------*/
 void 
-dumpEbbsToFileExt (int id, eBBlock ** ebbs, int count)
+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;
   }
@@ -211,17 +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",
+      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,
-              ebbs[i]->isLastInLoop);
+              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, "\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);
     }
@@ -235,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++;
     }
@@ -258,6 +315,14 @@ iCode2eBBlock (iCode * ic)
       ebb->ech = ebb->sch;
       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)
@@ -278,7 +343,7 @@ iCode2eBBlock (iCode * ic)
        {
          ebb->hasFcall = 1;
          if (currFunc)
-           currFunc->hasFcall = 1;
+           FUNC_HASFCALL(currFunc->type) = 1;
        }
 
       /* if the next one is a label */
@@ -300,8 +365,10 @@ 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++)
@@ -396,7 +463,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;
 
@@ -438,6 +508,7 @@ addiCodeToeBBlock (eBBlock * ebp, iCode * ic, iCode * ip)
 void 
 remiCodeFromeBBlock (eBBlock * ebb, iCode * ic)
 {
+  wassert (ic->seq>=ebb->fSeq && ic->seq<=ebb->lSeq);
   if (ic->prev)
     ic->prev->next = ic->next;
   else
@@ -452,17 +523,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;
-
-  *count = 0;
+  ebbIndex *ebbi;
+  
+  ebbi = Safe_alloc (sizeof (ebbIndex));
+  ebbi->count = 0;
+  ebbi->dfOrder = NULL; /* no depth first order information yet */
 
   /* allocate for the first entry */
 
-  ebbs = Safe_calloc (1, sizeof (eBBlock **));
+  ebbs = Safe_alloc (sizeof (eBBlock *));
+  ebbi->bbOrder = ebbs;
 
   while (loop)
     {
@@ -474,64 +549,66 @@ iCodeBreakDown (iCode * ic, int *count)
       ebb->ech->next = NULL;   /* mark the end of this chain */
       if (loop)
        loop->prev = NULL;
-      ebb->bbnum = *count;     /* save this block number     */
+      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))
+      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[(*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 (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 (ebbs, label, (*count))) &&
+         if ((destBlock = eBBWithEntryLabel (ebbi, label)) &&
              destBlock->preHeader == NULL &&
              otherPathsPresent (ebbs, destBlock))
            {
 
-             symbol *preHeaderLabel = newiTempPreheaderLabel ();
+             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 < (*count); i++)
+             for (i = 0; i < (ebbi->count); i++)
                {
                  if (ebbs[i] == destBlock)
                    break;
                  replaceLabel (ebbs[i], label, preHeaderLabel);
                }
 
-             (*count)++;
+             (ebbi->count)++;
 
              /* if we have stopped at the block , allocate for an extra one */
 
-             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;
 
              /* then move the block down one count */
              pBlock = ebbs[j = i];
-             for (i += 1; i < (*count); i++)
+             for (i += 1; i < (ebbi->count); i++)
                {
                  eBBlock *xBlock;
 
@@ -551,9 +628,9 @@ iCodeBreakDown (iCode * ic, int *count)
     }
 
   /* mark the end */
-  ebbs[*count] = NULL;
+  ebbs[ebbi->count] = NULL;
 
-  return ebbs;
+  return ebbi;
 }
 
 /*-----------------------------------------------------------------*/
@@ -581,7 +658,7 @@ replaceSymBySym (set * sset, operand * src, operand * dest)
            {
              bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
              IC_COND (ic) = operandFromOperand (dest);
-             OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
+             OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
              continue;
            }
 
@@ -590,7 +667,7 @@ replaceSymBySym (set * sset, operand * src, operand * dest)
              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);
+             OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
            }
 
          if (isOperandEqual (IC_LEFT (ic), src))
@@ -606,7 +683,7 @@ replaceSymBySym (set * sset, operand * src, operand * dest)
                  IC_LEFT (ic) = operandFromOperand (dest);
                  IC_LEFT (ic)->isaddr = 0;
                }
-             OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
+             OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
            }
 
          /* special case for pointer sets */
@@ -616,7 +693,7 @@ replaceSymBySym (set * sset, operand * src, operand * dest)
              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);
+             OP_USES(dest)=bitVectSetBit (OP_USES (dest), ic->key);
            }
        }
     }
@@ -676,13 +753,32 @@ iCodeFromeBBlock (eBBlock ** ebbs, int count)
          (ebbs[i]->entryLabel != entryLabel &&
           ebbs[i]->entryLabel != returnLabel))
        {
-         werror (W_CODE_UNREACH, ebbs[i]->sch->filename, ebbs[i]->sch->lineno);
-         continue;
+          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;