X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fds390%2Fralloc.c;h=d731417dbf76deb8ffa770e67a6310d8825db95a;hb=99419f4aa880e9b20ecced49fe093395d79be88b;hp=7bc49eae623c18f1e56e68fee23c4ab51a2433dd;hpb=b4d69dfd516f175255aa87b18b59dcf309d98b46;p=fw%2Fsdcc diff --git a/src/ds390/ralloc.c b/src/ds390/ralloc.c index 7bc49eae..d731417d 100644 --- a/src/ds390/ralloc.c +++ b/src/ds390/ralloc.c @@ -36,12 +36,15 @@ /* since the pack the registers depending strictly on the MCU */ /*-----------------------------------------------------------------*/ +#define D(x) + /* Global data */ static struct { bitVect *spiltSet; set *stackSpil; bitVect *regAssigned; + bitVect *totRegAssigned; /* final set of LRs that got into registers */ short blockSpil; int slocNum; bitVect *funcrUsed; /* registers used in a function */ @@ -57,23 +60,29 @@ int ds390_ptrRegReq; /* one byte pointer register required */ regs regs390[] = { - {REG_GPR, R2_IDX, REG_GPR, "r2", "ar2", "0", 2, 1}, - {REG_GPR, R3_IDX, REG_GPR, "r3", "ar3", "0", 3, 1}, - {REG_GPR, R4_IDX, REG_GPR, "r4", "ar4", "0", 4, 1}, - {REG_GPR, R5_IDX, REG_GPR, "r5", "ar5", "0", 5, 1}, - {REG_GPR, R6_IDX, REG_GPR, "r6", "ar6", "0", 6, 1}, - {REG_GPR, R7_IDX, REG_GPR, "r7", "ar7", "0", 7, 1}, - {REG_PTR, R0_IDX, REG_PTR, "r0", "ar0", "0", 0, 1}, - {REG_PTR, R1_IDX, REG_PTR, "r1", "ar1", "0", 1, 1}, - {REG_GPR, X8_IDX, REG_GPR, "x8", "x8", "xreg", 0, 1}, - {REG_GPR, X9_IDX, REG_GPR, "x9", "x9", "xreg", 1, 1}, - {REG_GPR, X10_IDX, REG_GPR, "x10", "x10", "xreg", 2, 1}, - {REG_GPR, X11_IDX, REG_GPR, "x11", "x11", "xreg", 3, 1}, - {REG_GPR, X12_IDX, REG_GPR, "x12", "x12", "xreg", 4, 1}, - {REG_CND, CND_IDX, REG_CND, "C", "C", "xreg", 0, 1}, + {REG_GPR, R2_IDX, REG_GPR, "r2", "ar2", "0", 2, 1, 1}, + {REG_GPR, R3_IDX, REG_GPR, "r3", "ar3", "0", 3, 1, 1}, + {REG_GPR, R4_IDX, REG_GPR, "r4", "ar4", "0", 4, 1, 1}, + {REG_GPR, R5_IDX, REG_GPR, "r5", "ar5", "0", 5, 1, 1}, + {REG_GPR, R6_IDX, REG_GPR, "r6", "ar6", "0", 6, 1, 1}, + {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}, }; int ds390_nRegs = 13; static void spillThis (symbol *); +static void freeAllRegs (); +static iCode * packRegsDPTRuse (operand *); /*-----------------------------------------------------------------*/ /* allocReg - allocates register of given type */ @@ -138,6 +147,15 @@ freeReg (regs * reg) reg->isFree = 1; } +/*-----------------------------------------------------------------*/ +/* useReg - marks a register as used */ +/*-----------------------------------------------------------------*/ +static void +useReg (regs * reg) +{ + reg->isFree = 0; +} + /*-----------------------------------------------------------------*/ /* nFreeRegs - returns number of free registers */ @@ -197,6 +215,16 @@ allDefsOutOfRange (bitVect * defs, int fseq, int toseq) return TRUE; } +/*-----------------------------------------------------------------*/ +/* isOperandInReg - returns true if operand is currently in regs */ +/*-----------------------------------------------------------------*/ +static int isOperandInReg(operand *op) +{ + if (!IS_SYMOP(op)) return 0; + + return bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(op)->key); +} + /*-----------------------------------------------------------------*/ /* computeSpillable - given a point find the spillable live ranges */ /*-----------------------------------------------------------------*/ @@ -380,15 +408,11 @@ noOverLap (set * itmpStack, symbol * fsym) { symbol *sym; - for (sym = setFirstItem (itmpStack); sym; sym = setNextItem (itmpStack)) { - if (sym->liveTo > fsym->liveFrom) - return 0; - + if (bitVectBitValue(sym->clashes,fsym->key)) return 0; } - return 1; } @@ -482,7 +506,7 @@ createStackSpil (symbol * sym) if (applyToSet (_G.stackSpil, isFree, &sloc, sym)) { /* found a free one : just update & return */ - sym->usl.spillLoc = sloc; + sym->usl.spillLoc = sloc; sym->stackSpil = 1; sloc->isFree = 0; addSetHead (&sloc->usl.itmpStack, sym); @@ -505,8 +529,15 @@ createStackSpil (symbol * sym) /* set the type to the spilling symbol */ sloc->type = copyLinkChain (sym->type); sloc->etype = getSpec (sloc->type); - SPEC_SCLS (sloc->etype) = options.model ? S_XDATA : S_DATA; + if (options.model == MODEL_SMALL) { + SPEC_SCLS (sloc->etype) = S_DATA; + } else { + SPEC_SCLS (sloc->etype) = S_XDATA; + } 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 @@ -592,10 +623,11 @@ spillThis (symbol * sym) /* mark it has spilt & put it in the spilt set */ - sym->isspilt = 1; + sym->isspilt = sym->spillA = 1; _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key); bitVectUnSetBit (_G.regAssigned, sym->key); + bitVectUnSetBit (_G.totRegAssigned, sym->key); for (i = 0; i < sym->nRegs; i++) @@ -610,12 +642,12 @@ spillThis (symbol * sym) LIVE ranges */ if (!ds390_ptrRegReq && isSpiltOnStack (sym)) { - ds390_ptrRegReq++; + ds390_ptrRegReq += !options.stack10bit; spillLRWithPtrReg (sym); } if (sym->usl.spillLoc && !sym->remat) - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return; } @@ -649,7 +681,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) sym->usl.spillLoc->name)); sym->spildir = 1; /* mark it as allocation required */ - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -694,7 +726,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) sym = leastUsedLR (selectS); /* mark this as allocation required */ - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -703,7 +735,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) { sym = leastUsedLR (selectS); - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -715,7 +747,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* return a created spil location */ sym = createStackSpil (leastUsedLR (selectS)); - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -739,12 +771,13 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym) ssym = selectSpil (ic, ebp, forSym); /* mark it as spilt */ - ssym->isspilt = 1; + ssym->isspilt = ssym->spillA = 1; _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key); /* mark it as not register assigned & take it away from the set */ bitVectUnSetBit (_G.regAssigned, ssym->key); + bitVectUnSetBit (_G.totRegAssigned, ssym->key); /* mark the registers as free */ for (i = 0; i < ssym->nRegs; i++) @@ -753,9 +786,9 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym) /* if spilt on stack then free up r0 & r1 if they could have been assigned to as gprs */ - if (!ds390_ptrRegReq && isSpiltOnStack (ssym)) + if (!ds390_ptrRegReq && isSpiltOnStack (ssym) && !options.stack10bit) { - ds390_ptrRegReq++; + ds390_ptrRegReq++; spillLRWithPtrReg (ssym); } @@ -845,6 +878,41 @@ tryAgain: goto tryAgain; } +/*-----------------------------------------------------------------*/ +/* getRegPtrNoSpil - get it cannot split */ +/*-----------------------------------------------------------------*/ +static regs *getRegPtrNoSpil() +{ + regs *reg; + + /* try for a ptr type */ + if ((reg = allocReg (REG_PTR))) + return reg; + + /* try for gpr type */ + if ((reg = allocReg (REG_GPR))) + return reg; + + assert(0); +} + +/*-----------------------------------------------------------------*/ +/* getRegGprNoSpil - get it cannot split */ +/*-----------------------------------------------------------------*/ +static regs *getRegGprNoSpil() +{ + + regs *reg; + if ((reg = allocReg (REG_GPR))) + return reg; + + if (!ds390_ptrRegReq) + if ((reg = allocReg (REG_PTR))) + return reg; + + assert(0); +} + /*-----------------------------------------------------------------*/ /* symHasReg - symbol has a given register */ /*-----------------------------------------------------------------*/ @@ -944,6 +1012,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) result->regs[i] = getRegGpr (ic, ebp, result); _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key); + _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key); } @@ -973,10 +1042,11 @@ reassignLR (operand * op) int i; /* not spilt any more */ - sym->isspilt = sym->blockSpil = sym->remainSpil = 0; + sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0; bitVectUnSetBit (_G.spiltSet, sym->key); _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); + _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key); _G.blockSpil--; @@ -1026,15 +1096,16 @@ willCauseSpill (int nr, int rt) /* ult and operand, if this happens make sure they are in the same */ /* position as the operand otherwise chaos results */ /*-----------------------------------------------------------------*/ -static void -positionRegs (symbol * result, symbol * opsym, int lineno) +static int +positionRegs (symbol * result, symbol * opsym) { int count = min (result->nRegs, opsym->nRegs); int i, j = 0, shared = 0; + int change = 0; /* if the result has been spilt then cannot share */ if (opsym->isspilt) - return; + return 0; again: shared = 0; /* first make sure that they actually share */ @@ -1055,8 +1126,10 @@ xchgPositions: regs *tmp = result->regs[i]; result->regs[i] = result->regs[j]; result->regs[j] = tmp; + change ++; goto again; } + return change ; } /*-----------------------------------------------------------------*/ @@ -1090,7 +1163,7 @@ serialRegAssign (eBBlock ** ebbs, int count) /* if result is present && is a true symbol */ if (IC_RESULT (ic) && ic->op != IFX && IS_TRUE_SYMOP (IC_RESULT (ic))) - OP_SYMBOL (IC_RESULT (ic))->allocreq = 1; + OP_SYMBOL (IC_RESULT (ic))->allocreq++; /* take away registers from live ranges that end at this instruction */ @@ -1149,19 +1222,24 @@ serialRegAssign (eBBlock ** ebbs, int count) /* if it has a spillocation & is used less than all other live ranges then spill this */ - if (willCS && sym->usl.spillLoc) - { - - symbol *leastUsed = - leastUsedLR (liveRangesWith (spillable, - allLRs, - ebbs[i], - ic)); - if (leastUsed && - leastUsed->used > sym->used) - { - spillThis (sym); - continue; + if (willCS) { + if (sym->usl.spillLoc) { + symbol *leastUsed = leastUsedLR (liveRangesWith (spillable, + allLRs, ebbs[i], ic)); + if (leastUsed && leastUsed->used > sym->used) { + spillThis (sym); + continue; + } + } else { + /* 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)) { + /* 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; + } + } } } @@ -1169,13 +1247,14 @@ serialRegAssign (eBBlock ** ebbs, int count) then mark it */ if (POINTER_GET (ic) && IS_SYMOP (IC_LEFT (ic)) && getSize (OP_SYMBOL (IC_LEFT (ic))->type) - <= PTRSIZE) + <= (unsigned) PTRSIZE) { ds390_ptrRegReq++; ptrRegSet = 1; } /* else we assign registers to it */ _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); + _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key); for (j = 0; j < sym->nRegs; j++) { @@ -1194,12 +1273,12 @@ serialRegAssign (eBBlock ** ebbs, int count) if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) && OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') positionRegs (OP_SYMBOL (IC_RESULT (ic)), - OP_SYMBOL (IC_LEFT (ic)), ic->lineno); + OP_SYMBOL (IC_LEFT (ic))); /* do the same for the right operand */ if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) && OP_SYMBOL (IC_RIGHT (ic))->nRegs) positionRegs (OP_SYMBOL (IC_RESULT (ic)), - OP_SYMBOL (IC_RIGHT (ic)), ic->lineno); + OP_SYMBOL (IC_RIGHT (ic))); if (ptrRegSet) { @@ -1212,11 +1291,146 @@ serialRegAssign (eBBlock ** ebbs, int count) } } +/*-----------------------------------------------------------------*/ +/* fillGaps - Try to fill in the Gaps left by Pass1 */ +/*-----------------------------------------------------------------*/ +static void fillGaps() +{ + symbol *sym =NULL; + int key =0; + + if (getenv("DISABLE_FILL_GAPS")) return; + + /* First try to do DPTRuse once more since now we know what got into + registers */ + + for (sym = hTabFirstItem(liveRanges,&key) ; sym ; + sym = hTabNextItem(liveRanges,&key)) { + + if (sym->uptr && !sym->ruonly && getSize(sym->type) < 4) { + if (packRegsDPTRuse(operandFromSymbol(sym))) { + + D (fprintf (stderr, "FILL GAPS: found more DPTR use for " + "%s in func %s\n", + sym->name, currFunc ? currFunc->name : "UNKNOWN")); + /* 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); + sym->nRegs = 0; + } else if (sym->usl.spillLoc) sym->usl.spillLoc->allocreq--; + + sym->isspilt = sym->spillA = 0; + } + } + } + + /* 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 ; + + /* 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 ; + + 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 & 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; + } + } + 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; + } + } + /* 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--; + freeAllRegs(); + } +} + /*-----------------------------------------------------------------*/ /* rUmaskForOp :- returns register mask for an operand */ /*-----------------------------------------------------------------*/ -static bitVect * -rUmaskForOp (operand * op) +bitVect * +ds390_rUmaskForOp (operand * op) { bitVect *rumask; symbol *sym; @@ -1256,7 +1470,7 @@ regsUsedIniCode (iCode * ic) if (ic->op == IFX) { rmask = bitVectUnion (rmask, - rUmaskForOp (IC_COND (ic))); + ds390_rUmaskForOp (IC_COND (ic))); goto ret; } @@ -1264,7 +1478,7 @@ regsUsedIniCode (iCode * ic) if (ic->op == JUMPTABLE) { rmask = bitVectUnion (rmask, - rUmaskForOp (IC_JTCOND (ic))); + ds390_rUmaskForOp (IC_JTCOND (ic))); goto ret; } @@ -1272,16 +1486,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; @@ -1341,7 +1555,15 @@ createRegMask (eBBlock ** ebbs, int count) "createRegMask cannot find live range"); exit (0); } - + + /* special case for ruonly */ + if (sym->ruonly && sym->liveFrom != sym->liveTo) { + int size = getSize(sym->type); + int j = DPL_IDX; + for (k = 0 ; k < size; k++ ) + ic->rMask = bitVectSetBit (ic->rMask, j++); + continue ; + } /* if no register assigned to it */ if (!sym->nRegs || sym->isspilt) continue; @@ -1377,7 +1599,11 @@ rematStr (symbol * sym) ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode; continue; } - + /* cast then continue */ + if (IS_CAST_ICODE(ic)) { + ic = OP_SYMBOL (IC_RIGHT (ic))->rematiCode; + continue; + } /* we reached the end */ sprintf (s, "%s", OP_SYMBOL (IC_LEFT (ic))->rname); break; @@ -1432,13 +1658,14 @@ regTypeNum () (ic = hTabItemWithKey (iCodehTab, bitVectFirstBit (sym->defs))) && POINTER_GET (ic) && + !sym->noSpilLoc && !IS_BITVAR (sym->etype)) { /* if remat in data space */ if (OP_SYMBOL (IC_LEFT (ic))->remat && - // sym->type && + !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) && DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) { @@ -1595,25 +1822,27 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) /* if the true symbol is defined in far space or on stack then we should not since this will increase register pressure */ +#if 0 if (isOperandInFarSpace (IC_RESULT (ic))) { if ((dic = farSpacePackable (ic))) goto pack; else return 0; - } +#else + if (isOperandInFarSpace(IC_RESULT(ic)) && !farSpacePackable(ic)) { + return 0; + } +#endif + /* find the definition of iTempNN scanning backwards if we find a a use of the true symbol in before we find the definition then we cannot */ for (dic = ic->prev; dic; dic = dic->prev) { - - /* if there is a function call and this is - a parameter & not my parameter then don't pack it */ - if ((dic->op == CALL || dic->op == PCALL) && - (OP_SYMBOL (IC_RESULT (ic))->_isparm && - !OP_SYMBOL (IC_RESULT (ic))->ismyparm)) + /* if there is a function call then don't pack it */ + if ((dic->op == CALL || dic->op == PCALL)) { dic = NULL; break; @@ -1687,6 +1916,7 @@ 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) @@ -1704,6 +1934,7 @@ 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); return 1; @@ -1733,9 +1964,9 @@ findAssignToSym (operand * op, iCode * ic) /* or in stack space in case of + & - */ /* if assigned to a non-symbol then return - true */ + FALSE */ if (!IS_SYMOP (IC_RIGHT (dic))) - break; + return NULL; /* if the symbol is in far space then we should not */ @@ -1792,8 +2023,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 */ @@ -1808,12 +2040,16 @@ 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); + } 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++; @@ -1841,14 +2077,17 @@ 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); + } 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++; } @@ -1860,144 +2099,115 @@ right: /*-----------------------------------------------------------------*/ -/* packRegsForOneuse : - will reduce some registers for single Use */ +/* packRegsDPTRuse : - will reduce some registers for single Use */ /*-----------------------------------------------------------------*/ static iCode * -packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) +packRegsDPTRuse (operand * op) { -#if 1 - - /* I can't figure out how to make this safe yet. */ - if ((int)ic+(int)op+(int)ebp) { - return 0; - } else { - return 0; - } - return NULL; - -#else - bitVect *uses; - iCode *dic, *sic; - - /* if returning a literal then do nothing */ - if (!IS_SYMOP (op)) - return NULL; - - /* only upto 2 bytes since we cannot predict - the usage of b, & acc */ - if (getSize (operandType (op)) > (fReturnSize_390 - 2) && - ic->op != RETURN && - ic->op != SEND && - !POINTER_SET (ic) && - !POINTER_GET (ic)) - return NULL; - - /* this routine will mark the a symbol as used in one - instruction use only && if the defintion is local - (ie. within the basic block) && has only one definition && - that definiion is either a return value from a - function or does not contain any variables in - far space */ - uses = bitVectCopy (OP_USES (op)); - bitVectUnSetBit (uses, ic->key); /* take away this iCode */ - if (!bitVectIsZero (uses)) /* has other uses */ - return NULL; - - /* if it has only one defintion */ - if (bitVectnBitsOn (OP_DEFS (op)) > 1) - return NULL; /* has more than one definition */ - - /* get the that definition */ - if (!(dic = - hTabItemWithKey (iCodehTab, - bitVectFirstBit (OP_DEFS (op))))) - return NULL; - - /* found the definition now check if it is local */ - if (dic->seq < ebp->fSeq || - dic->seq > ebp->lSeq) - return NULL; /* non-local */ - - /* now check if it is the return from - a function call */ - if (dic->op == CALL || dic->op == PCALL) - { - if (ic->op != SEND && ic->op != RETURN) - { - OP_SYMBOL (op)->ruonly = 1; - return dic; + /* go thru entire liveRange of this variable & check for + other possible usage of DPTR , if we don't find it the + assign this to DPTR (ruonly) + */ + int i, key; + symbol *sym; + iCode *ic, *dic; + sym_link *type, *etype; + + 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 + assigned to DPTR */ + if (OP_SYMBOL(op)->clashes) { + for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ ) { + if (bitVectBitValue(OP_SYMBOL(op)->clashes,i)) { + sym = hTabItemWithKey(liveRanges,i); + if (sym->ruonly) return NULL ; + } } - dic = dic->next; - } - - - /* otherwise check that the definition does - not contain any symbols in far space */ - if (isOperandInFarSpace (IC_LEFT (dic)) || - isOperandInFarSpace (IC_RIGHT (dic)) || - IS_OP_RUONLY (IC_LEFT (ic)) || - IS_OP_RUONLY (IC_RIGHT (ic))) - { - return NULL; } - /* if pointer set then make sure the pointer - is one byte */ - if (POINTER_SET (dic) && - !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE))) - return NULL; - - if (POINTER_GET (dic) && - !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE))) - return NULL; - - sic = dic; - - /* also make sure the intervenening instructions - don't have any thing in far space */ - for (dic = dic->next; dic && dic != ic; dic = dic->next) - { - - /* if there is an intervening function call then no */ - if (dic->op == CALL || dic->op == PCALL) - return NULL; - /* if pointer set then make sure the pointer - is one byte */ - if (POINTER_SET (dic) && - !IS_DATA_PTR (aggrToPtr (operandType (IC_RESULT (dic)), FALSE))) - return NULL; - - if (POINTER_GET (dic) && - !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE))) - return NULL; - - /* if address of & the result is remat the okay */ - if (dic->op == ADDRESS_OF && - OP_SYMBOL (IC_RESULT (dic))->remat) - continue; - - /* if operand has size of three or more & this - operation is a '*','/' or '%' then 'b' may - cause a problem */ - if ((dic->op == '%' || dic->op == '/' || dic->op == '*') && - getSize (operandType (op)) >= 3) - return NULL; + /* no then go thru this guys live range */ + dic = ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom); + 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 + 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 || isOperandEqual(op,IC_RESULT(ic))) + continue ; + return NULL ; + } - /* if left or right or result is in far space */ - if (isOperandInFarSpace (IC_LEFT (dic)) || - isOperandInFarSpace (IC_RIGHT (dic)) || - isOperandInFarSpace (IC_RESULT (dic)) || - IS_OP_RUONLY (IC_LEFT (dic)) || - IS_OP_RUONLY (IC_RIGHT (dic)) || - IS_OP_RUONLY (IC_RESULT (dic))) - { - return NULL; + /* special case of add with a [remat] */ + if (ic->op == '+' && + OP_SYMBOL(IC_LEFT(ic))->remat && + (isOperandInFarSpace(IC_RIGHT(ic)) && + !isOperandInReg(IC_RIGHT(ic)))) return NULL ; + + /* special cases */ + /* pointerGet */ + 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 (getSize(OP_SYM_TYPE(IC_RESULT(ic))) > + getSize(OP_SYM_TYPE(IC_RIGHT(ic)))) { + return 0; + } } - } - OP_SYMBOL (op)->ruonly = 1; - return sic; -#endif + /* general case */ + if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && + !isOperandEqual(IC_RESULT(ic),op) && + ((isOperandInFarSpace(IC_RESULT(ic)) && !isOperandInReg(IC_RESULT(ic))) || + OP_SYMBOL(IC_RESULT(ic))->ruonly || + OP_SYMBOL(IC_RESULT(ic))->onStack)) return NULL; + + if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && + !isOperandEqual(IC_RIGHT(ic),op) && + (OP_SYMBOL(IC_RIGHT(ic))->liveTo >= ic->seq || + IS_TRUE_SYMOP(IC_RIGHT(ic)) || + OP_SYMBOL(IC_RIGHT(ic))->ruonly) && + ((isOperandInFarSpace(IC_RIGHT(ic)) && !isOperandInReg(IC_RIGHT(ic)))|| + OP_SYMBOL(IC_RIGHT(ic))->onStack)) return NULL; + + if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && + !isOperandEqual(IC_LEFT(ic),op) && + (OP_SYMBOL(IC_LEFT(ic))->liveTo > ic->seq || + IS_TRUE_SYMOP(IC_LEFT(ic)) || + OP_SYMBOL(IC_LEFT(ic))->ruonly) && + ((isOperandInFarSpace(IC_LEFT(ic)) && !isOperandInReg(IC_LEFT(ic)))|| + OP_SYMBOL(IC_LEFT(ic))->onStack)) return NULL; + + if (IC_LEFT(ic) && IC_RIGHT(ic) && + IS_ITEMP(IC_LEFT(ic)) && IS_ITEMP(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; + return dic; } /*-----------------------------------------------------------------*/ @@ -2022,7 +2232,7 @@ isBitwiseOptimizable (iCode * ic) bit | bit bit | x */ - if (IS_LITERAL (rtype) || + if ( IS_LITERAL (rtype) || (IS_BITVAR (ltype) && IN_BITSPACE (SPEC_OCLS (ltype)))) return TRUE; else @@ -2037,6 +2247,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) @@ -2112,9 +2338,14 @@ 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 0 if (IS_TRUE_SYMOP (IC_RESULT (uic)) && OP_SYMBOL (IC_RESULT (uic))->onStack) return; +#else + if (isOperandOnStack(IC_RESULT(uic))) + return; +#endif /* if either one of them in far space then we cannot */ if ((IS_TRUE_SYMOP (IC_LEFT (uic)) && @@ -2134,6 +2365,10 @@ 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)))) @@ -2141,6 +2376,7 @@ packRegsForAccUse (iCode * ic) 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 && @@ -2169,7 +2405,8 @@ accuse: static void packForPush (iCode * ic, eBBlock * ebp) { - iCode *dic; + iCode *dic, *lic; + bitVect *dbv; if (ic->op != IPUSH || !IS_ITEMP (IC_LEFT (ic))) return; @@ -2187,11 +2424,31 @@ packForPush (iCode * ic, eBBlock * ebp) if (dic->op != '=' || POINTER_SET (dic)) return; + /* make sure the right side does not have any definitions + inbetween */ + dbv = OP_DEFS(IC_RIGHT(dic)); + for (lic = ic; lic && lic != dic ; lic = lic->prev) { + if (bitVectBitValue(dbv,lic->key)) return ; + } + /* make sure they have the same type */ + { + sym_link *itype=operandType(IC_LEFT(ic)); + sym_link *ditype=operandType(IC_RIGHT(dic)); + + if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) || + SPEC_LONG(itype)!=SPEC_LONG(ditype)) + 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; + } /* 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); } @@ -2251,6 +2508,7 @@ packRegisters (eBBlock * ebp) !POINTER_SET (ic) && IS_SYMOP (IC_RIGHT (ic)) && OP_SYMBOL (IC_RIGHT (ic))->remat && + !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode) && bitVectnBitsOn (OP_SYMBOL (IC_RESULT (ic))->defs) <= 1) { @@ -2259,6 +2517,20 @@ packRegisters (eBBlock * ebp) OP_SYMBOL (IC_RESULT (ic))->rematiCode = OP_SYMBOL (IC_RIGHT (ic))->rematiCode; } + + /* if cast to a generic pointer & the pointer being + cast is remat, then we can remat this cast as well */ + if (ic->op == CAST && + IS_SYMOP(IC_RIGHT(ic)) && + OP_SYMBOL(IC_RIGHT(ic))->remat ) { + sym_link *to_type = operandType(IC_LEFT(ic)); + sym_link *from_type = operandType(IC_RIGHT(ic)); + if (IS_GENPTR(to_type) && IS_PTR(from_type)) { + OP_SYMBOL (IC_RESULT (ic))->remat = 1; + OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic; + OP_SYMBOL (IC_RESULT (ic))->usl.spillLoc = NULL; + } + } /* if this is a +/- operation with a rematerizable then mark this as rematerializable as well */ @@ -2266,6 +2538,7 @@ packRegisters (eBBlock * ebp) (IS_SYMOP (IC_LEFT (ic)) && IS_ITEMP (IC_RESULT (ic)) && OP_SYMBOL (IC_LEFT (ic))->remat && + (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) && bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && IS_OP_LITERAL (IC_RIGHT (ic)))) { @@ -2283,38 +2556,39 @@ packRegisters (eBBlock * ebp) if (POINTER_GET (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 (!SKIP_IC2 (ic)) { /* if we are using a symbol on the stack then we should say ds390_ptrRegReq */ if (ic->op == IFX && IS_SYMOP (IC_COND (ic))) - ds390_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack || - OP_SYMBOL (IC_COND (ic))->iaccess) ? 1 : 0); + ds390_ptrRegReq += ((OP_SYMBOL (IC_COND (ic))->onStack ? !options.stack10bit : 0) + + OP_SYMBOL (IC_COND (ic))->iaccess); else if (ic->op == JUMPTABLE && IS_SYMOP (IC_JTCOND (ic))) - ds390_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack || - OP_SYMBOL (IC_JTCOND (ic))->iaccess) ? 1 : 0); + ds390_ptrRegReq += ((OP_SYMBOL (IC_JTCOND (ic))->onStack ? !options.stack10bit : 0) + + OP_SYMBOL (IC_JTCOND (ic))->iaccess); else { if (IS_SYMOP (IC_LEFT (ic))) - ds390_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack || - OP_SYMBOL (IC_LEFT (ic))->iaccess) ? 1 : 0); + ds390_ptrRegReq += ((OP_SYMBOL (IC_LEFT (ic))->onStack ? !options.stack10bit : 0) + + OP_SYMBOL (IC_LEFT (ic))->iaccess); if (IS_SYMOP (IC_RIGHT (ic))) - ds390_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack || - OP_SYMBOL (IC_RIGHT (ic))->iaccess) ? 1 : 0); + ds390_ptrRegReq += ((OP_SYMBOL (IC_RIGHT (ic))->onStack ? !options.stack10bit : 0) + + OP_SYMBOL (IC_RIGHT (ic))->iaccess); if (IS_SYMOP (IC_RESULT (ic))) - ds390_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack || - OP_SYMBOL (IC_RESULT (ic))->iaccess) ? 1 : 0); + ds390_ptrRegReq += ((OP_SYMBOL (IC_RESULT (ic))->onStack ? !options.stack10bit : 0) + + OP_SYMBOL (IC_RESULT (ic))->iaccess); } } +#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) || - ((ic->op == BITWISEAND || - ic->op == '|' || - ic->op == '^') && - isBitwiseOptimizable (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) @@ -2323,6 +2597,22 @@ packRegisters (eBBlock * ebp) 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 + mark the itemp as a conditional */ + if ((IS_CONDITIONAL (ic) || + (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic))) && + ic->next && ic->next->op == IFX && + bitVectnBitsOn (OP_USES(IC_RESULT(ic)))==1 && + 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; + } +#endif /* reduce for support function calls */ if (ic->supportRtn || ic->op == '+' || ic->op == '-') @@ -2330,10 +2620,20 @@ packRegisters (eBBlock * ebp) /* some cases the redundant moves can can be eliminated for return statements */ - if ((ic->op == RETURN || ic->op == SEND) && + if ((ic->op == RETURN || ic->op == SEND) && !isOperandInFarSpace (IC_LEFT (ic)) && - !options.model) - packRegsForOneuse (ic, IC_LEFT (ic), ebp); + !options.model) { + + packRegsDPTRuse (IC_LEFT (ic)); + } + + 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 */ @@ -2341,19 +2641,20 @@ packRegisters (eBBlock * ebp) !isOperandInFarSpace (IC_RIGHT (ic)) && !OP_SYMBOL (IC_RESULT (ic))->remat && !IS_OP_RUONLY (IC_RIGHT (ic)) && - getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1) - - packRegsForOneuse (ic, IC_RESULT (ic), ebp); + getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1) { + + packRegsDPTRuse (IC_RESULT (ic)); + } /* if pointer get */ if (POINTER_GET (ic) && !isOperandInFarSpace (IC_RESULT (ic)) && !OP_SYMBOL (IC_LEFT (ic))->remat && !IS_OP_RUONLY (IC_RESULT (ic)) && - getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) - - packRegsForOneuse (ic, IC_LEFT (ic), ebp); + getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) { + packRegsDPTRuse (IC_LEFT (ic)); + } /* if this is cast for intergral promotion then check if only use of the definition of the @@ -2370,13 +2671,15 @@ packRegisters (eBBlock * ebp) SPEC_USIGN (fromType) == SPEC_USIGN (toType)) { - iCode *dic = packRegsForOneuse (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); ic = ic->prev; @@ -2390,14 +2693,16 @@ packRegisters (eBBlock * ebp) /* if the type from and type to are the same then if this is the only use then packit */ - if (checkType (operandType (IC_RIGHT (ic)), + if (compareType (operandType (IC_RIGHT (ic)), operandType (IC_LEFT (ic))) == 1) { - iCode *dic = packRegsForOneuse (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); ic = ic->prev; @@ -2427,17 +2732,16 @@ packRegisters (eBBlock * ebp) we can leave the result of this operation in acc:b combination */ if ((IS_ARITHMETIC_OP (ic) - + || IS_CONDITIONAL(ic) || IS_BITWISE_OP (ic) - - || ic->op == LEFT_OP || ic->op == RIGHT_OP - + || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL + || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic))) ) && IS_ITEMP (IC_RESULT (ic)) && getSize (operandType (IC_RESULT (ic))) <= 2) packRegsForAccUse (ic); - + } } @@ -2450,22 +2754,20 @@ ds390_assignRegisters (eBBlock ** ebbs, int count) iCode *ic; int i; - setToNull ((void *) &_G.funcrUsed); + setToNull ((void *) &_G.funcrUsed); + setToNull ((void *) &_G.regAssigned); + setToNull ((void *) &_G.totRegAssigned); + setToNull ((void *) &_G.funcrUsed); ds390_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; - /* if not register extentions then reduce number - of registers */ - if (options.regExtend) - ds390_nRegs = 13; - else - ds390_nRegs = 8; - + ds390_nRegs = 12; + if (options.model != MODEL_FLAT24) options.stack10bit = 0; /* change assignments this will remove some live ranges reducing some register pressure */ for (i = 0; i < count; i++) packRegisters (ebbs[i]); if (options.dump_pack) - dumpEbbsToFileExt (".dumppack", ebbs, count); + dumpEbbsToFileExt (DUMP_PACK, ebbs, count); /* first determine for each live range the number of registers & the type of registers required for each */ @@ -2474,6 +2776,11 @@ ds390_assignRegisters (eBBlock ** ebbs, int count) /* and serially allocate registers */ serialRegAssign (ebbs, count); + ds390_nRegs = 8; + freeAllRegs (); + fillGaps(); + ds390_nRegs = 12; + /* if stack was extended then tell the user */ if (_G.stackExtend) { @@ -2496,8 +2803,10 @@ ds390_assignRegisters (eBBlock ** ebbs, int count) /* redo that offsets for stacked automatic variables */ redoStackOffsets (); - if (options.dump_rassgn) - dumpEbbsToFileExt (".dumprassgn", ebbs, count); + if (options.dump_rassgn) { + dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count); + dumpLiveRanges (DUMP_LRANGE, liveRanges); + } /* do the overlaysegment stuff SDCCmem.c */ doOverlays (ebbs, count); @@ -2514,6 +2823,7 @@ ds390_assignRegisters (eBBlock ** ebbs, int count) setToNull ((void **) &_G.stackSpil); setToNull ((void **) &_G.spiltSet); /* mark all registers as free */ + ds390_nRegs = 8; freeAllRegs (); return;