flat 24: mung fReturnSize before packing registers to get packRegForOneUse working...
[fw/sdcc] / src / mcs51 / ralloc.c
index 9e0ccc9db7768b57dc644ad319d4f724922cc7ff..0f01e758b96233da85799425a7aa13ee03dfc82e 100644 (file)
    You are forbidden to forbid anyone else to use, share and improve
    what you give them.   Help stamp out software-hoarding!  
 -------------------------------------------------------------------------*/
-#include <stdio.h>
-#include <stdlib.h>
-#include "SDCCglobl.h"
-#include "SDCCast.h"
-#include "SDCCmem.h"
-#include "SDCCy.h" 
-#include "SDCChasht.h"
-#include "SDCCbitv.h"
-#include "SDCCset.h"
-#include "SDCCicode.h"
-#include "SDCClabel.h"
-#include "SDCCBBlock.h"
-#include "SDCCloop.h"
-#include "SDCCcse.h"
-#include "SDCCcflow.h"
-#include "SDCCdflow.h"
-#include "SDCClrange.h"
-#include "SDCCralloc.h"
+
+#include "common.h"
+#include "ralloc.h"
+#include "gen.h"
 
 /*-----------------------------------------------------------------*/
 /* At this point we start getting processor specific although      */
@@ -87,7 +73,7 @@ regs regs8051[] =
     { REG_CND  ,CND_IDX,REG_CND , "C"  , "C"  ,  "xreg", 0, 1 },  
 };
 int mcs51_nRegs = 13;
-void spillThis (symbol *);
+static void spillThis (symbol *);
 
 /*-----------------------------------------------------------------*/
 /* allocReg - allocates register of given type                     */
@@ -283,7 +269,7 @@ static int notUsedInBlock (symbol *sym, eBBlock *ebp, iCode *ic)
 /*-----------------------------------------------------------------*/
 /* notUsedInRemaining - not used or defined in remain of the block */
 /*-----------------------------------------------------------------*/
-int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
+static int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
 {
     return ((usedInRemaining (operandFromSymbol(sym),ic) ? 0 : 1) &&
            allDefsOutOfRange (sym->defs,ic->seq,ebp->lSeq));
@@ -292,7 +278,7 @@ int notUsedInRemaining (symbol *sym, eBBlock *ebp, iCode *ic)
 /*-----------------------------------------------------------------*/
 /* allLRs - return true for all                                    */
 /*-----------------------------------------------------------------*/
-int allLRs (symbol *sym, eBBlock *ebp, iCode *ic)
+static int allLRs (symbol *sym, eBBlock *ebp, iCode *ic)
 {
     return 1;
 }
@@ -300,7 +286,7 @@ int allLRs (symbol *sym, eBBlock *ebp, iCode *ic)
 /*-----------------------------------------------------------------*/
 /* liveRangesWith - applies function to a given set of live range  */
 /*-----------------------------------------------------------------*/
-set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *),
+static set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *),
                     eBBlock *ebp, iCode *ic)
 {
     set *rset = NULL;
@@ -333,7 +319,7 @@ set *liveRangesWith (bitVect *lrs, int (func)(symbol *,eBBlock *, iCode *),
 /*-----------------------------------------------------------------*/
 /* leastUsedLR - given a set determines which is the least used    */
 /*-----------------------------------------------------------------*/
-symbol *leastUsedLR (set *sset)
+static symbol *leastUsedLR (set *sset)
 {
     symbol *sym = NULL, *lsym = NULL ;
     
@@ -364,7 +350,7 @@ symbol *leastUsedLR (set *sset)
 /*-----------------------------------------------------------------*/
 /* noOverLap - will iterate through the list looking for over lap  */
 /*-----------------------------------------------------------------*/
-int noOverLap (set *itmpStack, symbol *fsym)
+static int noOverLap (set *itmpStack, symbol *fsym)
 {
     symbol *sym;
    
@@ -382,7 +368,7 @@ int noOverLap (set *itmpStack, symbol *fsym)
 /*-----------------------------------------------------------------*/
 /* isFree - will return 1 if the a free spil location is found     */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(isFree)
+static DEFSETFUNC(isFree)
 {
     symbol *sym = item;
     V_ARG(symbol **,sloc);
@@ -409,7 +395,7 @@ DEFSETFUNC(isFree)
 /*-----------------------------------------------------------------*/
 /* spillLRWithPtrReg :- will spil those live ranges which use PTR  */
 /*-----------------------------------------------------------------*/
-void spillLRWithPtrReg (symbol *forSym)
+static void spillLRWithPtrReg (symbol *forSym)
 {
     symbol *lrsym;
     regs *r0,*r1;
@@ -451,7 +437,7 @@ void spillLRWithPtrReg (symbol *forSym)
 /*-----------------------------------------------------------------*/
 /* createStackSpil - create a location on the stack to spil        */
 /*-----------------------------------------------------------------*/
-symbol *createStackSpil (symbol *sym)
+static symbol *createStackSpil (symbol *sym)
 {
     symbol *sloc= NULL;
     int useXstack, model, noOverlay;
@@ -525,7 +511,7 @@ symbol *createStackSpil (symbol *sym)
 /*-----------------------------------------------------------------*/
 /* isSpiltOnStack - returns true if the spil location is on stack  */
 /*-----------------------------------------------------------------*/
-bool isSpiltOnStack (symbol *sym)
+static bool isSpiltOnStack (symbol *sym)
 {
     link *etype;
 
@@ -551,7 +537,7 @@ bool isSpiltOnStack (symbol *sym)
 /*-----------------------------------------------------------------*/
 /* spillThis - spils a specific operand                            */
 /*-----------------------------------------------------------------*/
-void spillThis (symbol *sym)
+static void spillThis (symbol *sym)
 {
     int i;
     /* if this is rematerializable or has a spillLocation
@@ -590,7 +576,7 @@ void spillThis (symbol *sym)
 /*-----------------------------------------------------------------*/
 /* selectSpil - select a iTemp to spil : rather a simple procedure */
 /*-----------------------------------------------------------------*/
-symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
+static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
 {
     bitVect *lrcs= NULL ; 
     set *selectS ;
@@ -683,7 +669,7 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym)
 /*-----------------------------------------------------------------*/
 /* spilSomething - spil some variable & mark registers as free     */
 /*-----------------------------------------------------------------*/
-bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
+static bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym)
 {
     symbol *ssym;
     int i ;
@@ -771,7 +757,7 @@ regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym)
 /*-----------------------------------------------------------------*/
 /* getRegGpr - will try for GPR if not spil                        */
 /*-----------------------------------------------------------------*/
-regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
+static regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
 {
     regs *reg;
 
@@ -783,7 +769,7 @@ regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym)
     if (!mcs51_ptrRegReq)
        if ((reg = allocReg(REG_PTR)))
            return reg ;
-
+       
     /* we have to spil */
     if (!spilSomething (ic,ebp,sym))
        return NULL ;
@@ -811,7 +797,7 @@ static bool symHasReg(symbol *sym,regs *reg)
 /* deassignLRs - check the live to and if they have registers & are*/
 /*               not spilt then free up the registers              */
 /*-----------------------------------------------------------------*/
-void deassignLRs (iCode *ic, eBBlock *ebp)
+static void deassignLRs (iCode *ic, eBBlock *ebp)
 {
     symbol *sym;
     int k;
@@ -904,7 +890,7 @@ void deassignLRs (iCode *ic, eBBlock *ebp)
 /*-----------------------------------------------------------------*/
 /* reassignLR - reassign this to registers                         */
 /*-----------------------------------------------------------------*/
-void reassignLR (operand *op)
+static void reassignLR (operand *op)
 {
     symbol *sym = OP_SYMBOL(op);
     int i;
@@ -924,7 +910,7 @@ void reassignLR (operand *op)
 /*-----------------------------------------------------------------*/
 /* willCauseSpill - determines if allocating will cause a spill    */
 /*-----------------------------------------------------------------*/
-int willCauseSpill ( int nr, int rt)
+static int willCauseSpill ( int nr, int rt)
 {
     /* first check if there are any avlb registers
        of te type required */
@@ -987,7 +973,7 @@ static void positionRegs (symbol *result, symbol *opsym, int lineno)
 /*-----------------------------------------------------------------*/
 /* serialRegAssign - serially allocate registers to the variables  */
 /*-----------------------------------------------------------------*/
-void serialRegAssign (eBBlock **ebbs, int count)
+static void serialRegAssign (eBBlock **ebbs, int count)
 {
     int i;
 
@@ -1084,7 +1070,9 @@ void serialRegAssign (eBBlock **ebbs, int count)
                
                /* if we need ptr regs for the right side
                   then mark it */
-               if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) < 2) {
+               if (POINTER_GET(ic) && getSize(OP_SYMBOL(IC_LEFT(ic))->type) 
+                   <= PTRSIZE) 
+               {
                    mcs51_ptrRegReq++;
                    ptrRegSet = 1;
                }
@@ -1127,7 +1115,7 @@ void serialRegAssign (eBBlock **ebbs, int count)
 /*-----------------------------------------------------------------*/
 /* rUmaskForOp :- returns register mask for an operand             */
 /*-----------------------------------------------------------------*/
-bitVect *rUmaskForOp (operand *op)
+static bitVect *rUmaskForOp (operand *op)
 {
     bitVect *rumask;
     symbol *sym;
@@ -1157,7 +1145,7 @@ bitVect *rUmaskForOp (operand *op)
 /*-----------------------------------------------------------------*/
 /* regsUsedIniCode :- returns bit vector of registers used in iCode*/
 /*-----------------------------------------------------------------*/
-bitVect *regsUsedIniCode (iCode *ic)
+static bitVect *regsUsedIniCode (iCode *ic)
 {
     bitVect *rmask = newBitVect(mcs51_nRegs);
 
@@ -1197,7 +1185,7 @@ bitVect *regsUsedIniCode (iCode *ic)
 /*-----------------------------------------------------------------*/
 /* createRegMask - for each instruction will determine the regsUsed*/
 /*-----------------------------------------------------------------*/
-void createRegMask (eBBlock **ebbs, int count)
+static void createRegMask (eBBlock **ebbs, int count)
 {
     int i;
 
@@ -1261,7 +1249,7 @@ void createRegMask (eBBlock **ebbs, int count)
 /*-----------------------------------------------------------------*/
 /* rematStr - returns the rematerialized string for a remat var    */
 /*-----------------------------------------------------------------*/
-char *rematStr (symbol *sym)
+static char *rematStr (symbol *sym)
 {
     char *s = buffer;   
     iCode *ic = sym->rematiCode;    
@@ -1288,7 +1276,7 @@ char *rematStr (symbol *sym)
 /*-----------------------------------------------------------------*/
 /* regTypeNum - computes the type & number of registers required   */
 /*-----------------------------------------------------------------*/
-void regTypeNum ()
+static void regTypeNum ()
 {
     symbol *sym;
     int k;
@@ -1379,7 +1367,7 @@ void regTypeNum ()
 /*-----------------------------------------------------------------*/
 /* freeAllRegs - mark all registers as free                        */
 /*-----------------------------------------------------------------*/
-void freeAllRegs()
+static void freeAllRegs()
 {
     int i;
 
@@ -1390,7 +1378,7 @@ void freeAllRegs()
 /*-----------------------------------------------------------------*/
 /* deallocStackSpil - this will set the stack pointer back         */
 /*-----------------------------------------------------------------*/
-DEFSETFUNC(deallocStackSpil)
+static DEFSETFUNC(deallocStackSpil)
 {
     symbol *sym = item;
 
@@ -1464,7 +1452,7 @@ static iCode *farSpacePackable (iCode *ic)
 /*-----------------------------------------------------------------*/
 /* packRegsForAssign - register reduction for assignment           */
 /*-----------------------------------------------------------------*/
-int packRegsForAssign (iCode *ic,eBBlock *ebp)
+static int packRegsForAssign (iCode *ic,eBBlock *ebp)
 {
     iCode *dic, *sic;
     
@@ -1500,7 +1488,13 @@ int packRegsForAssign (iCode *ic,eBBlock *ebp)
 
        if (SKIP_IC2(dic))
            continue;
-       
+
+       if (IS_TRUE_SYMOP(IC_RESULT(dic)) &&
+           IS_OP_VOLATILE(IC_RESULT(dic))) {
+               dic = NULL;
+               break;
+       }
+
        if (IS_SYMOP(IC_RESULT(dic)) &&
            IC_RESULT(dic)->key == IC_RIGHT(ic)->key) {
            if (POINTER_SET(dic))
@@ -1569,6 +1563,7 @@ pack:
     }
         
     remiCodeFromeBBlock(ebp,ic);
+    hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
     return 1;
     
 }
@@ -1576,7 +1571,7 @@ pack:
 /*-----------------------------------------------------------------*/
 /* findAssignToSym : scanning backwards looks for first assig found*/
 /*-----------------------------------------------------------------*/
-iCode *findAssignToSym (operand *op,iCode *ic)
+static iCode *findAssignToSym (operand *op,iCode *ic)
 {
     iCode *dic;
 
@@ -1648,7 +1643,7 @@ iCode *findAssignToSym (operand *op,iCode *ic)
 /*-----------------------------------------------------------------*/
 /* packRegsForSupport :- reduce some registers for support calls   */
 /*-----------------------------------------------------------------*/
-int packRegsForSupport (iCode *ic, eBBlock *ebp)
+static int packRegsForSupport (iCode *ic, eBBlock *ebp)
 {
     int change = 0 ;
     /* for the left & right operand :- look to see if the
@@ -1670,7 +1665,8 @@ int packRegsForSupport (iCode *ic, eBBlock *ebp)
        IC_LEFT(ic)->operand.symOperand =
            IC_RIGHT(dic)->operand.symOperand;
        IC_LEFT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
-       remiCodeFromeBBlock(ebp,dic);   
+       remiCodeFromeBBlock(ebp,dic);
+       hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
        change++;      
     }
     
@@ -1702,6 +1698,7 @@ int packRegsForSupport (iCode *ic, eBBlock *ebp)
        IC_RIGHT(ic)->key = IC_RIGHT(dic)->operand.symOperand->key;
        
        remiCodeFromeBBlock(ebp,dic);
+       hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
        change ++;
     }
    
@@ -1725,7 +1722,7 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
     
     /* only upto 2 bytes since we cannot predict
        the usage of b, & acc */
-    if (getSize(operandType(op)) > 2 && 
+    if (getSize(operandType(op)) >  (fReturnSize - 2) &&
        ic->op != RETURN             &&
        ic->op != SEND)
        return NULL;
@@ -1814,7 +1811,7 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp)
           operation is a '*','/' or '%' then 'b' may
           cause a problem */
        if (( dic->op == '%' || dic->op == '/' || dic->op == '*') &&
-           getSize(aggrToPtr(operandType(op),FALSE)) >= 3)
+           getSize(operandType(op)) >= 3)
                return NULL;
 
        /* if left or right or result is in far space */
@@ -1864,7 +1861,7 @@ static bool isBitwiseOptimizable (iCode *ic)
 /*-----------------------------------------------------------------*/
 /* packRegsForAccUse - pack registers for acc use                  */
 /*-----------------------------------------------------------------*/
-void packRegsForAccUse (iCode *ic)
+static void packRegsForAccUse (iCode *ic)
 {
     iCode *uic;
     
@@ -2009,14 +2006,15 @@ static void packForPush(iCode *ic, eBBlock *ebp)
                                bitVectFirstBit(OP_DEFS(IC_LEFT(ic))))))
        return ;
 
-    if (dic->op != '=' || POINTER_SET(dic) || IS_ITEMP(IC_RESULT(dic)))
+    if (dic->op != '=' || POINTER_SET(dic))
        return;
 
     /* we now we know that it has one & only one def & use
        and the that the definition is an assignment */
     IC_LEFT(ic) = IC_RIGHT(dic);
 
-    remiCodeFromeBBlock(ebp,dic);      
+    remiCodeFromeBBlock(ebp,dic);
+    hTabDeleteItem (&iCodehTab,dic->key,dic,DELETE_ITEM,NULL);
 }
 
 /*-----------------------------------------------------------------*/
@@ -2192,6 +2190,7 @@ static void packRegisters (eBBlock *ebp)
                    if (IS_ARITHMETIC_OP(dic)) {
                        IC_RESULT(dic) = IC_RESULT(ic);
                        remiCodeFromeBBlock(ebp,ic);
+                       hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
                        ic = ic->prev;
                    } else
                        OP_SYMBOL(IC_RIGHT(ic))->ruonly =  0;
@@ -2206,6 +2205,7 @@ static void packRegisters (eBBlock *ebp)
                    if (dic) {
                        IC_RESULT(dic) = IC_RESULT(ic);
                        remiCodeFromeBBlock(ebp,ic);
+                       hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL);
                        ic = ic->prev;
                    }
                }