* device/include/pic16/adc.h,
[fw/sdcc] / src / pic / pcoderegs.c
index 0c8f4bebed9c1dc485ee9726b5e23259cb100b97..c115b3213ab9df8b8d6a7a56cd79eec6a74d6b47 100644 (file)
@@ -26,129 +26,20 @@ pcoderegs.c
   The purpose of the code in this file is to optimize the register usage.
 
 */
-#include <stdio.h>
 
-#include "common.h"   // Include everything in the SDCC src directory
-#include "newalloc.h"
-#include "ralloc.h"
-#include "device.h"
-#include "pcode.h"
+#include "main.h"
 #include "pcoderegs.h"
 #include "pcodeflow.h"
-#include "main.h"
-
-extern void dbg_dumpregusage(void);
-extern pCode * findPrevInstruction(pCode *pci);
-extern pBranch * pBranchAppend(pBranch *h, pBranch *n);
-void unlinkpCode(pCode *pc);
-extern int pCodeSearchCondition(pCode *pc, unsigned int cond, int contIfSkip);
-char *pCode2str(char *str, int size, pCode *pc);
-void SAFE_snprintf(char **str, size_t *size, const  char  *format, ...);
-//static int sameRegs (const regs *reg1, const regs *reg2);
-
-int total_registers_saved=0;
-int register_optimization=1;
-
-/*-----------------------------------------------------------------*
-* void AddRegToFlow(regs *reg, pCodeFlow *pcfl)
-*-----------------------------------------------------------------*/
-/*
-void AddRegToFlow(regs *reg, pCodeFlow *pcfl)
-{
-
-       if(!reg || ! pcfl || !isPCFL(pcflow))
-       return;
-
-       if(!pcfl->registers) 
-       pcfl->registers =  newSet();
-       
-}
-*/
-
-
-/*-----------------------------------------------------------------*
-* 
-*-----------------------------------------------------------------*/
-void dbg_regusage(set *fregs)
-{
-       regs *reg;
-       pCode *pcfl;
-       pCode *pc;
-       
-       
-       for (reg = setFirstItem(fregs) ; reg ;
-       reg = setNextItem(fregs)) {
-               
-               if(elementsInSet(reg->reglives.usedpCodes)) {
-                       
-                       fprintf (stderr, "%s  addr=0x%03x rIdx=0x%03x",
-                               reg->name,
-                               reg->address,
-                               reg->rIdx);
-                       
-                       pcfl = setFirstItem(reg->reglives.usedpFlows);
-                       if(pcfl)
-                               fprintf(stderr, "\n   used in seq");
-                       
-                       while(pcfl) {
-                               fprintf(stderr," 0x%03x",pcfl->seq);
-                               pcfl = setNextItem(reg->reglives.usedpFlows);
-                       }
-                       
-                       pcfl = setFirstItem(reg->reglives.assignedpFlows);
-                       if(pcfl)
-                               fprintf(stderr, "\n   assigned in seq");
-                       
-                       while(pcfl) {
-                               fprintf(stderr," 0x%03x",pcfl->seq);
-                               pcfl = setNextItem(reg->reglives.assignedpFlows);
-                       }
-                       
-                       pc = setFirstItem(reg->reglives.usedpCodes);
-                       if(pc)
-                               fprintf(stderr, "\n   used in instructions ");
-                       
-                       while(pc) {
-                               pcfl = PCODE(PCI(pc)->pcflow);
-                               if(pcfl)
-                                       fprintf(stderr," 0x%03x:",pcfl->seq);
-                               fprintf(stderr,"0x%03x",pc->seq);
-                               
-                               pc = setNextItem(reg->reglives.usedpCodes);
-                       }
-                       
-                       fprintf(stderr, "\n");
-               }
-       }
-}
+#include "ralloc.h"
 
-/*-----------------------------------------------------------------*
-* 
-*-----------------------------------------------------------------*/
-void dbg_dumpregusage(void)
-{
-       
-       fprintf(stderr,"***  Register Usage  ***\n");
-       fprintf(stderr,"InternalRegs:\n");
-       dbg_regusage(dynInternalRegs);
-       fprintf(stderr,"AllocRegs:\n");
-       dbg_regusage(dynAllocRegs);
-       fprintf(stderr,"StackRegs:\n");
-       dbg_regusage(dynStackRegs);
-       fprintf(stderr,"DirectRegs:\n");
-       dbg_regusage(dynDirectRegs);
-       fprintf(stderr,"DirectBitRegs:\n");
-       dbg_regusage(dynDirectBitRegs);
-       fprintf(stderr,"ProcessorRegs:\n");
-       dbg_regusage(dynProcessorRegs);
-       
-}
 
+static int total_registers_saved=0;
+static int register_optimization=1;
 
 /*-----------------------------------------------------------------*
 * void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
 *-----------------------------------------------------------------*/
-void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
+static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
 {
        
        pCode *pc=NULL;
@@ -192,6 +83,7 @@ void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
                                addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl);
                        
                        addSetIfnotP(& (reg->reglives.usedpCodes), pc);
+                       reg->wasUsed = 1;
                }
                
                
@@ -237,8 +129,6 @@ void pCodeRegMapLiveRanges(pBlock *pb)
        }
 #endif
        
-       //  dbg_dumpregusage();
-       
 }
 
 
@@ -277,20 +167,21 @@ static void Remove1pcode(pCode *pc, regs *reg, int debug_code)
        }
        
        
-       if(1){
-       /*
-       Debug stuff. Comment out the instruction we're about to delete.
-               */
+       if(1) {
+                /*
+                 * Debug stuff. Comment out the instruction we're about to delete.
+                 */
                
                char buff1[256];
                size_t size = 256;
                
-               char *pbuff,**ppbuff;
-               pbuff = buff1;
-               ppbuff = &pbuff;
+               char *pbuff;
+               pbuff = &buff1[0];
                
-               SAFE_snprintf(ppbuff,&size, ";%d", debug_code);
-               pCode2str(*ppbuff, size, pc);
+               SNPRINTF(pbuff, size, ";%d", debug_code);
+               size -= strlen(pbuff);
+               pbuff += strlen(pbuff);
+               pCode2str(pbuff, size, pc);
                pCodeInsertBefore(pc, newpCodeCharP(buff1));
                //fprintf(stderr,"removing instruction:\n%s\n",buff1);
        }
@@ -303,7 +194,7 @@ static void Remove1pcode(pCode *pc, regs *reg, int debug_code)
 * void RemoveRegsFromSet(set *regset)
 *
 *-----------------------------------------------------------------*/
-void  RemoveRegsFromSet(set *regset)
+static void RemoveRegsFromSet(set *regset)
 {
        regs *reg;
        int used;
@@ -370,9 +261,7 @@ void  RemoveRegsFromSet(set *regset)
        }
 }
 
-void RegsUnMapLiveRanges(void);
-extern pFile *the_pFile;
-void pic14_ReMapLiveRanges(void)
+static void pic14_ReMapLiveRanges(void)
 {
        pBlock *pb;
        if (!the_pFile) return;
@@ -453,7 +342,7 @@ static void Remove2pcodes(pCode *pcflow, pCode *pc1, pCode *pc2, regs *reg, int
 /*-----------------------------------------------------------------*
 *
 *-----------------------------------------------------------------*/
-int regUsedinRange(pCode *pc1, pCode *pc2, regs *reg)
+static int regUsedinRange(pCode *pc1, pCode *pc2, regs *reg)
 {
        int i=0;
        regs *testreg;
@@ -475,7 +364,7 @@ int regUsedinRange(pCode *pc1, pCode *pc2, regs *reg)
        return 0;
 }
 
-int regIsSpecial (regs *reg, int mayBeGlobal)
+static int regIsSpecial (regs *reg, int mayBeGlobal)
 {
   if (!reg) return 0;
 
@@ -484,23 +373,6 @@ int regIsSpecial (regs *reg, int mayBeGlobal)
   return 0;
 }
 
-#if 0
-static int regIsLocal (regs *reg)
-{
-       if (!reg) return 1;
-       /* temporaries are local */
-       if (reg->type == REG_TMP) return 1;
-       /* registers named r0x... are local */
-       if (reg->name && !strncmp(reg->name,"r0x", 3))
-       {
-               //fprintf (stderr, "reg %s is not marked REG_TMP...\n", reg->name);
-               return 1;
-       }
-
-       return 0;
-}
-#endif
-
 /*-----------------------------------------------------------------*
 * void pCodeOptime2pCodes(pCode *pc1, pCode *pc2) 
 *
@@ -512,7 +384,7 @@ static int regIsLocal (regs *reg)
 * 
 *
 *-----------------------------------------------------------------*/
-int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int can_free, int optimize_level)
+static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int can_free, int optimize_level)
 {
        pCode *pct1, *pct2;
        regs  *reg1, *reg2;
@@ -522,24 +394,27 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
        if (!isPCI(pc1) || !isPCI(pc2)) return 0;
        if (PCI(pc1)->pcflow != PCI(pc2)->pcflow) return 0;
        
-       if(pc2->seq < pc1->seq) {
+       if (pc2->seq < pc1->seq) {
                pct1 = pc2;
                pc2 = pc1;
                pc1 = pct1;
        }
 
        /* disable this optimization for now -- it's buggy */
-       if(pic14_options.disable_df) return 0;
+       if (pic14_options.disable_df) return 0;
        
        //fprintf(stderr,"pCodeOptime2pCodes\n");
        //pc1->print(stderr,pc1);
        //pc2->print(stderr,pc2);
 
        if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_MOVFW) ){
+           /*
+            * CLRF sets Z
+            * MOVFW affects Z
+            * MOVWF does not touch Z
+            * MOVLW does not touch Z
+            */
                pCode *newpc;
-               int regUsed = 0;
-               int wUsed   = 0;
-               int wSaved  = 0;
                /*
                clrf  reg    ; pc1
                stuff...
@@ -552,41 +427,26 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
                */
                DFPRINTF((stderr, "   optimising CLRF reg ... MOVF reg,W to ... MOVLW 0\n"));
                pct2 = findNextInstruction(pc2->next);
-               
-               if(pct2 && PCI(pct2)->op == POC_MOVWF) {
-                       wSaved = wUsed = 1; /* Maybe able to replace with clrf pc2->next->reg. */
-               } else {
-                       wUsed = pCodeSearchCondition(pct2,PCC_W,1) != -1;
-               }
-               regUsed = regUsedinRange(pct2,0,reg);
-               if ((regUsed&&wUsed) || (pCodeSearchCondition(pct2,PCC_Z,0) != -1)) {
-                       /* Do not optimise as exisiting code is required. */
-               } else {
-                       /* Can optimise. */
-                       if(regUsed) {
-                               newpc = newpCode(POC_CLRF, PCI(pc1)->pcop);
-                       } else if(wSaved && !wUsed) {
-                               newpc = newpCode(POC_CLRF, PCI(pct2)->pcop);
-                               pct2->destruct(pct2);
-                       } else {
-                               newpc = newpCode(POC_MOVLW, newpCodeOpLit(0));
-                       }
+               if (pCodeSearchCondition(pct2, PCC_Z, 0) == -1) {
+                       /* Z is definitely overwritten before use */
+                       newpc = newpCode(POC_MOVLW, newpCodeOpLit(0));
                        
                        pCodeInsertAfter(pc2, newpc);
                        PCI(newpc)->pcflow = PCFL(pcfl_used);
                        newpc->seq = pc2->seq;
                        
                        //fprintf (stderr, "%s:%d(%s): Remove2pcodes (CLRF reg, ..., MOVF reg,W)\n", __FILE__, __LINE__, __FUNCTION__);
-                       Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free);
-                       total_registers_saved++;  // debugging stats.
+                       //Remove2pcodes(pcfl_used, pc2, NULL, reg, 0);
+                       pc2->destruct(pc2);
+                       //total_registers_saved++;  // debugging stats.
                }
        } else if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_IORFW) ){
                DFPRINTF((stderr, "   optimising CLRF/IORFW\n"));
                
                pct2 = findNextInstruction(pc2->next);
                
-               /* We must ensure that is destroyed before being read---IORLW must be performed unless this is proven. */
-               if(pCodeSearchCondition(pct2, PCC_Z,0) != -1) {
+               /* We must ensure that is destroyed before being read---IORLW must be performed unless this is proven. */
+               if (pCodeSearchCondition(pct2, PCC_Z, 0) != -1) {
                        pct2 = newpCode(POC_IORLW, newpCodeOpLit(0));
                        pct2->seq = pc2->seq;
                        PCI(pct2)->pcflow = PCFL(pcfl_used);
@@ -710,7 +570,7 @@ int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *reg, int
 /*-----------------------------------------------------------------*
 * void pCodeRegOptimeRegUsage(pBlock *pb) 
 *-----------------------------------------------------------------*/
-void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_level)
+static void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_level)
 {
        regs *reg;
        int used;
@@ -843,7 +703,6 @@ void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_level)
                                        
                                        if(pc1 && isPCI(pc1) &&  ( (pcfl1 = PCI(pc1)->pcflow) != NULL) ) {
                                                
-                                               //while(rset2 && searching) {
                                                if(rset2) {
                                                        
                                                        pc2 = rset2->item;
@@ -859,819 +718,13 @@ void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_level)
                                                        
                                                }
                                        }
-                                       rset1 = rset1->next;
+                                       rset1 = rset2;
                                }
                        }
                }
        }
 }
 
-#if 0
-
-/* The following routines implement pCode optimizations based on
- * dataflow analysis. The effects should be similar to those
- * of pCodeOptime2pCodes() but more powerful.
- *
- * Unfortunately, the current approach (comparing operands by
- * their associated registers) is seriously flawed:
- * Some pCodeOps do not provide access to their repsective regs
- * (PO_DIRs are created from arbitrary strings, immediates need
- * to take offset and index into account, ...)
- *
- * This has to be rewritten based on pCodeOps instead of regs...
- */
-
-/* ------------------------------------------------------------------
-   Returns TRUE iff reg1 and reg2 are the same registers.
-   ------------------------------------------------------------------ */
-
-static int sameRegs (const regs *reg1, const regs *reg2)
-{
-       if (reg1 == reg2) return 1;
-       if (!reg1 || !reg2) return 0;
-       assert (reg1->name && reg2->name);
-
-       /* Compare names, as rIdx is not unique... */
-       if (!strcmp(reg1->name, reg2->name)) return 1;
-
-       /* Name mismatch -- not the same register. */
-       return 0;
-}
-
-/* ------------------------------------------------------------------
-   Returns 1 if the register is live at pc (read in this flow),
-   returns -1 if the register is NOT live at pc (assigned a new value
-   prior to readingi the old value in this flow) or
-   return 0 if the register is not mentioned.
-   ------------------------------------------------------------------ */
-
-static int checkRegInFlow (regs **reg, int *cond, pCode *pc)
-{
-       const int verbose = 0;
-       /* find next PCI at or after pc */
-       while (pc && isPCFL(pc)) pc = pc->next;
-
-       assert (reg && cond);
-
-       /* remove pseudo flags from cond */
-       *cond &= ~(PCC_REGISTER | PCC_EXAMINE_PCOP);
-
-       if (verbose && pc)
-       {
-               fprintf (stderr, "Checking for reg %s, cond %x on pc ", *reg ? (*reg)->name : "<none>", *cond); pc->print (stderr, pc);
-       }
-       
-       while (pc && !isPCFL(pc))
-       {
-               if (verbose)
-               {
-                       fprintf (stderr, "        now checking for reg %s, cond %x on pc ", *reg ? (*reg)->name : "<none>", *cond);
-                       pc->print (stderr, pc);
-               }
-               if (isPCI(pc))
-               {
-                       pCode *pcprev;
-                       regs *op = NULL;
-                       int prevIsSkip = 0;
-                       
-                       pcprev = findPrevInstruction (pc);
-                       if (pcprev && isPCI_SKIP(pcprev))
-                               prevIsSkip = 1;
-
-                       if ((PCI(pc)->inCond | PCI(pc)->outCond) & PCC_REGISTER)
-                       {
-                               op = getRegFromInstruction (pc);
-
-                               /* pCodeOpRegBits do not provide register information... */
-                               //if (!op) { __asm__("int3"); pc->print (stderr, pc); }
-                               //assert (op);
-                               if (!op) 
-                               {
-                                       if (reg)
-                                               return 1; /* assume `reg' is alive */
-                               }
-
-                               /* SPECIAL CASE: jump to unknown destination -- assume everything alive */
-                               if (op->type == PO_PCL)
-                               {
-                                       return 1;
-                               }
-                       } // if
-
-                       if (PCI(pc)->inCond & PCC_REGISTER)
-                       {
-                               /* `op' is live (possibly read) */
-                               if (*reg && sameRegs (op, *reg))
-                               {
-                                       if (verbose)
-                                       {
-                                               fprintf (stderr, "reg is read in pc ");
-                                               pc->print (stderr, pc);
-                                       }
-                                       return 1;
-                               }
-                       }
-
-                       /* handle additional implicit operands */
-                       switch (PCI(pc)->op)
-                       {
-                       case POC_CALL: /* read arguments from WREG, clobbers WREG */
-                               if (*cond & PCC_W)
-                               {
-                                       if (verbose)
-                                       {
-                                               fprintf (stderr, "conditions are read at pc ");
-                                               pc->print (stderr, pc);
-                                       }
-                                       return 1;
-                               }
-                               *cond &= ~PCC_W;
-                               break;
-                       case POC_RETURN: /* returns WREG to caller */
-                               //fprintf (stderr, "reached RETURN, reg %s, cond %x\n", *reg ? (*reg)->name : "<none>", *cond);
-                               if (*cond & PCC_W)
-                               {
-                                       if (verbose)
-                                       {
-                                               fprintf (stderr, "conditions are read at pc ");
-                                               pc->print (stderr, pc);
-                                       }
-                                       return 1;
-                               }
-                               /* afterwards, no condition is alive */
-                               *cond = 0;
-                               /* afterwards, all local registers are dead */
-                               if (*reg && regIsLocal (*reg)) *reg = NULL;
-                               break;
-                       case POC_RETLW:
-                       case POC_RETFIE: /* this does not erturn WREG to the "caller", thus its rather a RETLW */
-                               /* this discards WREG */
-                               *cond &= ~PCC_W;
-                               /* afterwards, no condition is alive */
-                               *cond = 0;
-                               /* afterwards, all local registers are dead */
-                               if (*reg && regIsLocal (*reg)) *reg = NULL;
-                               break;
-                       default:
-                               /* no implicit arguments */
-                               break;
-                       }
-
-                       if (PCI(pc)->inCond & (*cond))
-                       {
-                               /* a condition is read */
-                               if (verbose)
-                               {
-                                       fprintf (stderr, "conditions are read at pc ");
-                                       pc->print (stderr, pc);
-                               }
-                               return 1;
-                       }
-
-                       /* remove outConds from `cond' */
-                       (*cond) &= ~(PCI(pc)->outCond);
-
-                       if (PCI(pc)->outCond & PCC_REGISTER)
-                       {
-                               /* `op' is (possibly) discarded */
-                               if (*reg && !prevIsSkip && sameRegs (op, *reg))
-                               {
-                                       if (verbose)
-                                       {
-                                               fprintf (stderr, "reg is assigned (cont'd) at pc ");
-                                               pc->print (stderr, pc);
-                                       }
-                                       *reg = NULL;
-                               }
-                       }
-
-                       /* have all interesting conditions/registers been discarded? */
-                       if (!(*reg) && !(*cond))
-                       {
-                               if (verbose)
-                               {
-                                       fprintf (stderr, "reg and conditions are discarded after ");
-                                       pc->print (stderr, pc);
-                               }
-                               return -1;
-                       }
-               } // if
-
-               pc = pc->next;
-       } // while
-
-       /* no use of (or only conditional writes to) `reg' found in flow */
-       if (verbose)
-       {
-               fprintf (stderr, "analysis inconclusive: reg %s, cond %x remains\n", *reg ? "remains" : "is void", *cond);
-       }
-       return 0;
-}
-
-/* ------------------------------------------------------------------
-   This will return 1 only if
-   - reg is NULL or of type REG_TMP
-   - reg is NULL or its value is discarded after pc
-   - cond is 0 or all conditions are overwritten before being used
-   ------------------------------------------------------------------ */
-
-typedef struct {
-  pCode *pc;
-  regs *reg;
-  int cond;
-} df_state_t;
-
-df_state_t *df_free_states = NULL;
-
-static df_state_t *
-df_newState (regs *reg, int cond, pCode *pc)
-{
-       df_state_t *state;
-
-       if (df_free_states) {
-         state = df_free_states;
-         df_free_states = (df_state_t *)df_free_states->pc;
-       } else {
-         state = Safe_calloc(1, sizeof(df_state_t));
-       }
-       state->pc = pc;
-       state->reg = reg;
-       state->cond = cond;
-       return state;
-}
-
-static int
-df_containsState (set *set, df_state_t *state)
-{
-       /* scan set for presence of `state' */
-       df_state_t *curr;
-       for (curr = setFirstItem (set); curr; curr = setNextItem (set))
-       {
-               if ((curr->pc == state->pc)
-                       && (curr->reg == state->reg)
-                       && (curr->cond == state->cond))
-               {
-                       /* `state' found */
-                       return 1;
-               }
-       }
-       return 0;
-}
-
-static void
-df_releaseState (df_state_t *state)
-{
-       state->pc = (pCode *)df_free_states;
-       df_free_states = (df_state_t *)state;
-       state->reg = NULL;
-       state->cond = 0;
-}
-
-static void
-df_removeStates ()
-{
-       df_state_t *next;
-       while (df_free_states)
-       {
-               next = (df_state_t *)df_free_states->pc;
-               Safe_free(df_free_states);
-               df_free_states = next;
-       } // while
-}
-
-int regIsDead (regs *reg, int cond, pCode *pc)
-{
-       set *seenStates = NULL;
-       set *todo = NULL;
-       pCode *curr;
-       df_state_t *state;
-       int result = 1;
-       
-       /* sanity checks */
-       if (reg && !regIsLocal (reg)) return 0;
-
-       pc = findNextInstruction (pc->next);
-
-       addSet (&todo, df_newState(reg, cond, pc));
-
-       while ((result == 1) && (state = getSet (&todo)))
-       {
-               int res;
-               
-               if (df_containsState (seenStates, state)) continue;
-               addSet (&seenStates, state);
-
-               curr = state->pc;
-               reg = state->reg;
-               cond = state->cond;
-               
-               //fprintf (stderr, "Checking for reg %s/cond %x at pc ", reg ? reg->name : "<none>", cond);
-               //curr->print (stderr, curr);
-
-               res = checkRegInFlow (&reg, &cond, curr);
-               switch (res)
-               {
-               case 1: /* `reg' or `cond' is read---not dead */
-                       result = 0;
-                       break;
-               case -1: /* `reg' and `cond' are discarded in this flow---need to check other open flows */
-                       break;
-               default: /* `reg' is not read and (possibly) not assigned---check successor flows */
-                       if (curr)
-                       {
-                               pCodeFlow *pcfl = PCI(curr)->pcflow;
-                               pCodeFlowLink *link;
-                               pCode *first;
-                               assert (pcfl);
-
-                               for (link = setFirstItem(pcfl->to); link; link = setNextItem (pcfl->to))
-                               {
-                                       /* add the first pCodeInstruction in the new flow to `todo' */
-                                       first = findNextInstruction (&link->pcflow->pc);
-                                       if (first) addSet (&todo, df_newState (reg, cond, first));
-                               } // for
-                       }
-                       break;
-               } // switch
-       } // while
-
-       /* clean up */
-       while (NULL != (state = getSet (&todo))) { df_releaseState (state); }
-       while (NULL != (state = getSet (&seenStates))) { df_releaseState (state); }
-
-       /* if result remained 1, `reg' is not even possibly read and thus dead */
-       return result;
-}
-
-
-
-/* ------------------------------------------------------------------
-   Safely remove a pCode.
-   This needs to check that the previous instruction was no SKIP
-   (otherwise the SKIP instruction would have to be removed as well,
-   which may not be done for SFRs (side-effects on read possible)).
-   ------------------------------------------------------------------ */
-
-extern void unBuildFlow (pBlock *pb);
-extern void RegsUnMapLiveRanges ();
-extern void BuildFlow (pBlock *pb);
-extern void LinkFlow (pBlock *pb);
-extern void BuildFlowTree (pBlock *pb);
-extern void pCodeRegMapLiveRanges (pBlock *pb);
-extern pFile *the_pFile;
-
-static int pCodeRemove (pCode *pc, const char *comment)
-{
-       pCode *pcprev, *pcnext;
-       unsigned int result = 0;
-       
-       /* Sanity checks. */
-       if (!pc) return 0;
-       if (!isPCI(pc)) return 0;
-
-       pcprev = findPrevInstruction (pc->prev);
-       if (pcprev && isPCI_SKIP(pcprev))
-       {
-               /* bail out until we know how to fix the Flow... */
-               //return 0;
-
-               /* we also need to remove the preceeding SKIP instruction(s) */
-               result = pCodeRemove (pcprev, "=DF= removing preceeding SKIP as well");
-               if (!result)
-               {
-                       /* previous instruction could not be removed -- this cannot be removed as well */
-                       return result;
-               }
-               /* FIXME: We now have to update the flow! */
-       } // if
-
-       /* do not remove pCodes with SFRs as operands (even reading them might cause side effects) */
-       {
-               regs *reg;
-               reg = getRegFromInstruction (pc);
-               /* accesses to the STATUS register aer always safe, but others... */
-               if (reg && reg->type == REG_SFR && reg->pc_type != PO_STATUS) return result;
-       }
-
-       /* MUST SUCEED FROM NOW ON (or revert the changes done since NOW ;-)) */
-       
-       /* fix flow */
-       if (PCI(pc)->pcflow && PCI(pc)->pcflow->end == pc)
-       {
-               pCode *pcprev;
-               pcprev = findPrevInstruction (pc->prev);
-               if (PCI(pcprev)->pcflow == PCI(pc)->pcflow)
-               {
-                       PCI(pc)->pcflow->end = pcprev;
-               } else {
-                       pBlock *pb = pc->pb;
-                       RegsUnMapLiveRanges();
-                       unBuildFlow(pb);
-                       BuildFlow(pb);
-                       LinkFlow(pb);
-                       BuildFlowTree(pb);
-                       for (pb = the_pFile->pbHead; pb; pb = pb->next)
-                       {
-                               pCodeRegMapLiveRanges(pb);
-                       }
-               }
-       }
-       
-       /* attach labels to next instruction */
-       pcnext = findNextInstruction (pc->next);
-       if (pcnext)
-       {
-               PCI(pcnext)->label = pBranchAppend (PCI(pcnext)->label, PCI(pc)->label);
-               if (!PCI(pcnext)->cline) PCI(pcnext)->cline = PCI(pc)->cline;
-       }
-       else
-       {
-               fprintf (stderr, "Cannot move a label...\n");
-               exit(EXIT_FAILURE);
-       }
-       
-       if (comment)
-       {
-               char buffer[512];
-               int size = 512;
-               char *pbuff = &buffer[0];
-               
-               SAFE_snprintf (&pbuff, &size, "; %s:%u(%s): %s", __FILE__, __LINE__, __FUNCTION__, comment);
-               pCodeInsertAfter(pc->prev, newpCodeCharP (&buffer[0]));
-       } // if
-
-       if (1)
-       {
-               /* replace removed pCode with out-commented version of itself */
-               char buffer[512];
-               int size = 512;
-               char *pbuff = &buffer[0];
-               
-               SAFE_snprintf (&pbuff, &size, "; %s:%u(%s): ", __FILE__, __LINE__, __FUNCTION__);
-               pCode2str (pbuff, size, pc);
-               pCodeInsertAfter(pc->prev, newpCodeCharP (&buffer[0]));
-       }
-
-       pc->destruct (pc);
-       return result+1;
-}
-
-/* ------------------------------------------------------------------
-   Find and remove dead pCodes.
-   ------------------------------------------------------------------ */
-
-static int removeIfDeadPCI (pCode *pc)
-{
-       pCode *pcnext = NULL;
-       pCode *curr;
-       unsigned int outCond;
-       unsigned int result = 0;
-       regs *dst;
-       
-       if (!pc) return 0;
-       dst = NULL;
-       
-       /* skip non-PCIs */
-       pcnext = findNextInstruction (pc->next);
-       if (!isPCI(pc)) return 0;
-
-       switch (PCI(pc)->op)
-       {
-       case POC_ADDLW:
-       case POC_ADDWF:
-       case POC_ADDFW:
-       case POC_ANDLW:
-       case POC_ANDWF:
-       case POC_ANDFW:
-       case POC_BCF:
-       case POC_BSF:
-       //case POC_BTFSC:
-       //case POC_BTFSS:
-       //case POC_CALL:
-       case POC_COMF:
-       case POC_COMFW:
-       case POC_CLRF:
-       case POC_CLRW:
-       //case POC_CLRWDT:
-       case POC_DECF:
-       case POC_DECFW:
-       //case POC_DECFSZ:
-       //case POC_DECFSZW:
-       //case POC_GOTO:
-       case POC_INCF:
-       case POC_INCFW:
-       //case POC_INCFSZ:
-       //case POC_INCFSZW:
-       case POC_IORLW:
-       case POC_IORWF:
-       case POC_IORFW:
-       case POC_MOVF:
-       case POC_MOVFW:
-       case POC_MOVLW:
-       case POC_MOVWF:
-       case POC_NOP:
-       //case POC_RETLW:
-       //case POC_RETURN:
-       //case POC_RETFIE:
-       case POC_RLF:
-       case POC_RLFW:
-       case POC_RRF:
-       case POC_RRFW:
-       case POC_SUBLW:
-       case POC_SUBWF:
-       case POC_SUBFW:
-       case POC_SWAPF:
-       case POC_SWAPFW:
-       //case POC_TRIS:
-       case POC_XORLW:
-       case POC_XORWF:
-       case POC_XORFW:
-       //case POC_BANKSEL:
-       //case POC_PAGESEL:
-               break;
-       
-       default:
-               /* do not remove unknown PCIs */
-               return 0;
-       } // switch
-
-       /* redundant checks---those instructions may never be removed */
-       if (isPCI_BRANCH(pc)) return 0;
-       if (isPCI_SKIP(pc)) return 0;
-       
-       outCond = PCI(pc)->outCond;
-       curr = pcnext;
-
-       /* unknown operands assigned to, then ignore */
-       if ((outCond & (PCC_REGISTER | PCC_C | PCC_Z | PCC_DC | PCC_W)) != outCond)
-               return 0;
-       
-       if (outCond & PCC_REGISTER)
-       {
-               dst = getRegFromInstruction (pc);
-               if (!dst) return 0;
-
-               /* special reg? */
-               if (!regIsLocal (dst)) return 0;
-               if (regIsSpecial (dst,0)) return 0;
-       }
-       
-       //fprintf (stderr, "--> checking for liveness pc "); pc->print (stderr, pc);
-       if (regIsDead (dst, outCond, pc))
-       {
-               /* no result from pc has been used -- pc is `dead' */
-               //fprintf (stderr, "--> reg %s and cond %x assumed unused\n", dst ? dst->name : "<none>", outCond);
-               //fprintf (stderr, "--> removing dead pc "); pc->print (stderr, pc);
-               result = pCodeRemove (pc, "=DF= removed dead pCode");
-       }
-       
-       return result;
-}
-
-/* ------------------------------------------------------------------
-   This routine is intended to safely replace one pCodeInstruction
-   with a different pCodeInstruction.
-   If desired, the replaced pCode will be left in (commented out) for
-   debugging.
-   Further, an optional comment can be inserted to indicate the
-   reason for the possible removal of the pCode.
-   ------------------------------------------------------------------ */
-
-static void replace_PCI (pCodeInstruction *pc, pCodeInstruction *newpc, char *comment)
-{
-  newpc->from =  pBranchAppend (newpc->from, pc->from);
-  newpc->to = pBranchAppend (newpc->to, pc->to);
-  newpc->label = pBranchAppend (newpc->label, pc->label);
-  //newpc->pcflow = pc->pcflow; // updated in pCodeInsertAfter, ->pb is as well
-  newpc->cline = pc->cline;
-
-  newpc->pc.seq = pc->pc.seq;
-
-  pCodeInsertAfter (&pc->pc, &newpc->pc);
-
-  /* FIXME: replacing pc will break the liverange maps (usedpCodes, ...) */
-  pCodeRegMapLiveRanges( pc->pBlock ); /*FIXME:UNTESTED*/
-  
-  if (comment)
-  {
-    pCodeInsertAfter (&pc->pc, newpCodeCharP (comment));
-  } // if
-
-  if (1)
-  {
-    /* replace pc with commented out version of itself */
-    char buffer[1024], buffer2[1024];
-    char *pbuff = &buffer[0];
-    int size=1024;
-    pCode2str (&buffer2[0],1024,&pc->pc);
-    SAFE_snprintf (&pbuff,&size,"%s:%u(%s): removed pCode was %s\t", __FILE__, __LINE__, __FUNCTION__, &buffer2[0]);
-    pCodeInsertAfter (&pc->pc, newpCodeCharP (&buffer[0]));
-  } // if
-
-  pc->pc.destruct (&pc->pc);
-}
-
-/* ------------------------------------------------------------------
-   Find the first (unique) assignment to `reg' (prior to pc).
-   ------------------------------------------------------------------ */
-
-pCode *findAssignmentToReg (regs *reg, pCode *pc)
-{
-       pCode *curr;
-       
-       assert (pc && isPCI(pc) && reg);
-
-       curr = findPrevInstruction (pc->prev);
-       
-       while (curr && PCI(curr)->pcflow == PCI(pc)->pcflow)
-       {
-               if (PCI(curr)->outCond & PCC_REGISTER)
-               {
-                       regs *op = getRegFromInstruction (curr);
-                       if (op && (sameRegs(op,reg)))
-                               return curr;
-               } // if
-               curr = findPrevInstruction (curr->prev);
-       } // while
-       
-       /* no assignment to reg found */
-       return NULL;
-}
-
-/* ------------------------------------------------------------------
-   Find a register that holds the same value as `reg' (an alias).
-   ------------------------------------------------------------------ */
-
-regs *findRegisterAlias (regs *reg, pCode *pc)
-{
-       pCode *curr;
-
-       if(!reg) return NULL;
-
-       if (regIsSpecial (reg, 0)) return NULL;
-
-       curr = findAssignmentToReg (reg, pc);
-
-       /* no assignment found --> no alias found */
-       if (!curr) return NULL;
-
-       switch (PCI(curr)->op)
-       {
-       case POC_MOVWF:
-               /* find previous assignment to WREG */
-               while (curr && !(PCI(curr)->outCond & PCC_W))
-                       curr = findPrevInstruction (curr->prev);
-               if (curr && PCI(curr)->op == POC_MOVFW)
-               {
-                       regs *op = getRegFromInstruction (curr);
-                       /* alias must not be changed since assignment... */
-                       if (PCI(curr)->pcop)
-                       {
-                               switch (PCI(curr)->pcop->type)
-                               {
-                               case PO_GPR_REGISTER:
-                               case PO_GPR_TEMP:
-                                       /* these operands are ok */
-                                       break;
-                               default:
-                                       /* not a plain register operand */
-                                       return NULL;
-                                       break;
-                               }
-                       }
-                       if (!op || regIsSpecial (op, 0) || !regIsUnchangedSince (op, pc, curr)) return NULL;
-                       //fprintf (stderr, "found register alias for %s: %s\n", reg->name, op && op->name ? op->name : "<no name>");
-                       return op;
-               } else {
-                       /* unknown source to WREG -- unknown register alias */
-                       return NULL;
-               }
-               break;
-       
-       default:
-               /* unhandled instruction -- assume unknown source, no alias */
-               return NULL;
-       }
-
-       /* no alias found */
-       return NULL;
-}
-
-/* ------------------------------------------------------------------
-   Analyze a single pCodeInstruction's dataflow relations and replace
-   it with a better variant if possible.
-   ------------------------------------------------------------------ */
-
-void analyzeAndReplacePCI (pCodeInstruction *pci)
-{
-       regs *op_reg, *alias_reg;
-       
-       assert (pci);
-
-       if (!isPCI(pci)) return;
-       
-       switch (pci->op)
-       {
-       case POC_MOVFW:
-       case POC_ADDFW:
-       case POC_ANDFW:
-       case POC_IORFW:
-       case POC_XORFW:
-               /* try to find a different source register */
-               op_reg = getRegFromInstruction (&pci->pc);
-               if (pci->op == POC_MOVFW) /* touches Z */
-               {
-                       pCode *assignment = findAssignmentToReg (op_reg, &pci->pc);
-                       if (assignment && isPCI(assignment) && (PCI(assignment)->op == POC_CLRF))
-                       {
-                               replace_PCI (pci, PCI(newpCode(POC_MOVLW, newpCodeOpLit(0))), "replaced with CLRF");
-                               return;
-                       }                       
-               }
-               
-               alias_reg = findRegisterAlias (op_reg, &pci->pc);
-               if (alias_reg)
-               {
-                       replace_PCI (pci, PCI(newpCode(pci->op, newpCodeOpRegFromStr (alias_reg->name))), "=DF= replaced with move from register alias");
-               }
-               break;
-
-       default:
-               /* do not optimize */
-               break;
-       } // switch
-}
-
-extern pFile *the_pFile;
-
-/* ------------------------------------------------------------------
-   Find and remove dead pCodes.
-   ------------------------------------------------------------------ */
-
-static int removeDeadPCIs (void)
-{
-       pBlock *pb;
-       unsigned int removed = 0;
-       
-       if (!the_pFile) return removed;
-       
-       do {
-               removed = 0;
-               
-               /* iterate over all pBlocks */
-               for (pb = the_pFile->pbHead; pb; pb = pb->next)
-               {
-                       pCode *pc, *pcnext = NULL;
-                       
-                       /* iterate over all pCodes */
-                       for (pc = findNextInstruction (pb->pcHead); pc; pc = pcnext)
-                       {
-                               pcnext = findNextInstruction (pc->next);
-                               removed += removeIfDeadPCI (pc);
-                       } // while
-               } // for pb
-
-               fprintf (stderr, "[removed %u dead pCodes]\n", removed);
-       } while (removed);
-       
-       return 0;
-}
-
-/* ------------------------------------------------------------------
-   This routine tries to optimize the dataflow by...
-   (1) 
-   
-   This routine leaves in dead pCodes (assignments whose results are
-   not used) -- these should be removed in a following sweep phase.
-   ------------------------------------------------------------------ */
-
-void optimizeDataflow (void)
-{
-       pBlock *pb;
-       
-       if (!the_pFile) return;
-
-       //fprintf (stderr, "%s:%u(%s): Starting optimization...\n", __FILE__, __LINE__, __FUNCTION__);
-       
-       /* iterate over all pBlocks */
-       for (pb = the_pFile->pbHead; pb; pb = pb->next)
-       {
-               pCode *pc, *pcnext = NULL;
-               
-               /* iterate over all pCodes */
-               for (pc = findNextInstruction (pb->pcHead); pc; pc = pcnext)
-               {
-                       pcnext = findNextInstruction (pc->next);
-                       analyzeAndReplacePCI (PCI(pc));
-               } // while
-       } // for pb
-
-       while (removeDeadPCIs ()) { /* remove dead codes in multiple passes */};
-       df_removeStates ();
-}
-
-#endif
-
 /*-----------------------------------------------------------------*
 * void pCodeRegOptimeRegUsage(pBlock *pb) 
 *-----------------------------------------------------------------*/
@@ -1712,16 +765,6 @@ void pCodeRegOptimizeRegUsage(int level)
        
        if(total_registers_saved == t) 
                DFPRINTF((stderr, "No registers saved on this pass\n"));
-
-
-       /*
-               fprintf(stderr,"dynamically allocated regs:\n");
-               dbg_regusage(dynAllocRegs);
-               fprintf(stderr,"stack regs:\n");
-               dbg_regusage(dynStackRegs);
-               fprintf(stderr,"direct regs:\n");
-               dbg_regusage(dynDirectRegs);
-       */
 }
 
 
@@ -1729,7 +772,7 @@ void pCodeRegOptimizeRegUsage(int level)
 * void RegsUnMapLiveRanges(set *regset)
 *
 *-----------------------------------------------------------------*/
-void  RegsSetUnMapLiveRanges(set *regset)
+static void RegsSetUnMapLiveRanges(set *regset)
 {
        regs *reg;