* src/pic/device.{c,h}: added pic14_getPIC()
[fw/sdcc] / src / pic / pcoderegs.c
index 536a9405c096be3a61f112f8e4343a9929f810d3..5c1b8d18896aeef2869e084d918af53d736b10d5 100644 (file)
@@ -161,11 +161,21 @@ void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
        
        pc = findNextInstruction(pcfl->pc.next);
        
-       while(isPCinFlow(pc,PCODE(pcfl))) {
-               
-               
+       while(pc && !isPCFL(pc)) {
+               while (pc && !isPCI(pc) && !isPCFL(pc))
+               {
+                       pc = pc->next;
+               } // while
+               if (!pc || isPCFL(pc)) continue;
+               assert( isPCI(pc) );
+
                reg = getRegFromInstruction(pc);
-               
+               #if 0
+               pc->print(stderr, pc);
+               fprintf( stderr, "--> reg %p (%s,%u), inCond/outCond: %x/%x\n",
+                       reg, reg ? reg->name : "(null)", reg ? reg->rIdx : -1,
+                       PCI(pc)->inCond, PCI(pc)->outCond );
+               #endif
                if(reg) {
                /*
                fprintf(stderr, "flow seq %d, inst seq %d  %s  ",PCODE(pcfl)->seq,pc->seq,reg->name);
@@ -182,13 +192,15 @@ void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl)
                                addSetIfnotP(& (reg->reglives.assignedpFlows), pcfl);
                        
                        addSetIfnotP(& (reg->reglives.usedpCodes), pc);
+                       reg->wasUsed = 1;
                }
                
                
-               pc = findNextInstruction(pc->next);
+               //pc = findNextInstruction(pc->next);
+               pc = pc->next;
                
        }
-       
+
 }
 
 /*-----------------------------------------------------------------*
@@ -358,6 +370,33 @@ void  RemoveRegsFromSet(set *regset)
                
        }
 }
+
+void RegsUnMapLiveRanges(void);
+extern pFile *the_pFile;
+void pic14_ReMapLiveRanges(void)
+{
+       pBlock *pb;
+       if (!the_pFile) return;
+       RegsUnMapLiveRanges();
+       for (pb = the_pFile->pbHead; pb; pb = pb->next)
+       {
+       #if 0
+               pCode *pc = findNextpCode(pb->pcHead, PC_FLOW);
+               if (pc) {
+                       pc->print( stderr, pc );
+               } else {
+                       fprintf( stderr, "unnamed pBlock\n");
+               }
+               pc = findNextInstruction(pb->pcHead);
+               while (pc) {
+                 pc->print( stderr, pc );
+                 pc = findNextInstruction(pc->next);;
+               }
+       #endif  
+               pCodeRegMapLiveRanges(pb);
+       } // for
+}
+
 /*-----------------------------------------------------------------*
 * void RemoveUnusedRegisters(void)
 *
@@ -365,6 +404,7 @@ void  RemoveRegsFromSet(set *regset)
 void RemoveUnusedRegisters(void)
 {
        /* First, get rid of registers that are used only one time */
+       pic14_ReMapLiveRanges();
        
        //RemoveRegsFromSet(dynInternalRegs);
        RemoveRegsFromSet(dynAllocRegs);
@@ -693,11 +733,23 @@ void OptimizeRegUsage(set *fregs, int optimize_multi_uses, int optimize_level)
                fprintf(stderr,"Reg: %s\n",reg->name);
                */
                
+               /* Catch inconsistently set-up live ranges
+                * (see tracker items #1469504 + #1474602)
+                * FIXME: Actually we should rather fix the
+                * computation of the liveranges instead...
+                */
+               if (!reg || !reg->reglives.usedpFlows
+                       || !reg->reglives.assignedpFlows)
+               {
+                 //fprintf( stderr, "skipping reg w/o liveranges: %s\n", reg ? reg->name : "(unknown)");
+                 continue;
+               }
+
                if(reg->type == REG_SFR || reg->type == REG_STK || reg->isPublic || reg->isExtern|| reg->isFixed) {
                        //fprintf(stderr,"skipping SFR: %s\n",reg->name);
                        continue;
                }
-               
+
                pcfl_used = setFirstItem(reg->reglives.usedpFlows);
                pcfl_assigned = setFirstItem(reg->reglives.assignedpFlows);
                
@@ -1202,7 +1254,7 @@ static int pCodeRemove (pCode *pc, const char *comment)
                if (reg && reg->type == REG_SFR && reg->pc_type != PO_STATUS) return result;
        }
 
-       /* MUST SUCEED FROM NOW ON (or ervert the changes done since NOW ;-)) */
+       /* MUST SUCEED FROM NOW ON (or revert the changes done since NOW ;-)) */
        
        /* fix flow */
        if (PCI(pc)->pcflow && PCI(pc)->pcflow->end == pc)
@@ -1236,7 +1288,7 @@ static int pCodeRemove (pCode *pc, const char *comment)
        else
        {
                fprintf (stderr, "Cannot move a label...\n");
-               exit(-1);
+               exit(EXIT_FAILURE);
        }
        
        if (comment)
@@ -1399,6 +1451,7 @@ static void replace_PCI (pCodeInstruction *pc, pCodeInstruction *newpc, char *co
   pCodeInsertAfter (&pc->pc, &newpc->pc);
 
   /* FIXME: replacing pc will break the liverange maps (usedpCodes, ...) */
+  pCodeRegMapLiveRanges( pc->pBlock ); /*FIXME:UNTESTED*/
   
   if (comment)
   {
@@ -1632,7 +1685,7 @@ void pCodeRegOptimizeRegUsage(int level)
 
 #if 0
        /* This is currently broken (need rewrite to correctly
-        * hamdle arbitrary pCodeOps instead of registers only). */
+        * handle arbitrary pCodeOps instead of registers only). */
        if (!pic14_options.disable_df)
                optimizeDataflow ();
 #endif