Yet another reg alloc bug uncovered by ds390
authorsandeep <sandeep@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 23 Sep 2000 17:58:53 +0000 (17:58 +0000)
committersandeep <sandeep@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 23 Sep 2000 17:58:53 +0000 (17:58 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@402 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/SDCCicode.h
src/SDCClrange.c
src/SDCCsymt.h
src/avr/ralloc.c
src/avr/ralloc.h
src/ds390/ralloc.c
src/mcs51/ralloc.c
src/z80/ralloc.c

index eb0e77b03601d04f435de82808f1edc4cdd06b15..f5059169016bae499fa2ccbd72191c6e0e4dba1f 100644 (file)
@@ -67,6 +67,7 @@ typedef enum {
 #define OP_LIVEFROM(op)    op->operand.symOperand->liveFrom
 #define OP_LIVETO(op)      op->operand.symOperand->liveTo
 #define OP_REQV(op)        op->operand.symOperand->reqv
+#define OP_ISLIVE_FCALL(op) (IS_ITEMP(op) && OP_SYMBOL(op)->isLiveFcall)
 
 /* typedef for operand */
 typedef struct operand {
@@ -79,7 +80,7 @@ typedef struct operand {
     unsigned int  isParm   :1 ;  /* is a parameter        */
     unsigned int  isLiteral:1 ;  /* operand is literal    */
     unsigned int  noSpilLoc:1 ;  /* cannot be assigned a spil location */
-    
+
     unsigned key ;
     int      parmBytes;
     union {
index 583aeb496f040c52ff0e28bc81933973627eebe6..bba270ef3f4e9788f3da3041eee9655212dfe02c 100644 (file)
@@ -514,9 +514,12 @@ void rlivePoint (eBBlock **ebbs, int count)
            for ( lrange = hTabFirstItem(liveRanges,&k); lrange;
                  lrange = hTabNextItem(liveRanges,&k)) {
 
+                   /* if it is live then add the lrange to ic->rlive */
                if (lrange->liveFrom <= ic->seq &&
-                   lrange->liveTo   >= ic->seq )
-                   ic->rlive = bitVectSetBit(ic->rlive,lrange->key);
+                   lrange->liveTo   >= ic->seq ) {
+                       lrange->isLiveFcall = (ic->op == CALL || ic->op == PCALL);
+                       ic->rlive = bitVectSetBit(ic->rlive,lrange->key);
+               }
            }
        }
     }  
index 0e1a7193bf706ca6c6b1cc9b4d0524ee204196b6..1829a3bf9272621f28107f87ff9c8372bc534418 100644 (file)
@@ -190,7 +190,7 @@ typedef struct symbol {
     /* following flags are used by the backend
        for code generation and can be changed
        if a better scheme for backend is thought of */
-
+    unsigned isLiveFcall:1      ;  /* is live at or across a function call */
     unsigned isspilt    :1      ;  /* has to be spilt */
     unsigned remat      :1      ;  /* can be remateriazed */
     unsigned isptr      :1      ;  /* is a pointer */
index 05e541a7ab0573a886dbcf2915fb2116e67254e0..2025960574646c7c18088c9e0047416480c5a80a 100644 (file)
@@ -619,11 +619,13 @@ static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
        if (!_G.blockSpil && 
            (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
            sym = leastUsedLR (selectS);
-           if (!sym->remat) {
-               sym->remainSpil = 1;
-               _G.blockSpil++;
+           if (sym != forSym) {
+               if (!sym->remat) {
+                   sym->remainSpil = 1;
+                   _G.blockSpil++;
+               }
+               return sym;
            }
-           return sym;
        }
     }   
 
@@ -1310,13 +1312,17 @@ static void regTypeNum ()
            /* determine the type of register required */
            if (sym->nRegs == 2   && /* size is two */
                IS_PTR(sym->type) && /* is a pointer */
-               sym->uptr)   {        /* has has pointer usage i.e. get/set pointer */
+               sym->uptr)   {        /* has pointer usage i.e. get/set pointer */
                sym->regType = REG_PTR ;
                avr_ptrRegReq++;
            }
-           else 
-               sym->regType = REG_GPR ;
-           
+           else {
+               /* live accross a function call then gpr else scratch */
+               if (sym->isLiveFcall)
+                   sym->regType = REG_GPR ;
+               else
+                   sym->regType = REG_SCR ;
+           }
        } else 
            /* for the first run we don't provide */
            /* registers for true symbols we will */
@@ -2211,6 +2217,7 @@ static void preAssignParms (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void setDefaultRegs(eBBlock **ebbs,int count)
 {
+    int i ;
 
     /* if no pointer registers required in this function
        then mark r26-27 & r30-r31 as GPR & free */
@@ -2239,17 +2246,25 @@ static void setDefaultRegs(eBBlock **ebbs,int count)
        regsAVR[R1_IDX].isFree =
        regsAVR[R24_IDX].isFree =
        regsAVR[R25_IDX].isFree = 0;
-
+    
     /* if this has no function calls then we need
        to do something special 
        a) pre-assign registers to parameters RECEIVE
        b) mark the remaining parameter regs as free */
     if (!currFunc->hasFcall) {
+       /* mark the parameter regs as GPR */
+       for (i= R16_IDX ; i <= R23_IDX ;i++) {
+           regsAVR[i].type = REG_GPR;
+           regsAVR[i].isFree = 1;
+       }
        preAssignParms(ebbs[0]->sch);
     } else {
-       int i=0;
-       for (i= R16_IDX ; i <= R23_IDX ;i++)
-           regsAVR[i].isFree = 0;
+
+       /* otherwise mark them as free scratch */
+       for (i= R16_IDX ; i <= R23_IDX ;i++) {
+           regsAVR[i].type = REG_SCR;
+           regsAVR[i].isFree = 1;
+       }
     }
 
     /* Y - is not allocated (it is the stack frame) */
@@ -2268,7 +2283,6 @@ void avr_assignRegisters (eBBlock **ebbs, int count)
     setToNull((void *)&_G.funcrUsed);
     avr_ptrRegReq = _G.stackExtend = _G.dataExtend = 0;
 
-    /* setup other default register allocation */
     /* change assignments this will remove some
        live ranges reducing some register pressure */
     for (i = 0 ; i < count ;i++ )
index 303c6b93eb86a971a4862b09c04dfb36545eebad..f293e60cec9a77ff5e801ca5a6b74e676dac4ca8 100644 (file)
@@ -38,6 +38,7 @@ enum { R0_IDX = 0, R1_IDX , R2_IDX , R3_IDX , R4_IDX ,
 
 #define REG_PTR 0x01
 #define REG_GPR 0x02
+#define REG_SCR 0x03
 #define REG_CND 0x04
 
 /* definition for the registers */
index a9061c92469fddea0d764cac50b8fa26481340f4..ecec03eafef81194f653bf18ff7a3cebab333bdb 100644 (file)
@@ -629,11 +629,13 @@ static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
           used in the remainder of the block */
        if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
            sym = leastUsedLR (selectS);
-           if (!sym->remat) {
-               sym->remainSpil = 1;
-               _G.blockSpil++;
+           if (sym != forSym) {
+               if (!sym->remat) {
+                   sym->remainSpil = 1;
+                   _G.blockSpil++;
+               }
+               return sym;
            }
-           return sym;
        }
     }   
 
index dd6d5a73e54c75cbde4b3232e92e2fd908dc5c5b..2a3726c340fe7a6fd705f54add137b535b9f6c08 100644 (file)
@@ -627,11 +627,13 @@ static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
           used in the remainder of the block */
        if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
            sym = leastUsedLR (selectS);
-           if (!sym->remat) {
-               sym->remainSpil = 1;
-               _G.blockSpil++;
+           if (sym != forSym) {
+               if (!sym->remat) {
+                   sym->remainSpil = 1;
+                   _G.blockSpil++;
+               }
+               return sym;
            }
-           return sym;
        }
     }   
 
index 9f42f5918c4c2e69dd3cb819abc8f3c0fb328d09..fc224eb42d34f840931c8bfaa93b3e8e1b256523 100644 (file)
@@ -569,11 +569,13 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
           used in the remainder of the block */
        if (!blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) {
            sym = leastUsedLR (selectS);
-           if (!sym->remat) {
-               sym->remainSpil = 1;
-               blockSpil++;
+           if (sym != ForSym) {
+               if (!sym->remat) {
+                   sym->remainSpil = 1;
+                   blockSpil++;
+               }
+               return sym;
            }
-           return sym;
        }
     }
     /* find live ranges with spillocation && not used as pointers */