had commited with options.parms_in_bank1 turned on by default
[fw/sdcc] / src / pic / pcode.c
index dd15d09c0b03d5b37671a65ac30be36d06ca3f16..14522f8afc07daa5909b9d09952e98be8a53afc2 100644 (file)
@@ -40,6 +40,8 @@ pCodeOpReg pc_fsr       = {{PO_FSR,     "FSR"}, -1, NULL,NULL};
 pCodeOpReg pc_pcl       = {{PO_PCL,     "PCL"}, -1, NULL,NULL};
 pCodeOpReg pc_pclath    = {{PO_PCLATH,  "PCLATH"}, -1, NULL,NULL};
 
+pCodeOpReg pc_kzero     = {{PO_GPR_REGISTER,  "KZ"}, -1, NULL,NULL};
+
 static int mnemonics_initialized = 0;
 
 
@@ -48,7 +50,7 @@ static hTab *pic14MnemonicsHash = NULL;
 
 
 static pFile *the_pFile = NULL;
-static int peepOptimizing = 1;
+static int peepOptimizing = 0;
 static int GpCodeSequenceNumber = 1;
 
 /****************************************************************/
@@ -70,6 +72,7 @@ static void pCodeOpPrint(FILE *of, pCodeOp *pcop);
 static char *get_op( pCodeInstruction *pcc);
 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd);
 int pCodePeepMatchRule(pCode *pc);
+void pBlockStats(FILE *of, pBlock *pb);
 
 
 pCodeInstruction pciADDWF = {
@@ -737,24 +740,6 @@ pCodeInstruction pciXORLW = {
 #define MAX_PIC14MNEMONICS 100
 pCodeInstruction *pic14Mnemonics[MAX_PIC14MNEMONICS];
 
-char *Safe_strdup(char *str)
-{
-  char *copy;
-
-  if(!str)
-    return NULL;
-
-  copy = strdup(str);
-  if(!copy) {
-    fprintf(stderr, "out of memory %s,%d\n",__FUNCTION__,__LINE__);
-    exit(1);
-  }
-
-  return copy;
-    
-}
-
-
 /*-----------------------------------------------------------------*/
 /* SAFE_snprintf - like snprintf except the string pointer is      */
 /*                 after the string has been printed to. This is   */
@@ -790,8 +775,14 @@ void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...)
 void  pCodeInitRegisters(void)
 {
 
-  pc_fsr.rIdx = 4;
-  pc_fsr.r = pic14_regWithIdx(4);
+  pc_fsr.rIdx = IDX_FSR;
+  pc_fsr.r = pic14_regWithIdx(IDX_FSR);
+
+  pc_indf.rIdx = IDX_INDF;
+  pc_indf.r = pic14_regWithIdx(IDX_INDF);
+
+  pc_kzero.rIdx = IDX_KZ;
+  pc_kzero.r = pic14_regWithIdx(IDX_KZ);
 
 }
 
@@ -882,7 +873,7 @@ void pic14initMnemonics(void)
   pci = hTabFirstItem(pic14MnemonicsHash, &key);
 
   while(pci) {
-    fprintf( stderr, "element %d key %d, mnem %s\n",i++,key,pci->mnemonic);
+    DFPRINTF((stderr, "element %d key %d, mnem %s\n",i++,key,pci->mnemonic));
     pci = hTabNextItem(pic14MnemonicsHash, &key);
   }
 
@@ -976,15 +967,17 @@ void copypCode(FILE *of, char dbName)
     return;
 
   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    if(getpBlock_dbName(pb) == dbName)
+    if(getpBlock_dbName(pb) == dbName) {
+      pBlockStats(of,pb);
       printpBlock(of,pb);
+    }
   }
 
 }
 void pcode_test(void)
 {
 
-  printf("pcode is alive!\n");
+  DFPRINTF((stderr,"pcode is alive!\n"));
 
   //initMnemonics();
 
@@ -1017,6 +1010,13 @@ void pcode_test(void)
     }
   }
 }
+/*-----------------------------------------------------------------*/
+/* int RegCond(pCodeOp *pcop) - if pcop points to the STATUS reg-  */
+/*      ister, RegCond will return the bit being referenced.       */
+/*                                                                 */
+/* fixme - why not just OR in the pcop bit field                   */
+/*-----------------------------------------------------------------*/
+
 static int RegCond(pCodeOp *pcop)
 {
 
@@ -1148,7 +1148,10 @@ pCode *newpCodeCharP(char *cP)
   pcc->pc.destruct = genericDestruct;
   pcc->pc.print = genericPrint;
 
-  pcc->comment = Safe_strdup(cP);
+  if(cP)
+    pcc->comment = Safe_strdup(cP);
+  else
+    pcc->comment = NULL;
 
   return ( (pCode *)pcc);
 
@@ -1190,14 +1193,15 @@ pCode *newpCodeFunction(char *mod,char *f)
 
 }
 
+/*-----------------------------------------------------------------*/
+/* pCodeLabelDestruct - free memory used by a label.               */
+/*-----------------------------------------------------------------*/
 static void pCodeLabelDestruct(pCode *pc)
 {
 
   if(!pc)
     return;
 
-  unlinkPC(pc);
-
   if((pc->type == PC_LABEL) && PCL(pc)->label)
     free(PCL(pc)->label);
 
@@ -1224,11 +1228,13 @@ pCode *newpCodeLabel(int key)
 
   pcl->key = key;
 
+  pcl->label = NULL;
   if(key>0) {
     sprintf(s,"_%05d_DS_",key);
-    pcl->label = Safe_strdup(s);
-  } else
-    pcl->label = NULL;
+    if(s)
+      pcl->label = Safe_strdup(s);
+  }
+
 
   return ( (pCode *)pcl);
 
@@ -1237,7 +1243,10 @@ pCode *newpCodeLabelStr(char *str)
 {
   pCode *pc = newpCodeLabel(-1);
 
-  PCL(pc)->label = Safe_strdup(str);
+  if(str)
+    PCL(pc)->label = Safe_strdup(str);
+  else
+    PCL(pc)->label = NULL;
 
   return pc;
 }
@@ -1262,7 +1271,7 @@ pBlock *newpBlock(void)
 }
 
 /*-----------------------------------------------------------------*/
-/* newpCodeChai0n - create a new chain of pCodes                    */
+/* newpCodeChain - create a new chain of pCodes                    */
 /*-----------------------------------------------------------------*
  *
  *  This function will create a new pBlock and the pointer to the
@@ -1297,17 +1306,21 @@ pCodeOp *newpCodeOpLabel(int key)
   pcop = Safe_calloc(1,sizeof(pCodeOpLabel) );
   pcop->type = PO_LABEL;
 
+  pcop->name = NULL;
   if(key>0) {
     sprintf(s,"_%05d_DS_",key);
-    pcop->name = Safe_strdup(s);
-  } else
-    pcop->name = NULL;
+    if(s)
+      pcop->name = Safe_strdup(s);
+  } 
+
 
   ((pCodeOpLabel *)pcop)->key = key;
 
   return pcop;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 pCodeOp *newpCodeOpLit(int lit)
 {
   char *s = buffer;
@@ -1316,17 +1329,21 @@ pCodeOp *newpCodeOpLit(int lit)
 
   pcop = Safe_calloc(1,sizeof(pCodeOpLit) );
   pcop->type = PO_LITERAL;
+  pcop->name = NULL;
   if(lit>=0) {
     sprintf(s,"0x%02x",lit);
-    pcop->name = Safe_strdup(s);
-  } else
-    pcop->name = NULL;
+    if(s)
+      pcop->name = Safe_strdup(s);
+  } 
+
 
   ((pCodeOpLit *)pcop)->lit = lit;
 
   return pcop;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype)
 {
   char *s = buffer;
@@ -1351,13 +1368,18 @@ pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype)
   return pcop;
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace)
 {
   pCodeOp *pcop;
 
   pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
   pcop->type = PO_BIT;
-  pcop->name = Safe_strdup(s);   
+  if(s)
+    pcop->name = Safe_strdup(s);   
+  else
+    pcop->name = NULL;
 
   PCOB(pcop)->bit = bit;
   PCOB(pcop)->inBitSpace = inBitSpace;
@@ -1401,7 +1423,10 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
   default:
     pcop = Safe_calloc(1,sizeof(pCodeOp) );
     pcop->type = type;
-    pcop->name = Safe_strdup(name);   
+    if(name)
+      pcop->name = Safe_strdup(name);   
+    else
+      pcop->name = NULL;
   }
 
   return pcop;
@@ -1434,7 +1459,7 @@ void addpBlock(pBlock *pb)
 
   if(!the_pFile) {
     /* First time called, we'll pass through here. */
-    _ALLOC(the_pFile,sizeof(the_pFile));
+    _ALLOC(the_pFile,sizeof(pFile));
     the_pFile->pbHead = the_pFile->pbTail = pb;
     the_pFile->functions = NULL;
     return;
@@ -1514,6 +1539,8 @@ static void genericDestruct(pCode *pc)
 }
 
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 void pBlockRegs(FILE *of, pBlock *pb)
 {
 
@@ -1534,8 +1561,12 @@ static char *get_op( pCodeInstruction *pcc)
 
 
     switch(pcc->pcop->type) {
-
+    case PO_INDF:
     case PO_FSR:
+      //fprintf(stderr,"get_op getting register name rIdx=%d\n",PCOR(pcc->pcop)->rIdx);
+      r = pic14_regWithIdx(PCOR(pcc->pcop)->rIdx);
+      return r->name;
+      break;
     case PO_GPR_TEMP:
     case PO_GPR_BIT:
       r = pic14_regWithIdx(PCOR(pcc->pcop)->r->rIdx);
@@ -1645,7 +1676,7 @@ static void genericPrint(FILE *of, pCode *pc)
     // If the opcode has a label, print that first
     {
       pBranch *pbl = pc->label;
-      while(pbl) {
+      while(pbl && pbl->pc) {
        if(pbl->pc->type == PC_LABEL)
          pCodePrintLabel(of, pbl->pc);
        pbl = pbl->next;
@@ -1755,16 +1786,28 @@ static void pCodePrintLabel(FILE *of, pCode *pc)
 
 }
 /*-----------------------------------------------------------------*/
-static void  unlinkpCodeFromBranch(pBranch *pb , pCode *pc)
+/* unlinkpCodeFromBranch - Search for a label in a pBranch and     */
+/*                         remove it if it is found.               */
+/*-----------------------------------------------------------------*/
+static void unlinkpCodeFromBranch(pCode *pcl , pCode *pc)
 {
   pBranch *b, *bprev;
 
   bprev = NULL;
-  b = pb;
+  b = pcl->label;
   while(b) {
     if(b->pc == pc) {
-      if(bprev)
-       bprev->next = b->next;
+
+      /* Found a label */
+      if(bprev) {
+       bprev->next = b->next;  /* Not first pCode in chain */
+       free(b);
+      } else {
+       pc->destruct(pc);
+       pcl->label = b->next;   /* First pCode in chain */
+       free(b);
+      }
+      return;  /* A label can't occur more than once */
     }
     bprev = b;
     b = b->next;
@@ -1772,6 +1815,8 @@ static void  unlinkpCodeFromBranch(pBranch *pb , pCode *pc)
 
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 static pBranch * pBranchAppend(pBranch *h, pBranch *n)
 {
   pBranch *b;
@@ -1902,6 +1947,8 @@ static void genericAnalyze(pCode *pc)
        } else
          npc = npc->next;
       }
+      /* reached the end of the pcode chain without finding
+       * an instruction we could link to. */
     }
   }
 }
@@ -2022,6 +2069,8 @@ static void AnalyzeRETURN(pCode *pc)
 
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 
 void AnalyzepBlock(pBlock *pb)
 {
@@ -2030,13 +2079,19 @@ void AnalyzepBlock(pBlock *pb)
   if(!pb)
     return;
 
-  /* Find all of the registers used in this pBlock */
+  /* Find all of the registers used in this pBlock 
+   * by looking at each instruction and examining it's
+   * operands
+   */
   for(pc = pb->pcHead; pc; pc = pc->next) {
-    if(pc->type == PC_OPCODE) {
-      if(PCI(pc)->pcop && PCI(pc)->pcop->type == PO_GPR_TEMP) {
+
+    /* Is this an instruction with operands? */
+    if(pc->type == PC_OPCODE && PCI(pc)->pcop) {
+
+      if(PCI(pc)->pcop->type == PO_GPR_TEMP) {
 
        /* Loop through all of the registers declared so far in
-          this block and see if we find this new there */
+          this block and see if we find this one there */
 
        regs *r = setFirstItem(pb->registers);
 
@@ -2054,14 +2109,30 @@ void AnalyzepBlock(pBlock *pb)
          memcpy(r,PCOR(PCI(pc)->pcop)->r, sizeof(regs));
          addSet(&pb->registers, r);
          PCOR(PCI(pc)->pcop)->r = r;
-         fprintf(stderr,"added register to pblock: reg %d\n",r->rIdx);
-       } else 
+         //fprintf(stderr,"added register to pblock: reg %d\n",r->rIdx);
+       }/* else 
          fprintf(stderr,"found register in pblock: reg %d\n",r->rIdx);
+        */
+      }
+      if(PCI(pc)->pcop->type == PO_GPR_REGISTER) {
+       if(PCOR(PCI(pc)->pcop)->r) {
+         pic14_allocWithIdx (PCOR(PCI(pc)->pcop)->r->rIdx);
+         DFPRINTF((stderr,"found register in pblock: reg 0x%x\n",PCOR(PCI(pc)->pcop)->r->rIdx));
+       } else {
+         if(PCI(pc)->pcop->name)
+           fprintf(stderr,"ERROR: %s is a NULL register\n",PCI(pc)->pcop->name );
+         else
+           fprintf(stderr,"ERROR: NULL register\n");
+       }
       }
     }
+
+
   }
 }
 
+/*-----------------------------------------------------------------*/
+/*-----------------------------------------------------------------*/
 int OptimizepBlock(pBlock *pb)
 {
   pCode *pc;
@@ -2070,10 +2141,11 @@ int OptimizepBlock(pBlock *pb)
   if(!pb || !peepOptimizing)
     return 0;
 
-  fprintf(stderr," Optimizing pBlock: %c\n",getpBlock_dbName(pb));
+  DFPRINTF((stderr," Optimizing pBlock: %c\n",getpBlock_dbName(pb)));
   for(pc = pb->pcHead; pc; pc = pc->next)
     matches += pCodePeepMatchRule(pc);
-
+  if(matches)
+    DFPRINTF((stderr," Optimizing pBlock: %c - matches=%d\n",getpBlock_dbName(pb),matches));
   return matches;
 
 }
@@ -2125,16 +2197,16 @@ void pBlockRemoveUnusedLabels(pBlock *pb)
        * So, unlink the pCode label from it's pCode chain
        * and destroy the label */
 
-      fprintf(stderr," !!! REMOVED A LABEL !!! key = %d\n", pcl->key);
+      DFPRINTF((stderr," !!! REMOVED A LABEL !!! key = %d\n", pcl->key));
 
       if(pc->type == PC_LABEL) {
-       //unlinkPC(pc);
+       unlinkPC(pc);
        pCodeLabelDestruct(pc);
       } else {
-       unlinkpCodeFromBranch(pc->label, pc);
-       if(pc->label->next == NULL && pc->label->pc == NULL) {
+       unlinkpCodeFromBranch(pc, PCODE(pcl));
+       /*if(pc->label->next == NULL && pc->label->pc == NULL) {
          free(pc->label);
-       }
+       }*/
       }
 
     }
@@ -2165,14 +2237,14 @@ void pBlockMergeLabels(pBlock *pb)
   for(pc = pb->pcHead; pc; pc = pc->next) {
 
     if(pc->type == PC_LABEL) {
-      fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
+      //fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
       if( !(pcnext = findNextInstruction(pc)) ) 
        return;  // Couldn't find an instruction associated with this label
 
       // Unlink the pCode label from it's pCode chain
       unlinkPC(pc);
 
-      fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key);
+      //fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key);
       // And link it into the instruction's pBranch labels. (Note, since
       // it's possible to have multiple labels associated with one instruction
       // we must provide a means to accomodate the additional labels. Thus
@@ -2208,7 +2280,7 @@ void OptimizepCode(char dbName)
   if(!the_pFile)
     return;
 
-  fprintf(stderr," Optimizing pCode\n");
+  DFPRINTF((stderr," Optimizing pCode\n"));
 
   do {
     for(pb = the_pFile->pbHead; pb; pb = pb->next) {
@@ -2234,25 +2306,35 @@ void AnalyzepCode(char dbName)
   pCode *pc;
   pBranch *pbr;
 
+  int i,changes;
+
   if(!the_pFile)
     return;
 
-  fprintf(stderr," Analyzing pCode");
 
-  /* First, merge the labels with the instructions */
-  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    if('*' == dbName || getpBlock_dbName(pb) == dbName) {
+  i = 0;
+  do {
+
+    DFPRINTF((stderr," Analyzing pCode: PASS #%d\n",i+1));
 
-      fprintf(stderr," analyze and merging block %c\n",dbName);
-      pBlockMergeLabels(pb);
-      AnalyzepBlock(pb);
+    /* First, merge the labels with the instructions */
+    for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+      if('*' == dbName || getpBlock_dbName(pb) == dbName) {
+
+       DFPRINTF((stderr," analyze and merging block %c\n",dbName));
+       pBlockMergeLabels(pb);
+       AnalyzepBlock(pb);
+      }
     }
-  }
 
-  for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    if('*' == dbName || getpBlock_dbName(pb) == dbName)
-      OptimizepBlock(pb);
-  }
+    changes = 0;
+
+    for(pb = the_pFile->pbHead; pb; pb = pb->next) {
+      if('*' == dbName || getpBlock_dbName(pb) == dbName)
+       changes += OptimizepBlock(pb);
+    }
+      
+  } while(changes && (i++ < MAX_PASSES));
 
   /* Now build the call tree.
      First we examine all of the pCodes for functions.
@@ -2375,26 +2457,28 @@ void pBlockStats(FILE *of, pBlock *pb)
   pCode *pc;
   regs  *r;
 
-  fprintf(of,"***\n  pBlock Stats\n***\n");
+  fprintf(of,";***\n;  pBlock Stats\n;***\n");
 
   // for now just print the first element of each set
   pc = setFirstItem(pb->function_entries);
   if(pc) {
-    fprintf(of,"entry\n");
+    fprintf(of,";entry:  ");
     pc->print(of,pc);
   }
   pc = setFirstItem(pb->function_exits);
   if(pc) {
-    fprintf(of,"has an exit\n");
-    pc->print(of,pc);
+    fprintf(of,";has an exit\n");
+    //pc->print(of,pc);
   }
 
   pc = setFirstItem(pb->function_calls);
   if(pc) {
-    fprintf(of,"functions called\n");
+    fprintf(of,";functions called:\n");
 
     while(pc) {
-      pc->print(of,pc);
+      if(pc->type == PC_OPCODE && PCI(pc)->op == POC_CALL) {
+       fprintf(of,";   %s\n",get_op(PCI(pc)));
+      }
       pc = setNextItem(pb->function_calls);
     }
   }
@@ -2403,10 +2487,10 @@ void pBlockStats(FILE *of, pBlock *pb)
   if(r) {
     int n = elementsInSet(pb->registers);
 
-    fprintf(of,"%d compiler assigned register%c:\n",n, ( (n!=1) ? 's' : ' '));
+    fprintf(of,";%d compiler assigned register%c:\n",n, ( (n!=1) ? 's' : ' '));
 
     while (r) {
-      fprintf(of,"   %s\n",r->name);
+      fprintf(of,";   %s\n",r->name);
       r = setNextItem(pb->registers);
     }
   }
@@ -2464,8 +2548,13 @@ set *register_usage(pBlock *pb)
 
   }
 
-
+#ifdef PCODE_DEBUG
   pBlockStats(stderr,pb);  // debug
+#endif
+
+  // Mark the registers in this block as used.
+
+  MarkUsedRegisters(pb->registers);
   if(registersInCallPath) {
     /* registers were used in the functions this pBlock has called */
     /* so now, we need to see if these collide with the ones we are */
@@ -2473,29 +2562,32 @@ set *register_usage(pBlock *pb)
 
     regs *r1,*r2, *newreg;
 
-    fprintf(stderr,"comparing registers\n");
+    DFPRINTF((stderr,"comparing registers\n"));
 
     r1 = setFirstItem(registersInCallPath);
     while(r1) {
 
       r2 = setFirstItem(pb->registers);
 
-      while(r2) {
+      while(r2 && (r1->type != REG_STK)) {
 
        if(r2->rIdx == r1->rIdx) {
-         newreg = pic14_findFreeReg();
+         newreg = pic14_findFreeReg(REG_GPR);
 
 
          if(!newreg) {
-           fprintf(stderr,"Bummer, no more registers.\n");
+           DFPRINTF((stderr,"Bummer, no more registers.\n"));
            exit(1);
          }
 
-         fprintf(stderr,"Cool found register collision nIdx=%d moving to %d\n",
-                 r1->rIdx, newreg->rIdx);
+         DFPRINTF((stderr,"Cool found register collision nIdx=%d moving to %d\n",
+                 r1->rIdx, newreg->rIdx));
          r2->rIdx = newreg->rIdx;
          //if(r2->name) free(r2->name);
-         r2->name = Safe_strdup(newreg->name);
+         if(newreg->name)
+           r2->name = Safe_strdup(newreg->name);
+         else
+           r2->name = NULL;
          newreg->isFree = 0;
          newreg->wasUsed = 1;
        }
@@ -2508,24 +2600,26 @@ set *register_usage(pBlock *pb)
     /* Collisions have been resolved. Now free the registers in the call path */
     r1 = setFirstItem(registersInCallPath);
     while(r1) {
-      newreg = pic14_regWithIdx(r1->rIdx);
-      newreg->isFree = 1;
+      if(r1->type != REG_STK) {
+       newreg = pic14_regWithIdx(r1->rIdx);
+       newreg->isFree = 1;
+      }
       r1 = setNextItem(registersInCallPath);
     }
 
-  } else
-    MarkUsedRegisters(pb->registers);
+  }// else
+  //    MarkUsedRegisters(pb->registers);
 
   registers = unionSets(pb->registers, registersInCallPath, THROW_NONE);
-
+#ifdef PCODE_DEBUG
   if(registers) 
-    fprintf(stderr,"returning regs\n");
+    DFPRINTF((stderr,"returning regs\n"));
   else
-    fprintf(stderr,"not returning regs\n");
+    DFPRINTF((stderr,"not returning regs\n"));
 
-  fprintf(stderr,"pBlock after register optim.\n");
+  DFPRINTF((stderr,"pBlock after register optim.\n"));
   pBlockStats(stderr,pb);  // debug
-
+#endif
 
   return registers;
 }
@@ -2611,7 +2705,10 @@ void pct2(FILE *of,pBlock *pb,int indent)
                  r1->rIdx, newreg->rIdx);
          r2->rIdx = newreg->rIdx;
          //if(r2->name) free(r2->name);
-         r2->name = Safe_strdup(newreg->name);
+         if(newreg->name)
+           r2->name = Safe_strdup(newreg->name);
+         else
+           r2->name = NULL;
          newreg->isFree = 0;
          newreg->wasUsed = 1;
        }
@@ -2667,7 +2764,7 @@ void printCallTree(FILE *of)
 
   fprintf(of, "\npBlock statistics\n");
   for(pb = the_pFile->pbHead; pb;  pb = pb->next )
-    pBlockStats(stderr,pb);
+    pBlockStats(of,pb);