* src/SDCCsymt.h,
[fw/sdcc] / src / ds390 / ralloc.c
index 3f04aa2312638b1c16eeba0efed61b278221e105..8760bd7b50b06629ff0f87189ccdcdc9ec75594a 100644 (file)
@@ -362,7 +362,7 @@ leastUsedLR (set * sset)
 
     }
 
-  setToNull ((void **) &sset);
+  setToNull ((void *) &sset);
   sym->blockSpil = 0;
   return sym;
 }
@@ -605,12 +605,12 @@ spillThis (symbol * sym)
        sym->regs[i] = NULL;
       }
 
-  /* if spilt on stack then free up r0 & r1 
+  /* if spilt on stack then free up r0 & r1
      if they could have been assigned to some
      LIVE ranges */
-  if (!ds390_ptrRegReq && isSpiltOnStack (sym))
+  if (!ds390_ptrRegReq && isSpiltOnStack (sym) && !options.stack10bit)
     {
-      ds390_ptrRegReq += !options.stack10bit;
+      ds390_ptrRegReq ++;
       spillLRWithPtrReg (sym);
     }
 
@@ -802,6 +802,7 @@ static regs *
 getRegPtr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
 tryAgain:
   /* try for a ptr type */
@@ -816,6 +817,11 @@ tryAgain:
   if (!spilSomething (ic, ebp, sym))
     return NULL;
 
+  /* make sure partially assigned registers aren't reused */
+  for (j=0; j<=sym->nRegs; j++)
+    if (sym->regs[j])
+      sym->regs[j]->isFree = 0;
+      
   /* this looks like an infinite loop but 
      in really selectSpil will abort  */
   goto tryAgain;
@@ -828,6 +834,7 @@ static regs *
 getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym)
 {
   regs *reg;
+  int j;
 
 tryAgain:
   /* try for gpr type */
@@ -842,6 +849,11 @@ tryAgain:
   if (!spilSomething (ic, ebp, sym))
     return NULL;
 
+  /* make sure partially assigned registers aren't reused */
+  for (j=0; j<=sym->nRegs; j++)
+    if (sym->regs[j])
+      sym->regs[j]->isFree = 0;
+      
   /* this looks like an infinite loop but 
      in really selectSpil will abort  */
   goto tryAgain;
@@ -1198,6 +1210,31 @@ void reassignUnusedLRs (bitVect *unused)
     }
 }
 
+/*------------------------------------------------------------------*/
+/* verifyRegsAssigned - make sure an iTemp is properly initialized; */
+/* it should either have registers or have beed spilled. Otherwise, */
+/* there was an uninitialized variable, so just spill this to get   */
+/* the operand in a valid state.                                    */
+/*------------------------------------------------------------------*/
+static void
+verifyRegsAssigned (operand *op, iCode * ic)
+{
+  symbol * sym;
+  
+  if (!op) return;
+  if (!IS_ITEMP (op)) return;
+  
+  sym = OP_SYMBOL (op);
+  if (sym->isspilt) return;
+  if (!sym->nRegs) return;
+  if (sym->regs[0]) return;
+  
+  werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, 
+           sym->prereqv ? sym->prereqv->name : sym->name);
+  spillThis (sym);
+}
+
+
 /*-----------------------------------------------------------------*/
 /* serialRegAssign - serially allocate registers to the variables  */
 /*-----------------------------------------------------------------*/
@@ -1367,6 +1404,40 @@ serialRegAssign (eBBlock ** ebbs, int count)
        }
       reassignUnusedLRs(unusedLRs);
     }
+
+    /* Check for and fix any problems with uninitialized operands */
+    for (i = 0; i < count; i++)
+      {
+       iCode *ic;
+
+       if (ebbs[i]->noPath &&
+           (ebbs[i]->entryLabel != entryLabel &&
+            ebbs[i]->entryLabel != returnLabel))
+           continue;
+
+       for (ic = ebbs[i]->sch; ic; ic = ic->next)
+         {
+           if (SKIP_IC2 (ic))
+             continue;
+
+           if (ic->op == IFX)
+             {
+               verifyRegsAssigned (IC_COND (ic), ic);
+               continue;
+             }
+
+           if (ic->op == JUMPTABLE)
+             {
+               verifyRegsAssigned (IC_JTCOND (ic), ic);
+               continue;
+             }
+
+           verifyRegsAssigned (IC_RESULT (ic), ic);
+           verifyRegsAssigned (IC_LEFT (ic), ic);
+           verifyRegsAssigned (IC_RIGHT (ic), ic);
+          }
+      }    
+    
 }
 
 /*-----------------------------------------------------------------*/
@@ -1377,6 +1448,7 @@ static void fillGaps()
     symbol *sym =NULL;
     int key =0;    
     int loop = 0, change;
+    int pass;
 
     if (getenv("DISABLE_FILL_GAPS")) return;
     
@@ -1468,44 +1540,53 @@ static void fillGaps()
                    sym->regs[i] = getRegGprNoSpil ();            
            }
            
-           /* for all its definitions & uses check if the registers
+           /* For all its definitions check if the registers
               allocated needs positioning NOTE: we can position
               only ONCE if more than One positioning required 
-              then give up */
+              then give up.
+              We may need to perform the checks twice; once to
+              position the registers as needed, the second to
+              verify any register repositioning is still
+              compatible.
+              */
            sym->isspilt = 0;
-           for (i = 0 ; i < sym->defs->size ; i++ ) {
-               if (bitVectBitValue(sym->defs,i)) {
-                   iCode *ic;
-                   if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
-                   if (SKIP_IC(ic)) continue;
-                   assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
-                   /* if left is assigned to registers */
-                   if (IS_SYMOP(IC_LEFT(ic)) && 
-                       bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
-                       pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0);
-                   }
-                   if (IS_SYMOP(IC_RIGHT(ic)) && 
-                       bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
-                       pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0);
+            for (pass=0; pass<2; pass++) {
+               for (i = 0 ; i < sym->defs->size ; i++ ) {
+                   if (bitVectBitValue(sym->defs,i)) {
+                       iCode *ic;
+                       if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+                       if (SKIP_IC(ic)) continue;
+                       assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */
+                        /* if left is assigned to registers */
+                        if (IS_SYMOP(IC_LEFT(ic)) && 
+                         bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) {
+                           pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0);
+                       }
+                       if (IS_SYMOP(IC_RIGHT(ic)) && 
+                         bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) {
+                           pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0);
+                       }
+                       if (pdone > 1) break;
                    }
-                   if (pdone > 1) break;
-               }
-           }
-           for (i = 0 ; i < sym->uses->size ; i++ ) {
-               if (bitVectBitValue(sym->uses,i)) {
-                   iCode *ic;
-                   if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
-                   if (SKIP_IC(ic)) continue;
-                   if (POINTER_SET(ic) || POINTER_GET(ic)) continue ;
-                   
-                   /* if result is assigned to registers */
-                   if (IS_SYMOP(IC_RESULT(ic)) && 
-                       bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
-                       pdone += (positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)))>0);
+               }
+               for (i = 0 ; i < sym->uses->size ; i++ ) {
+                   if (bitVectBitValue(sym->uses,i)) {
+                       iCode *ic;
+                       if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ;
+                       if (SKIP_IC(ic)) continue;
+                       if (POINTER_SET(ic) || POINTER_GET(ic)) continue ;
+
+                       /* if result is assigned to registers */
+                       if (IS_SYMOP(IC_RESULT(ic)) && 
+                         bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RESULT(ic))->key)) {
+                           pdone += (positionRegs(sym,OP_SYMBOL(IC_RESULT(ic)))>0);
+                       }
+                       if (pdone > 1) break;
                    }
-                   if (pdone > 1) break;
-               }
-           }
+               }
+                if (pdone == 0) break; /* second pass only if regs repositioned */
+               if (pdone > 1) break;
+            }
            /* had to position more than once GIVE UP */
            if (pdone > 1) {
                /* UNDO all the changes we made to try this */
@@ -1661,7 +1742,7 @@ createRegMask (eBBlock ** ebbs, int count)
                          "createRegMask cannot find live range");
                  exit (0);
                }
-             
+#if 0
              /* special case for ruonly */
              if (sym->ruonly && sym->liveFrom != sym->liveTo) {
                  int size = getSize(sym->type);
@@ -1670,6 +1751,7 @@ createRegMask (eBBlock ** ebbs, int count)
                      ic->rMask = bitVectSetBit (ic->rMask, j++);
                  continue ;
              }
+#endif
              /* if no register assigned to it */
              if (!sym->nRegs || sym->isspilt)
                continue;
@@ -3015,6 +3097,10 @@ ds390_assignRegisters (eBBlock ** ebbs, int count)
   for (i = 0; i < count; i++)
     packRegisters (ebbs[i]);
 
+  /* liveranges probably changed by register packing
+     so we compute them again */
+  recomputeLiveRanges (ebbs, count);
+
   if (options.dump_pack)
     dumpEbbsToFileExt (DUMP_PACK, ebbs, count);
 
@@ -3070,8 +3156,8 @@ ds390_assignRegisters (eBBlock ** ebbs, int count)
   /* free up any _G.stackSpil locations allocated */
   applyToSet (_G.stackSpil, deallocStackSpil);
   _G.slocNum = 0;
-  setToNull ((void **) &_G.stackSpil);
-  setToNull ((void **) &_G.spiltSet);
+  setToNull ((void *) &_G.stackSpil);
+  setToNull ((void *) &_G.spiltSet);
   /* mark all registers as free */
   ds390_nRegs = 8;
   freeAllRegs ();