X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fralloc.c;h=09fd032dfcc3b2d7ef83d7ee2ab34bc5b3d5a684;hb=85bfc3dc629c33427a664f90bd6551f14f14a507;hp=2ae154ab80cf6b6b565f92f8bfbb4dad1f90b33f;hpb=53149b16f40e4d1a76ae913cb53fb62825833ae6;p=fw%2Fsdcc diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 2ae154ab..09fd032d 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -25,6 +25,7 @@ #include "common.h" #include "ralloc.h" +#include "gen.h" /*-----------------------------------------------------------------*/ /* At this point we start getting processor specific although */ @@ -271,7 +272,7 @@ static int notUsedInBlock (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)); + allDefsOutOfRange (sym->defs,ebp->fSeq,ebp->lSeq)); } /*-----------------------------------------------------------------*/ @@ -440,7 +441,8 @@ static symbol *createStackSpil (symbol *sym) { symbol *sloc= NULL; int useXstack, model, noOverlay; - int stackAuto; + + char slocBuffer[30]; /* first go try and find a free one that is already existing on the stack */ @@ -457,13 +459,19 @@ static symbol *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 */ - sprintf(buffer,"sloc%d",_G.slocNum++); - sloc = newiTemp(buffer); + if (sprintf(slocBuffer,"sloc%d",_G.slocNum++) >= sizeof(slocBuffer)) + { + fprintf(stderr, "***Internal error: slocBuffer overflowed: %s:%d\n", + __FILE__, __LINE__); + exit(1); + } + + sloc = newiTemp(slocBuffer); /* set the type to the spilling symbol */ sloc->type = copyLinkChain(sym->type); sloc->etype = getSpec(sloc->type); - SPEC_SCLS(sloc->etype) = S_AUTO ; + SPEC_SCLS(sloc->etype) = S_DATA ; SPEC_EXTR(sloc->etype) = 0; /* we don't allow it to be allocated` @@ -471,22 +479,19 @@ static symbol *createStackSpil (symbol *sym) temporarily turn it off ; we also turn off memory model to prevent the spil from going to the external storage - and turn off overlaying */ useXstack = options.useXstack; model = options.model; - noOverlay = options.noOverlay; - stackAuto = options.stackAuto; - options.noOverlay = 1; +/* noOverlay = options.noOverlay; */ +/* options.noOverlay = 1; */ options.model = options.useXstack = 0; allocLocal(sloc); options.useXstack = useXstack; options.model = model; - options.noOverlay = noOverlay; - options.stackAuto = stackAuto; +/* options.noOverlay = noOverlay; */ sloc->isref = 1; /* to prevent compiler warning */ /* if it is on the stack then update the stack */ @@ -603,8 +608,8 @@ static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) return sym; } - /* if the symbol is local to the block then */ - if (forSym->liveTo < ebp->lSeq ) { + /* if the symbol is local to the block then */ + if (forSym->liveTo < ebp->lSeq) { /* check if there are any live ranges allocated to registers that are not used in this block */ @@ -622,11 +627,13 @@ static symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) used in the remainder of the block */ if (!_G.blockSpil && (selectS = liveRangesWith(lrcs,notUsedInRemaining,ebp,ic))) { sym = leastUsedLR (selectS); - if (!sym->remat) { - sym->remainSpil = 1; - _G.blockSpil++; + if (sym != forSym) { + if (!sym->remat) { + sym->remainSpil = 1; + _G.blockSpil++; + } + return sym; } - return sym; } } @@ -731,7 +738,7 @@ static bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym) /*-----------------------------------------------------------------*/ /* getRegPtr - will try for PTR if not a GPR type if not spil */ /*-----------------------------------------------------------------*/ -regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym) +static regs *getRegPtr (iCode *ic, eBBlock *ebp, symbol *sym) { regs *reg; @@ -768,7 +775,7 @@ static 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 ; @@ -863,7 +870,7 @@ static void deassignLRs (iCode *ic, eBBlock *ebp) sym->nRegs) >= result->nRegs) ) { - for (i = 0 ; i < max(sym->nRegs,result->nRegs) ; i++) + for (i = 0 ; i < result->nRegs ; i++) if (i < sym->nRegs ) result->regs[i] = sym->regs[i] ; else @@ -1069,7 +1076,10 @@ static 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) && IS_SYMOP(IC_LEFT(ic)) + && getSize(OP_SYMBOL(IC_LEFT(ic))->type) + <= PTRSIZE) + { mcs51_ptrRegReq++; ptrRegSet = 1; } @@ -1095,7 +1105,7 @@ static void serialRegAssign (eBBlock **ebbs, int count) OP_SYMBOL(IC_LEFT(ic)),ic->lineno); /* do the same for the right operand */ if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && - OP_SYMBOL(IC_RIGHT(ic))->nRegs && ic->op != '=') + OP_SYMBOL(IC_RIGHT(ic))->nRegs) positionRegs(OP_SYMBOL(IC_RESULT(ic)), OP_SYMBOL(IC_RIGHT(ic)),ic->lineno); @@ -1131,7 +1141,7 @@ static bitVect *rUmaskForOp (operand *op) rumask = newBitVect(mcs51_nRegs); - for (j = 0; j < sym->nRegs; j++) { + for (j = 0; j < sym->nRegs; j++) { rumask = bitVectSetBit(rumask, sym->regs[j]->rIdx); } @@ -1451,15 +1461,16 @@ static iCode *farSpacePackable (iCode *ic) /*-----------------------------------------------------------------*/ static int packRegsForAssign (iCode *ic,eBBlock *ebp) { - iCode *dic, *sic; - - if ( -/* !IS_TRUE_SYMOP(IC_RESULT(ic)) || */ - !IS_ITEMP(IC_RIGHT(ic)) || + iCode *dic, *sic; + link *etype = operandType(IC_RIGHT(ic)); + + if (!IS_ITEMP(IC_RIGHT(ic)) || + OP_SYMBOL(IC_RIGHT(ic))->isind || OP_LIVETO(IC_RIGHT(ic)) > ic->seq || - OP_SYMBOL(IC_RIGHT(ic))->isind) + IS_BITFIELD(etype)) { return 0; - + } + /* if the true symbol is defined in far space or on stack then we should not since this will increase register pressure */ if (isOperandInFarSpace(IC_RESULT(ic))) { @@ -1485,7 +1496,13 @@ static 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)) @@ -1517,7 +1534,12 @@ static int packRegsForAssign (iCode *ic,eBBlock *ebp) if (!dic) return 0 ; /* did not find */ - + + /* if assignment then check that right is not a bit */ + if (ASSIGNMENT(dic) && !POINTER_SET(dic)) { + link *etype = operandType(IC_RIGHT(dic)); + if (IS_BITFIELD(etype)) return 0; + } /* if the result is on stack or iaccess then it must be the same atleast one of the operands */ if (OP_SYMBOL(IC_RESULT(ic))->onStack || @@ -1534,7 +1556,7 @@ static int packRegsForAssign (iCode *ic,eBBlock *ebp) (IC_RIGHT(dic) && IC_RESULT(ic)->key == IC_RIGHT(dic)->key))) return 0; - } + } pack: /* found the definition */ /* replace the result with the result of */ @@ -1554,6 +1576,8 @@ pack: } remiCodeFromeBBlock(ebp,ic); + hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL); + OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key); return 1; } @@ -1655,7 +1679,8 @@ static 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++; } @@ -1687,6 +1712,7 @@ static 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 ++; } @@ -1710,9 +1736,11 @@ 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) + ic->op != SEND && + !POINTER_SET(ic) && + !POINTER_GET(ic)) return NULL; /* this routine will mark the a symbol as used in one @@ -1775,7 +1803,7 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp) /* also make sure the intervenening instructions don't have any thing in far space */ - for (dic = dic->next ; dic && dic != ic ; dic = dic->next) { + for (dic = dic->next ; dic && dic != ic && sic != ic; dic = dic->next) { /* if there is an intervening function call then no */ if (dic->op == CALL || dic->op == PCALL) @@ -1799,11 +1827,11 @@ 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 */ - if (isOperandInFarSpace(IC_LEFT(dic)) || + if (isOperandInFarSpace(IC_LEFT(dic)) || isOperandInFarSpace(IC_RIGHT(dic)) || isOperandInFarSpace(IC_RESULT(dic)) || IS_OP_RUONLY(IC_LEFT(dic)) || @@ -1869,6 +1897,10 @@ static void packRegsForAccUse (iCode *ic) getSize(operandType(IC_RESULT(ic))) > 1)) return ; + if (IS_BITWISE_OP(ic) && + getSize(operandType(IC_RESULT(ic))) > 1) + return ; + /* has only one definition */ if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1) @@ -1994,14 +2026,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); } /*-----------------------------------------------------------------*/ @@ -2064,11 +2097,8 @@ static void packRegisters (eBBlock *ebp) } /* if this is a +/- operation with a rematerizable - then mark this as rematerializable as well only - if the literal value is within the range -255 and + 255 - the assembler cannot handle it other wise */ + then mark this as rematerializable as well */ if ((ic->op == '+' || ic->op == '-') && - (IS_SYMOP(IC_LEFT(ic)) && IS_ITEMP(IC_RESULT(ic)) && OP_SYMBOL(IC_LEFT(ic))->remat && @@ -2076,11 +2106,9 @@ static void packRegisters (eBBlock *ebp) IS_OP_LITERAL(IC_RIGHT(ic))) ) { int i = operandLitValue(IC_RIGHT(ic)); - if ( i < 255 && i > -255) { - OP_SYMBOL(IC_RESULT(ic))->remat = 1; - OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic; - OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL; - } + OP_SYMBOL(IC_RESULT(ic))->remat = 1; + OP_SYMBOL(IC_RESULT(ic))->rematiCode = ic; + OP_SYMBOL(IC_RESULT(ic))->usl.spillLoc = NULL; } /* mark the pointer usages */ @@ -2137,7 +2165,7 @@ static void packRegisters (eBBlock *ebp) can be eliminated for return statements */ if ((ic->op == RETURN || ic->op == SEND) && !isOperandInFarSpace(IC_LEFT(ic)) && - !options.model) + options.model == MODEL_SMALL) packRegsForOneuse (ic,IC_LEFT(ic),ebp); /* if pointer set & left has a size more than @@ -2170,13 +2198,16 @@ static void packRegisters (eBBlock *ebp) link *toType = operandType(IC_LEFT(ic)); if (IS_INTEGRAL(fromType) && IS_INTEGRAL(toType) && - getSize(fromType) != getSize(toType) ) { + getSize(fromType) != getSize(toType) && + SPEC_USIGN(fromType) == SPEC_USIGN(toType)) { iCode *dic = packRegsForOneuse(ic,IC_RIGHT(ic),ebp); if (dic) { if (IS_ARITHMETIC_OP(dic)) { IC_RESULT(dic) = IC_RESULT(ic); remiCodeFromeBBlock(ebp,ic); + hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL); + OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key); ic = ic->prev; } else OP_SYMBOL(IC_RIGHT(ic))->ruonly = 0; @@ -2191,6 +2222,8 @@ static void packRegisters (eBBlock *ebp) if (dic) { IC_RESULT(dic) = IC_RESULT(ic); remiCodeFromeBBlock(ebp,ic); + hTabDeleteItem (&iCodehTab,ic->key,ic,DELETE_ITEM,NULL); + OP_DEFS(IC_RESULT(dic)) = bitVectSetBit(OP_DEFS(IC_RESULT(dic)),dic->key); ic = ic->prev; } } @@ -2216,12 +2249,10 @@ static void packRegisters (eBBlock *ebp) the result of that operation is not on stack then we can leave the result of this operation in acc:b combination */ - if ((IS_ARITHMETIC_OP(ic) - - || IS_BITWISE_OP(ic) - + if ((IS_ARITHMETIC_OP(ic) + || IS_BITWISE_OP(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP - + || (ic->op == ADDRESS_OF && isOperandOnStack(IC_LEFT(ic))) ) && IS_ITEMP(IC_RESULT(ic)) && getSize(operandType(IC_RESULT(ic))) <= 2) @@ -2283,8 +2314,13 @@ void mcs51_assignRegisters (eBBlock **ebbs, int count) /* redo that offsets for stacked automatic variables */ redoStackOffsets (); - if (options.dump_rassgn) + if (options.dump_rassgn) { dumpEbbsToFileExt(".dumprassgn",ebbs,count); + dumpLiveRanges(".lrange",liveRanges); + } + + /* do the overlaysegment stuff SDCCmem.c */ + doOverlays(ebbs,count); /* now get back the chain */ ic = iCodeLabelOptimize(iCodeFromeBBlock (ebbs,count));