X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fds390%2Fralloc.c;h=f4f837b2423ebcd879c02d4da3bc378e30db397e;hb=ebe5ea72452272b27f7c45c7b79a5ef32eb88036;hp=c00e4994125c62c03157108b9cce720123f64175;hpb=05ab8b7668ae207babfaaf1a3f93ed722bb5c275;p=fw%2Fsdcc diff --git a/src/ds390/ralloc.c b/src/ds390/ralloc.c index c00e4994..f4f837b2 100644 --- a/src/ds390/ralloc.c +++ b/src/ds390/ralloc.c @@ -36,6 +36,8 @@ /* since the pack the registers depending strictly on the MCU */ /*-----------------------------------------------------------------*/ +#define D(x) + /* Global data */ static struct { @@ -66,20 +68,22 @@ regs regs390[] = {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1, 1}, {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1, 1}, {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1, 1}, + {REG_GPR, DPL_IDX, REG_GPR, "dpl", "dpl", "dpl", 0, 0, 0}, + {REG_GPR, DPH_IDX, REG_GPR, "dph", "dph", "dph", 0, 0, 0}, + {REG_GPR, DPX_IDX, REG_GPR, "dpx", "dpx", "dpx", 0, 0, 0}, + {REG_GPR, B_IDX, REG_GPR, "b", "b", "b", 0, 0, 0}, {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 0, 0}, {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 0, 0}, {REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 0, 0}, {REG_GPR, X11_IDX, REG_GPR, "x11", "x11", "xreg", 3, 0, 0}, {REG_GPR, X12_IDX, REG_GPR, "x12", "x12", "xreg", 4, 0, 0}, {REG_CND, CND_IDX, REG_GPR, "C", "C", "xreg", 0, 0, 0}, - {REG_GPR, DPL_IDX, REG_GPR, "dpl", "dpl", "dpl", 0, 0, 0}, - {REG_GPR, DPH_IDX, REG_GPR, "dph", "dph", "dph", 0, 0, 0}, - {REG_GPR, DPX_IDX, REG_GPR, "dpx", "dpx", "dpx", 0, 0, 0}, - {REG_GPR, B_IDX, REG_GPR, "b", "b", "b", 0, 0, 0}, }; int ds390_nRegs = 13; static void spillThis (symbol *); static void freeAllRegs (); +static iCode * packRegsDPTRuse (operand *); +static int packRegsDPTRnuse (operand *,int); /*-----------------------------------------------------------------*/ /* allocReg - allocates register of given type */ @@ -186,30 +190,17 @@ nfreeRegsType (int type) } + /*-----------------------------------------------------------------*/ -/* allDefsOutOfRange - all definitions are out of a range */ +/* isOperandInReg - returns true if operand is currently in regs */ /*-----------------------------------------------------------------*/ -static bool -allDefsOutOfRange (bitVect * defs, int fseq, int toseq) +static int isOperandInReg(operand *op) { - int i; - - if (!defs) - return TRUE; - - for (i = 0; i < defs->size; i++) - { - iCode *ic; - - if (bitVectBitValue (defs, i) && - (ic = hTabItemWithKey (iCodehTab, i)) && - (ic->seq >= fseq && ic->seq <= toseq)) - - return FALSE; - - } - - return TRUE; + if (!IS_SYMOP(op)) return 0; + if (OP_SYMBOL(op)->ruonly) return 1; + if (OP_SYMBOL(op)->accuse) return 1; + if (OP_SYMBOL(op)->dptr) return 1; + return bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(op)->key); } /*-----------------------------------------------------------------*/ @@ -288,17 +279,6 @@ rematable (symbol * sym, eBBlock * ebp, iCode * ic) return sym->remat; } -/*-----------------------------------------------------------------*/ -/* notUsedInBlock - not used in this block */ -/*-----------------------------------------------------------------*/ -static int -notUsedInBlock (symbol * sym, eBBlock * ebp, iCode * ic) -{ - return (!bitVectBitsInCommon (sym->defs, ebp->usesDefs) && - allDefsOutOfRange (sym->defs, ebp->fSeq, ebp->lSeq)); -/* return (!bitVectBitsInCommon(sym->defs,ebp->usesDefs)); */ -} - /*-----------------------------------------------------------------*/ /* notUsedInRemaining - not used or defined in remain of the block */ /*-----------------------------------------------------------------*/ @@ -504,7 +484,8 @@ createStackSpil (symbol * sym) we need to allocate this on the stack : this is really a hack!! but cannot think of anything better at this time */ - if (sprintf (slocBuffer, "sloc%d", _G.slocNum++) >= sizeof (slocBuffer)) + if (SNPRINTF (slocBuffer, sizeof(slocBuffer), + "sloc%d", _G.slocNum++) >= sizeof (slocBuffer)) { fprintf (stderr, "***Internal error: slocBuffer overflowed: %s:%d\n", __FILE__, __LINE__); @@ -523,6 +504,8 @@ createStackSpil (symbol * sym) } SPEC_EXTR (sloc->etype) = 0; SPEC_STAT (sloc->etype) = 0; + SPEC_VOLATILE(sloc->etype) = 0; + SPEC_ABSA(sloc->etype) = 0; /* we don't allow it to be allocated` onto the external stack since : so we @@ -661,9 +644,10 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) if ((selectS = liveRangesWith (lrcs, directSpilLoc, ebp, ic))) { sym = leastUsedLR (selectS); - strcpy (sym->rname, (sym->usl.spillLoc->rname[0] ? - sym->usl.spillLoc->rname : - sym->usl.spillLoc->name)); + strncpyz (sym->rname, + sym->usl.spillLoc->rname[0] ? + sym->usl.spillLoc->rname : sym->usl.spillLoc->name, + sizeof(sym->rname)); sym->spildir = 1; /* mark it as allocation required */ sym->usl.spillLoc->allocreq++; @@ -879,6 +863,9 @@ static regs *getRegPtrNoSpil() return reg; assert(0); + + /* just to make the compiler happy */ + return 0; } /*-----------------------------------------------------------------*/ @@ -896,6 +883,9 @@ static regs *getRegGprNoSpil() return reg; assert(0); + + /* just to make the compiler happy */ + return 0; } /*-----------------------------------------------------------------*/ @@ -1117,6 +1107,97 @@ xchgPositions: return change ; } +/*-----------------------------------------------------------------*/ +/* unusedLRS - returns a bitVector of liveranges not used in 'ebp' */ +/*-----------------------------------------------------------------*/ +bitVect *unusedLRs (eBBlock *ebp) +{ + bitVect *ret = NULL; + symbol *sym; + int key; + + if (!ebp) return NULL; + for (sym = hTabFirstItem(liveRanges,&key); sym ; + sym = hTabNextItem(liveRanges,&key)) { + + if (notUsedInBlock(sym,ebp,NULL)) { + ret = bitVectSetBit(ret,sym->key); + } + } + + return ret; +} + +/*-----------------------------------------------------------------*/ +/* deassignUnsedLRs - if this baisc block ends in a return then */ +/* deassign symbols not used in this block */ +/*-----------------------------------------------------------------*/ +bitVect *deassignUnsedLRs(eBBlock *ebp) +{ + bitVect *unused = NULL; + int i; + + switch (returnAtEnd(ebp)) { + case 2: /* successor block ends in a return */ + unused = unusedLRs((eBBlock *) setFirstItem(ebp->succList)); + /* fall thru */ + case 1: /* this block ends in a return */ + unused = bitVectIntersect(unused,unusedLRs(ebp)); + break; + } + + if (unused) { + for (i = 0 ; i < unused->size ; i++ ) { + + /* if unused */ + if (bitVectBitValue(unused,i)) { + + /* if assigned to registers */ + if (bitVectBitValue(_G.regAssigned,i)) { + symbol *sym; + int j; + + sym = hTabItemWithKey(liveRanges,i); + /* remove it from regassigned & mark the + register free */ + bitVectUnSetBit(_G.regAssigned,i); + for (j = 0 ; j < sym->nRegs; j++) + freeReg(sym->regs[j]); + } else { + /* not assigned to registers : remove from set*/ + bitVectUnSetBit(unused,i); + } + } + } + } + return unused; +} + +/*-----------------------------------------------------------------*/ +/* reassignUnusedLRs - put registers to unused Live ranges */ +/*-----------------------------------------------------------------*/ +void reassignUnusedLRs (bitVect *unused) +{ + int i; + if (!unused) return ; + + for (i = 0 ; i < unused->size ; i++ ) { + /* if unused : means it was assigned to registers before */ + if (bitVectBitValue(unused,i)) { + symbol *sym; + int j; + + /* put it back into reg set*/ + bitVectSetBit(_G.regAssigned,i) ; + + sym = hTabItemWithKey(liveRanges,i); + /* makr registers busy */ + for (j = 0 ; j < sym->nRegs; j++) + sym->regs[j]->isFree = 0; + } + } +} + /*-----------------------------------------------------------------*/ /* serialRegAssign - serially allocate registers to the variables */ /*-----------------------------------------------------------------*/ @@ -1127,15 +1208,18 @@ serialRegAssign (eBBlock ** ebbs, int count) /* for all blocks */ for (i = 0; i < count; i++) - { + { /* ebbs */ iCode *ic; + bitVect *unusedLRs = NULL; if (ebbs[i]->noPath && (ebbs[i]->entryLabel != entryLabel && ebbs[i]->entryLabel != returnLabel)) continue; - + + unusedLRs = deassignUnsedLRs(ebbs[i]); + /* of all instructions do */ for (ic = ebbs[i]->sch; ic; ic = ic->next) { @@ -1219,8 +1303,11 @@ serialRegAssign (eBBlock ** ebbs, int count) /* if none of the liveRanges have a spillLocation then better to spill this one than anything else already assigned to registers */ if (liveRangesWith(spillable,noSpilLoc,ebbs[i],ic)) { - spillThis (sym); - continue; + /* if this is local to this block then we might find a block spil */ + if (!(sym->liveFrom >= ebbs[i]->fSeq && sym->liveTo <= ebbs[i]->lSeq)) { + spillThis (sym); + continue; + } } } } @@ -1270,6 +1357,7 @@ serialRegAssign (eBBlock ** ebbs, int count) } } + reassignUnusedLRs(unusedLRs); } } @@ -1280,95 +1368,167 @@ static void fillGaps() { symbol *sym =NULL; int key =0; - - if (getenv("DISABLE_FILL_GAPS")) return; - /* look for livernages that was spilt by the allocator */ - for (sym = hTabFirstItem(liveRanges,&key) ; sym ; - sym = hTabNextItem(liveRanges,&key)) { + int loop = 0, change; - int i; - int pdone = 0; + if (getenv("DISABLE_FILL_GAPS")) return; + + /* First try to do DPTRuse once more since now we know what got into + registers */ + + while (loop++ < 10) { + change = 0; + + for (sym = hTabFirstItem(liveRanges,&key) ; sym ; + sym = hTabNextItem(liveRanges,&key)) { + int size = getSize(sym->type); + + if (sym->liveFrom == sym->liveTo) continue; + + if (sym->uptr && sym->dptr==0 && !sym->ruonly && + size < 4 && size > 1) { + + if (packRegsDPTRuse(operandFromSymbol(sym))) { + + /* if this was ssigned to registers then */ + if (bitVectBitValue(_G.totRegAssigned,sym->key)) { + /* take it out of the register assigned set */ + bitVectUnSetBit(_G.totRegAssigned,sym->key); + } else if (sym->usl.spillLoc) { + sym->usl.spillLoc->allocreq--; + sym->usl.spillLoc = NULL; + } + + sym->nRegs = 0; + sym->isspilt = sym->spillA = 0; + continue ; + } - if (!sym->spillA || !sym->clashes || sym->remat) continue ; + /* try assigning other dptrs */ + if (sym->dptr == 0 && packRegsDPTRnuse(operandFromSymbol(sym),1) && !getenv("DPTRnDISABLE")) { + /* if this was ssigned to registers then */ + if (bitVectBitValue(_G.totRegAssigned,sym->key)) { + /* take it out of the register assigned set */ + bitVectUnSetBit(_G.totRegAssigned,sym->key); + } else if (sym->usl.spillLoc) { + sym->usl.spillLoc->allocreq--; + sym->usl.spillLoc = NULL; + } + sym->nRegs = 0; + sym->isspilt = sym->spillA = 0; + } + } + } - /* find the liveRanges this one clashes with, that are - still assigned to registers & mark the registers as used*/ - for ( i = 0 ; i < sym->clashes->size ; i ++) { - int k; - symbol *clr; - - if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */ - bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */ + /* look for livernages that was spilt by the allocator */ + for (sym = hTabFirstItem(liveRanges,&key) ; sym ; + sym = hTabNextItem(liveRanges,&key)) { + + int i; + int pdone = 0; + + if (!sym->spillA || !sym->clashes || sym->remat) continue ; + if (!sym->uses || !sym->defs) continue ; + /* find the liveRanges this one clashes with, that are + still assigned to registers & mark the registers as used*/ + for ( i = 0 ; i < sym->clashes->size ; i ++) { + int k; + symbol *clr; + + if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */ + bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */ + continue ; + + clr = hTabItemWithKey(liveRanges,i); + assert(clr); + + /* mark these registers as used */ + for (k = 0 ; k < clr->nRegs ; k++ ) + useReg(clr->regs[k]); + } + + if (willCauseSpill(sym->nRegs,sym->regType)) { + /* NOPE :( clear all registers & and continue */ + freeAllRegs(); continue ; - - assert (clr = hTabItemWithKey(liveRanges,i)); - - /* mark these registers as used */ - for (k = 0 ; k < clr->nRegs ; k++ ) - useReg(clr->regs[k]); - } - - if (willCauseSpill(sym->nRegs,sym->regType)) { - /* NOPE :( clear all registers & and continue */ - freeAllRegs(); - continue ; - } - - /* THERE IS HOPE !!!! */ - for (i=0; i < sym->nRegs ; i++ ) { - if (sym->regType == REG_PTR) - sym->regs[i] = getRegPtrNoSpil (); - else - sym->regs[i] = getRegGprNoSpil (); - } - - /* 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 */ - 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))); + } + + /* THERE IS HOPE !!!! */ + for (i=0; i < sym->nRegs ; i++ ) { + if (sym->regType == REG_PTR) + sym->regs[i] = getRegPtrNoSpil (); + else + sym->regs[i] = getRegGprNoSpil (); + } + + /* for all its definitions & uses check if the registers + allocated needs positioning NOTE: we can position + only ONCE if more than One positioning required + then give up */ + 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))); + } + if (IS_SYMOP(IC_RIGHT(ic)) && + bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) { + pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic))); + } + if (pdone > 1) break; } - if (IS_SYMOP(IC_RIGHT(ic)) && - bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) { - pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic))); + } + 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 (!IS_ASSIGN_ICODE(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))); + } + if (pdone > 1) break; } - if (pdone > 1) break; } - } - /* had to position more than once GIVE UP */ - if (pdone > 1) { - /* UNDO all the changes we made to try this */ - sym->isspilt = 0; - for (i=0; i < sym->nRegs ; i++ ) { - sym->regs[i] = NULL; + /* had to position more than once GIVE UP */ + if (pdone > 1) { + /* UNDO all the changes we made to try this */ + sym->isspilt = 1; + for (i=0; i < sym->nRegs ; i++ ) { + sym->regs[i] = NULL; + } + freeAllRegs(); + D (fprintf (stderr, "Fill Gap gave up due to positioning for " + "%s in function %s\n", + sym->name, currFunc ? currFunc->name : "UNKNOWN")); + continue ; } + D (fprintf (stderr, "FILLED GAP for %s in function %s\n", + sym->name, currFunc ? currFunc->name : "UNKNOWN")); + _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key); + sym->isspilt = sym->spillA = 0 ; + sym->usl.spillLoc->allocreq--; + sym->usl.spillLoc = NULL; freeAllRegs(); - printf("Fill Gap gave up due to positioning for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"); - continue ; + change ++; } - printf("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"); - _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key); - sym->isspilt = sym->spillA = 0 ; - sym->usl.spillLoc->allocreq--; - freeAllRegs(); + if (!change) break; } } /*-----------------------------------------------------------------*/ /* rUmaskForOp :- returns register mask for an operand */ /*-----------------------------------------------------------------*/ -static bitVect * -rUmaskForOp (operand * op) +bitVect * +ds390_rUmaskForOp (operand * op) { bitVect *rumask; symbol *sym; @@ -1408,7 +1568,7 @@ regsUsedIniCode (iCode * ic) if (ic->op == IFX) { rmask = bitVectUnion (rmask, - rUmaskForOp (IC_COND (ic))); + ds390_rUmaskForOp (IC_COND (ic))); goto ret; } @@ -1416,7 +1576,7 @@ regsUsedIniCode (iCode * ic) if (ic->op == JUMPTABLE) { rmask = bitVectUnion (rmask, - rUmaskForOp (IC_JTCOND (ic))); + ds390_rUmaskForOp (IC_JTCOND (ic))); goto ret; } @@ -1424,16 +1584,16 @@ regsUsedIniCode (iCode * ic) /* of all other cases */ if (IC_LEFT (ic)) rmask = bitVectUnion (rmask, - rUmaskForOp (IC_LEFT (ic))); + ds390_rUmaskForOp (IC_LEFT (ic))); if (IC_RIGHT (ic)) rmask = bitVectUnion (rmask, - rUmaskForOp (IC_RIGHT (ic))); + ds390_rUmaskForOp (IC_RIGHT (ic))); if (IC_RESULT (ic)) rmask = bitVectUnion (rmask, - rUmaskForOp (IC_RESULT (ic))); + ds390_rUmaskForOp (IC_RESULT (ic))); ret: return rmask; @@ -1525,14 +1685,17 @@ rematStr (symbol * sym) char *s = buffer; iCode *ic = sym->rematiCode; + *s = 0; + while (1) { /* if plus or minus print the right hand side */ if (ic->op == '+' || ic->op == '-') { - sprintf (s, "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)), - ic->op); + SNPRINTF (s, sizeof(buffer) - strlen(buffer), + "0x%04x %c ", (int) operandLitValue (IC_RIGHT (ic)), + ic->op); s += strlen (s); ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode; continue; @@ -1543,7 +1706,8 @@ rematStr (symbol * sym) continue; } /* we reached the end */ - sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname); + SNPRINTF (s, sizeof(buffer) - strlen(buffer), + "%s", OP_SYMBOL (IC_LEFT (ic))->rname); break; } @@ -1588,10 +1752,7 @@ regTypeNum () } /* if the symbol has only one definition & - that definition is a get_pointer and the - pointer we are getting is rematerializable and - in "data" space */ - + that definition is a get_pointer */ if (bitVectnBitsOn (sym->defs) == 1 && (ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs))) && @@ -1599,19 +1760,18 @@ regTypeNum () !sym->noSpilLoc && !IS_BITVAR (sym->etype)) { - - - /* if remat in data space */ - if (OP_SYMBOL (IC_LEFT (ic))->remat && + /* and that pointer is remat in data space */ + if (IS_SYMOP (IC_LEFT (ic)) && + OP_SYMBOL (IC_LEFT (ic))->remat && !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) && - DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) + DCL_TYPE (aggrToPtr (operandType(IC_LEFT(ic)), FALSE)) == POINTER) { /* create a psuedo symbol & force a spil */ symbol *psym = newSymbol (rematStr (OP_SYMBOL (IC_LEFT (ic))), 1); psym->type = sym->type; psym->etype = sym->etype; - strcpy (psym->rname, psym->name); + strncpyz (psym->rname, psym->name, sizeof(psym->rname)); sym->isspilt = 1; sym->usl.spillLoc = psym; continue; @@ -1854,6 +2014,8 @@ pack: /* found the definition */ /* replace the result with the result of */ /* this assignment and remove this assignment */ + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); + IC_RESULT (dic) = IC_RESULT (ic); if (IS_ITEMP (IC_RESULT (dic)) && OP_SYMBOL (IC_RESULT (dic))->liveFrom > dic->seq) @@ -1871,8 +2033,9 @@ pack: } remiCodeFromeBBlock (ebp, ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); - OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); + OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); return 1; } @@ -1959,8 +2122,9 @@ findAssignToSym (operand * op, iCode * ic) /*-----------------------------------------------------------------*/ static int packRegsForSupport (iCode * ic, eBBlock * ebp) -{ +{ int change = 0; + /* for the left & right operand :- look to see if the left was assigned a true symbol in far space in that case replace them */ @@ -1975,12 +2139,18 @@ packRegsForSupport (iCode * ic, eBBlock * ebp) /* found it we need to remove it from the block */ - for (sic = dic; sic != ic; sic = sic->next) + for (sic = dic; sic != ic; sic = sic->next) { bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key); + sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key); + } + wassert(IS_SYMOP(IC_LEFT (ic))); + wassert(IS_SYMOP(IC_RIGHT (dic))); IC_LEFT (ic)->operand.symOperand = IC_RIGHT (dic)->operand.symOperand; + OP_SYMBOL(IC_LEFT(ic))->liveTo = ic->seq; IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key; + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); remiCodeFromeBBlock (ebp, dic); hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); change++; @@ -2008,14 +2178,19 @@ right: } /* found it we need to remove it from the block */ - for (sic = dic; sic != ic; sic = sic->next) + for (sic = dic; sic != ic; sic = sic->next) { bitVectUnSetBit (sic->rlive, IC_RIGHT (ic)->key); + sic->rlive = bitVectSetBit (sic->rlive, IC_RIGHT (dic)->key); + } + wassert(IS_SYMOP(IC_RIGHT (ic))); + wassert(IS_SYMOP(IC_RIGHT (dic))); IC_RIGHT (ic)->operand.symOperand = IC_RIGHT (dic)->operand.symOperand; IC_RIGHT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key; - + OP_SYMBOL(IC_RIGHT(ic))->liveTo = ic->seq; remiCodeFromeBBlock (ebp, dic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); change++; } @@ -2026,11 +2201,111 @@ right: #define IS_OP_RUONLY(x) (x && IS_SYMOP(x) && OP_SYMBOL(x)->ruonly) +/*-----------------------------------------------------------------*/ +/* packRegsDPTRnuse - color live ranges that can go into extra DPTRS */ +/*-----------------------------------------------------------------*/ +static int packRegsDPTRnuse( operand *op , int dptr) +{ + int i,key; + iCode *ic; + + if (!IS_SYMOP(op) || !IS_ITEMP(op)) return 0; + if (OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly || OP_SYMBOL(op)->dptr) + return 0; + + /* first check if any overlapping liverange has already been + assigned to this DPTR */ + if (OP_SYMBOL(op)->clashes) { + for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ ) { + symbol *sym; + if (bitVectBitValue(OP_SYMBOL(op)->clashes,i)) { + sym = hTabItemWithKey(liveRanges,i); + if (sym->dptr == dptr) return 0; + } + } + } + + /* future for more dptrs */ + if (dptr > 1) { + OP_SYMBOL(op)->dptr = dptr; + return 1; + } + + /* DPTR1 is special since it is also used as a scratch by the backend . + so we walk thru the entire live range of this operand and make sure + DPTR1 will not be used by the backed . The logic here is to find out if + more than one operand in an icode is in far space then we give up : we + don't keep it live across functions for now + */ + + ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom); + for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo; + ic = hTabNextItem(iCodeSeqhTab,&key)) { + int nfs =0; + + if (ic->op == CALL || ic->op == PCALL) return 0; + + /* single operand icode are ok */ + if (ic->op == IFX || ic->op == IPUSH) + continue ; + + if (ic->op == SEND ) { + if (ic->argreg != 1 ) return 0; + else continue ; + } + /* two special cases first */ + if (POINTER_GET(ic) && !isOperandEqual(IC_LEFT(ic),op) && /* pointer get */ + !OP_SYMBOL(IC_LEFT(ic))->ruonly && /* with result in far space */ + (isOperandInFarSpace(IC_RESULT(ic)) && + !isOperandInReg(IC_RESULT(ic)))) { + return 0; + } + + if (POINTER_SET(ic) && !isOperandEqual(IC_RESULT(ic),op) && /* pointer set */ + !OP_SYMBOL(IC_RESULT(ic))->ruonly && /* with right in far space */ + (isOperandInFarSpace(IC_RIGHT(ic)) && + !isOperandInReg(IC_RIGHT(ic)))) { + return 0; + } + + if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && /* if symbol operand */ + !isOperandEqual(IC_RESULT(ic),op) && /* not the same as this */ + ((isOperandInFarSpace(IC_RESULT(ic)) || /* in farspace or */ + OP_SYMBOL(IC_RESULT(ic))->onStack) && /* on the stack */ + !isOperandInReg(IC_RESULT(ic)))) { /* and not in register */ + nfs++; + } + /* same for left */ + if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && /* if symbol operand */ + !isOperandEqual(IC_LEFT(ic),op) && /* not the same as this */ + ((isOperandInFarSpace(IC_LEFT(ic)) || /* in farspace or */ + OP_SYMBOL(IC_LEFT(ic))->onStack) && /* on the stack */ + !isOperandInReg(IC_LEFT(ic)))) { /* and not in register */ + nfs++; + } + /* same for right */ + if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && /* if symbol operand */ + !isOperandEqual(IC_RIGHT(ic),op) && /* not the same as this */ + ((isOperandInFarSpace(IC_RIGHT(ic)) || /* in farspace or */ + OP_SYMBOL(IC_RIGHT(ic))->onStack) && /* on the stack */ + !isOperandInReg(IC_RIGHT(ic)))) { /* and not in register */ + nfs++; + } + + if (nfs && IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && + OP_SYMBOL(IC_RESULT(ic))->ruonly) return 0; + + if (nfs > 1) return 0; + } + OP_SYMBOL(op)->dptr = dptr; + return 1; +} + /*-----------------------------------------------------------------*/ /* packRegsDPTRuse : - will reduce some registers for single Use */ /*-----------------------------------------------------------------*/ static iCode * -packRegsDPTRuse (iCode * lic, operand * op, eBBlock * ebp) +packRegsDPTRuse (operand * op) { /* go thru entire liveRange of this variable & check for other possible usage of DPTR , if we don't find it the @@ -2041,7 +2316,7 @@ packRegsDPTRuse (iCode * lic, operand * op, eBBlock * ebp) iCode *ic, *dic; sym_link *type, *etype; - if (!IS_SYMOP(op)) return NULL; + if (!IS_SYMOP(op) || !IS_ITEMP(op)) return NULL; if (OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly) return NULL; /* first check if any overlapping liverange has already been @@ -2060,60 +2335,92 @@ packRegsDPTRuse (iCode * lic, operand * op, eBBlock * ebp) for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo; ic = hTabNextItem(iCodeSeqhTab,&key)) { + if (SKIP_IC3(ic)) continue; + /* if PCALL cannot be sure give up */ if (ic->op == PCALL) return NULL; - /* if CALL then make sure it is VOID || return value not used */ + /* if SEND & not the first parameter then giveup */ + if (ic->op == SEND && ic->argreg != 1 && + ((isOperandInFarSpace(IC_LEFT(ic)) && !isOperandInReg(IC_LEFT(ic))) || + isOperandEqual(op,IC_LEFT(ic)))) return NULL; + + /* if CALL then make sure it is VOID || return value not used + or the return value is assigned to this one */ if (ic->op == CALL) { if (OP_SYMBOL(IC_RESULT(ic))->liveTo == OP_SYMBOL(IC_RESULT(ic))->liveFrom) continue ; etype = getSpec(type = operandType(IC_RESULT(ic))); - if (getSize(type) == 0) continue ; + if (getSize(type) == 0 || isOperandEqual(op,IC_RESULT(ic))) + continue ; return NULL ; } /* special case of add with a [remat] */ if (ic->op == '+' && OP_SYMBOL(IC_LEFT(ic))->remat && - !isOperandInFarSpace(IC_RIGHT(ic))) continue ; + (isOperandInFarSpace(IC_RIGHT(ic)) && + !isOperandInReg(IC_RIGHT(ic)))) return NULL ; - /* special case */ + /* special cases */ /* pointerGet */ - if (POINTER_GET(ic) && isOperandEqual(IC_RESULT(ic),op) && - getSize(operandType(IC_LEFT(ic))) > 1) return NULL ; - - if (POINTER_SET(ic) && isOperandEqual(IC_RIGHT(ic),op) && - getSize(operandType(IC_RESULT(ic))) > 1) return NULL; + if (POINTER_GET(ic) && !isOperandEqual(IC_LEFT(ic),op) && + getSize(operandType(IC_LEFT(ic))) > 1 ) return NULL ; + + /* pointerSet */ + if (POINTER_SET(ic) && !isOperandEqual(IC_RESULT(ic),op) && + getSize(operandType(IC_RESULT(ic))) > 1 ) return NULL; + + /* conditionals can destroy 'b' - make sure B wont + be used in this one*/ + if ((IS_CONDITIONAL(ic) || ic->op == '*' || ic->op == '/' || + ic->op == LEFT_OP || ic->op == RIGHT_OP ) && + getSize(operandType(op)) > 3) return NULL; + + /* if this is a cast to a bigger type */ + if (ic->op==CAST) { + if (!IS_PTR(OP_SYM_TYPE(IC_RESULT(ic))) && + getSize(OP_SYM_TYPE(IC_RESULT(ic))) > + getSize(OP_SYM_TYPE(IC_RIGHT(ic)))) { + return 0; + } + } /* general case */ if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && !isOperandEqual(IC_RESULT(ic),op) && - (isOperandInFarSpace(IC_RESULT(ic)) || - OP_SYMBOL(IC_RESULT(ic))->ruonly || - OP_SYMBOL(IC_RESULT(ic))->onStack)) return NULL; + ( ( ( isOperandInFarSpace(IC_RESULT(ic)) || OP_SYMBOL(IC_RESULT(ic))->onStack) && + !isOperandInReg(IC_RESULT(ic))) || + OP_SYMBOL(IC_RESULT(ic))->ruonly)) return NULL; if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && !isOperandEqual(IC_RIGHT(ic),op) && - (OP_SYMBOL(IC_RIGHT(ic))->liveTo > ic->seq || + (OP_SYMBOL(IC_RIGHT(ic))->liveTo >= ic->seq || IS_TRUE_SYMOP(IC_RIGHT(ic)) || OP_SYMBOL(IC_RIGHT(ic))->ruonly) && - (isOperandInFarSpace(IC_RIGHT(ic)) || - OP_SYMBOL(IC_RIGHT(ic))->onStack)) return NULL; + ( ( isOperandInFarSpace(IC_RIGHT(ic)) || OP_SYMBOL(IC_RIGHT(ic))->onStack) && + !isOperandInReg(IC_RIGHT(ic))) ) return NULL; if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && !isOperandEqual(IC_LEFT(ic),op) && - (OP_SYMBOL(IC_LEFT(ic))->liveTo > ic->seq || + (OP_SYMBOL(IC_LEFT(ic))->liveTo >= ic->seq || IS_TRUE_SYMOP(IC_LEFT(ic)) || OP_SYMBOL(IC_LEFT(ic))->ruonly) && - (isOperandInFarSpace(IC_LEFT(ic)) || - OP_SYMBOL(IC_LEFT(ic))->onStack)) return NULL; + ( ( isOperandInFarSpace(IC_LEFT(ic)) || OP_SYMBOL(IC_LEFT(ic))->onStack) && + !isOperandInReg(IC_LEFT(ic))) ) return NULL; if (IC_LEFT(ic) && IC_RIGHT(ic) && IS_ITEMP(IC_LEFT(ic)) && IS_ITEMP(IC_RIGHT(ic)) && - isOperandInFarSpace(IC_LEFT(ic)) && isOperandInFarSpace(IC_RIGHT(ic))) + (isOperandInFarSpace(IC_LEFT(ic)) && !isOperandInReg(IC_LEFT(ic))) && + (isOperandInFarSpace(IC_RIGHT(ic)) && !isOperandInReg(IC_RIGHT(ic)))) return NULL; } OP_SYMBOL(op)->ruonly = 1; + if (OP_SYMBOL(op)->usl.spillLoc) { + if (OP_SYMBOL(op)->spillA) + OP_SYMBOL(op)->usl.spillLoc->allocreq--; + OP_SYMBOL(op)->usl.spillLoc = NULL; + } return dic; } @@ -2154,6 +2461,22 @@ packRegsForAccUse (iCode * ic) { iCode *uic; + /* if this is an aggregate, e.g. a one byte char array */ + if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) { + return; + } + + /* if we are calling a reentrant function that has stack parameters */ + if (ic->op == CALL && + IFFUNC_ISREENT(operandType(IC_LEFT(ic))) && + FUNC_HASSTACKPARM(operandType(IC_LEFT(ic)))) + return; + + if (ic->op == PCALL && + IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) && + FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next)) + return; + /* if + or - then it has to be one byte result */ if ((ic->op == '+' || ic->op == '-') && getSize (operandType (IC_RESULT (ic))) > 1) @@ -2229,8 +2552,7 @@ packRegsForAccUse (iCode * ic) /* make sure that the result of this icode is not on the stack, since acc is used to compute stack offset */ - if (IS_TRUE_SYMOP (IC_RESULT (uic)) && - OP_SYMBOL (IC_RESULT (uic))->onStack) + if (isOperandOnStack(IC_RESULT(uic))) return; /* if either one of them in far space then we cannot */ @@ -2251,19 +2573,6 @@ packRegsForAccUse (iCode * ic) IC_LEFT (uic)->key != IC_RESULT (ic)->key) return; -#if 0 - // this is too dangerous and need further restrictions - // see bug #447547 - - /* if one of them is a literal then we can */ - if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) || - (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic)))) - { - OP_SYMBOL (IC_RESULT (ic))->accuse = 1; - return; - } -#endif - /* if the other one is not on stack then we can */ if (IC_LEFT (uic)->key == IC_RESULT (ic)->key && (IS_ITEMP (IC_RIGHT (uic)) || @@ -2294,7 +2603,7 @@ packForPush (iCode * ic, eBBlock * ebp) iCode *dic, *lic; bitVect *dbv; - if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic))) + if ((ic->op != IPUSH && ic->op != SEND) || !IS_ITEMP (IC_LEFT (ic))) return; /* must have only definition & one usage */ @@ -2309,6 +2618,8 @@ packForPush (iCode * ic, eBBlock * ebp) if (dic->op != '=' || POINTER_SET (dic)) return; + + if (dic->eBBlockNum != ic->eBBlockNum) return ; /* make sure the right side does not have any definitions inbetween */ @@ -2317,6 +2628,7 @@ packForPush (iCode * ic, eBBlock * ebp) if (bitVectBitValue(dbv,lic->key)) return ; } /* make sure they have the same type */ + if (IS_SPEC(operandType(IC_LEFT(ic)))) { sym_link *itype=operandType(IC_LEFT(ic)); sym_link *ditype=operandType(IC_RIGHT(dic)); @@ -2326,14 +2638,24 @@ packForPush (iCode * ic, eBBlock * ebp) return; } /* extend the live range of replaced operand if needed */ - if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < ic->seq) { - OP_SYMBOL(IC_RIGHT(dic))->liveTo = ic->seq; + if (OP_SYMBOL(IC_RIGHT(dic))->liveTo < OP_SYMBOL(IC_LEFT(ic))->liveTo) { + OP_SYMBOL(IC_RIGHT(dic))->liveTo = OP_SYMBOL(IC_LEFT(ic))->liveTo; + OP_SYMBOL(IC_RIGHT(dic))->clashes = + bitVectUnion(OP_SYMBOL(IC_RIGHT(dic))->clashes, + OP_SYMBOL(IC_LEFT(ic))->clashes); } + for (lic = ic; lic && lic != dic; lic = lic->prev) + { + bitVectUnSetBit (lic->rlive, IC_LEFT (ic)->key); + if (IS_ITEMP (IC_RIGHT (dic))) + bitVectSetBit (lic->rlive, IC_RIGHT (dic)->key); + } /* 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); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); } @@ -2387,6 +2709,18 @@ packRegisters (eBBlock * ebp) } + /* if this is an itemp & used as a pointer + & assigned to a literal then remat */ + if (IS_ASSIGN_ICODE(ic) && + IS_ITEMP(IC_RESULT(ic)) && + bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && + isOperandLiteral(IC_RIGHT(ic))) + { + OP_SYMBOL (IC_RESULT (ic))->remat = 1; + OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic; + OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; + } + /* if straight assignment then carry remat flag if this is the only definition */ if (ic->op == '=' && @@ -2407,6 +2741,7 @@ packRegisters (eBBlock * ebp) cast is remat, then we can remat this cast as well */ if (ic->op == CAST && IS_SYMOP(IC_RIGHT(ic)) && + !OP_SYMBOL(IC_RESULT(ic))->isreqv && OP_SYMBOL(IC_RIGHT(ic))->remat ) { sym_link *to_type = operandType(IC_LEFT(ic)); sym_link *from_type = operandType(IC_RIGHT(ic)); @@ -2435,12 +2770,25 @@ packRegisters (eBBlock * ebp) } /* mark the pointer usages */ - if (POINTER_SET (ic)) + if (POINTER_SET (ic) && IS_SYMOP (IC_RESULT (ic))) OP_SYMBOL (IC_RESULT (ic))->uptr = 1; - if (POINTER_GET (ic)) + if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic))) OP_SYMBOL (IC_LEFT (ic))->uptr = 1; + if (ic->op == RETURN && IS_SYMOP (IC_LEFT(ic))) + OP_SYMBOL (IC_LEFT (ic))->uptr = 1; + + if (ic->op == RECEIVE && ic->argreg == 1 && + IS_SYMOP (IC_RESULT (ic)) && + getSize (operandType(IC_RESULT(ic))) <= 3) + OP_SYMBOL (IC_RESULT(ic))->uptr = 1; + + if (ic->op == SEND && ic->argreg == 1 && + IS_SYMOP(IC_LEFT(ic)) && + getSize (aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) <= 3) + OP_SYMBOL (IC_LEFT(ic))->uptr = 1; + if (!SKIP_IC2 (ic)) { /* if we are using a symbol on the stack @@ -2465,21 +2813,6 @@ packRegisters (eBBlock * ebp) } } -#if 0 - /* if the condition of an if instruction - is defined in the previous instruction then - mark the itemp as a conditional */ - if ((IS_CONDITIONAL (ic) || - (IS_BITWISE_OP(ic) && isBitwiseOptimizable(ic))) && - ic->next && ic->next->op == IFX && - isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)) && - OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq) - { - - OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND; - continue; - } -#else /* if the condition of an if instruction is defined in the previous instruction and this is the only usage then @@ -2494,44 +2827,50 @@ packRegisters (eBBlock * ebp) OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND; continue; } -#endif - +#if 1 /* reduce for support function calls */ if (ic->supportRtn || ic->op == '+' || ic->op == '-') packRegsForSupport (ic, ebp); - +#endif /* some cases the redundant moves can - can be eliminated for return statements */ - if ((ic->op == RETURN || ic->op == SEND) && + can be eliminated for return statements . Can be elminated for the first SEND */ + if ((ic->op == RETURN || + ((ic->op == SEND || ic->op == RECEIVE)&& ic->argreg == 1)) && !isOperandInFarSpace (IC_LEFT (ic)) && !options.model) { - packRegsDPTRuse (ic, IC_LEFT (ic), ebp); + packRegsDPTRuse (IC_LEFT (ic)); } - if ((ic->op == CALL && getSize(operandType(IC_RESULT(ic))) <= 4)) { - packRegsDPTRuse (ic, IC_RESULT (ic), ebp); + if (ic->op == CALL) { + sym_link *ftype = operandType(IC_LEFT(ic)); + if (getSize(operandType(IC_RESULT(ic))) <= 4 && + !IFFUNC_ISBUILTIN(ftype)) { + packRegsDPTRuse (IC_RESULT (ic)); + } } /* if pointer set & left has a size more than one and right is not in far space */ if (POINTER_SET (ic) && !isOperandInFarSpace (IC_RIGHT (ic)) && + IS_SYMOP (IC_RESULT (ic)) && !OP_SYMBOL (IC_RESULT (ic))->remat && !IS_OP_RUONLY (IC_RIGHT (ic)) && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1) { - packRegsDPTRuse (ic, IC_RESULT (ic), ebp); + packRegsDPTRuse (IC_RESULT (ic)); } /* if pointer get */ if (POINTER_GET (ic) && !isOperandInFarSpace (IC_RESULT (ic)) && + IS_SYMOP (IC_LEFT (ic)) && !OP_SYMBOL (IC_LEFT (ic))->remat && !IS_OP_RUONLY (IC_RESULT (ic)) && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) { - packRegsDPTRuse (ic, IC_LEFT (ic), ebp); + packRegsDPTRuse (IC_LEFT (ic)); } /* if this is cast for intergral promotion then @@ -2549,15 +2888,17 @@ packRegisters (eBBlock * ebp) SPEC_USIGN (fromType) == SPEC_USIGN (toType)) { - iCode *dic = packRegsDPTRuse (ic, IC_RIGHT (ic), ebp); + iCode *dic = packRegsDPTRuse (IC_RIGHT (ic)); if (dic) { if (IS_ARITHMETIC_OP (dic)) { + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,dic->key); IC_RESULT (dic) = IC_RESULT (ic); remiCodeFromeBBlock (ebp, ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); - OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); + OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); ic = ic->prev; } else @@ -2572,13 +2913,15 @@ packRegisters (eBBlock * ebp) if (compareType (operandType (IC_RIGHT (ic)), operandType (IC_LEFT (ic))) == 1) { - iCode *dic = packRegsDPTRuse (ic, IC_RIGHT (ic), ebp); + iCode *dic = packRegsDPTRuse (IC_RIGHT (ic)); if (dic) { + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); IC_RESULT (dic) = IC_RESULT (ic); remiCodeFromeBBlock (ebp, ic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key); hTabDeleteItem (&iCodehTab, ic->key, ic, DELETE_ITEM, NULL); - OP_DEFS (IC_RESULT (dic)) = bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); + OP_DEFS(IC_RESULT (dic))=bitVectSetBit (OP_DEFS (IC_RESULT (dic)), dic->key); ic = ic->prev; } } @@ -2591,7 +2934,7 @@ packRegisters (eBBlock * ebp) ------------- push V1 */ - if (ic->op == IPUSH) + if (ic->op == IPUSH || ic->op == SEND) { packForPush (ic, ebp); } @@ -2608,7 +2951,7 @@ packRegisters (eBBlock * ebp) if ((IS_ARITHMETIC_OP (ic) || IS_CONDITIONAL(ic) || IS_BITWISE_OP (ic) - || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL + || ic->op == LEFT_OP || ic->op == RIGHT_OP || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic))) ) && IS_ITEMP (IC_RESULT (ic)) && @@ -2633,7 +2976,7 @@ ds390_assignRegisters (eBBlock ** ebbs, int count) setToNull ((void *) &_G.totRegAssigned); setToNull ((void *) &_G.funcrUsed); ds390_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; - ds390_nRegs = 18; + ds390_nRegs = 12; if (options.model != MODEL_FLAT24) options.stack10bit = 0; /* change assignments this will remove some live ranges reducing some register pressure */ @@ -2653,7 +2996,7 @@ ds390_assignRegisters (eBBlock ** ebbs, int count) ds390_nRegs = 8; freeAllRegs (); fillGaps(); - ds390_nRegs = 18; + ds390_nRegs = 12; /* if stack was extended then tell the user */ if (_G.stackExtend) @@ -2675,7 +3018,8 @@ ds390_assignRegisters (eBBlock ** ebbs, int count) createRegMask (ebbs, count); /* redo that offsets for stacked automatic variables */ - redoStackOffsets (); + if (currFunc) + redoStackOffsets (); if (options.dump_rassgn) { dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count);