X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fralloc.c;h=5b46166f29e9b7e6c4dff7feb216c7705e281e66;hb=62309d5f28a502c8f30efaf282325b77252fa6c4;hp=447c9ff11ce6be4341154476860fcaa7f87e2c0a;hpb=25b445778074199472238a6178f40ed1e0f39058;p=fw%2Fsdcc diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 447c9ff1..5b46166f 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -1182,10 +1182,15 @@ serialRegAssign (eBBlock ** ebbs, int count) else sym->regs[j] = getRegGpr (ic, ebbs[i], sym); - /* if the allocation falied which means + /* if the allocation failed which means this was spilt then break */ - if (!sym->regs[j]) - break; + if (!sym->regs[j]) { + if (j) { + fprintf (stderr, "%d reg(s) lost in %s:%d\n", + j, __FILE__,__LINE__); + } + break; + } } /* if it shares registers with operands make sure @@ -1215,8 +1220,8 @@ serialRegAssign (eBBlock ** ebbs, int count) /*-----------------------------------------------------------------*/ /* rUmaskForOp :- returns register mask for an operand */ /*-----------------------------------------------------------------*/ -static bitVect * -rUmaskForOp (operand * op) +bitVect * +mcs51_rUmaskForOp (operand * op) { bitVect *rumask; symbol *sym; @@ -1256,7 +1261,7 @@ regsUsedIniCode (iCode * ic) if (ic->op == IFX) { rmask = bitVectUnion (rmask, - rUmaskForOp (IC_COND (ic))); + mcs51_rUmaskForOp (IC_COND (ic))); goto ret; } @@ -1264,7 +1269,7 @@ regsUsedIniCode (iCode * ic) if (ic->op == JUMPTABLE) { rmask = bitVectUnion (rmask, - rUmaskForOp (IC_JTCOND (ic))); + mcs51_rUmaskForOp (IC_JTCOND (ic))); goto ret; } @@ -1272,16 +1277,16 @@ regsUsedIniCode (iCode * ic) /* of all other cases */ if (IC_LEFT (ic)) rmask = bitVectUnion (rmask, - rUmaskForOp (IC_LEFT (ic))); + mcs51_rUmaskForOp (IC_LEFT (ic))); if (IC_RIGHT (ic)) rmask = bitVectUnion (rmask, - rUmaskForOp (IC_RIGHT (ic))); + mcs51_rUmaskForOp (IC_RIGHT (ic))); if (IC_RESULT (ic)) rmask = bitVectUnion (rmask, - rUmaskForOp (IC_RESULT (ic))); + mcs51_rUmaskForOp (IC_RESULT (ic))); ret: return rmask; @@ -1378,6 +1383,11 @@ rematStr (symbol * sym) 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,12 +1442,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 && + !IS_CAST_ICODE(OP_SYMBOL (IC_LEFT (ic))->rematiCode) && DCL_TYPE (aggrToPtr (sym->type, FALSE)) == POINTER) { @@ -1583,55 +1595,33 @@ static int packRegsForAssign (iCode * ic, eBBlock * ebp) { iCode *dic, *sic; - sym_link *etype = operandType (IC_RIGHT (ic)); + //sym_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 || - IS_BITFIELD (etype)) + OP_LIVETO (IC_RIGHT (ic)) > ic->seq + /* why? || 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 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 0 // jwk 20010410 - /* 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)) - { - dic = NULL; - break; - } -#else /* if there is a function call then don't pack it */ if ((dic->op == CALL || dic->op == PCALL)) { dic = NULL; break; } -#endif if (SKIP_IC2 (dic)) continue; @@ -1754,9 +1744,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 */ @@ -1815,6 +1805,8 @@ static int packRegsForSupport (iCode * ic, eBBlock * ebp) { int change = 0; + iCode *dic, *sic; + /* for the left & right operand :- look to see if the left was assigned a true symbol in far space in that case replace them */ @@ -1822,8 +1814,7 @@ packRegsForSupport (iCode * ic, eBBlock * ebp) if (IS_ITEMP (IC_LEFT (ic)) && OP_SYMBOL (IC_LEFT (ic))->liveTo <= ic->seq) { - iCode *dic = findAssignToSym (IC_LEFT (ic), ic); - iCode *sic; + dic = findAssignToSym (IC_LEFT (ic), ic); if (!dic) goto right; @@ -1833,9 +1824,8 @@ packRegsForSupport (iCode * ic, eBBlock * ebp) for (sic = dic; sic != ic; sic = sic->next) bitVectUnSetBit (sic->rlive, IC_LEFT (ic)->key); - IC_LEFT (ic)->operand.symOperand = - IC_RIGHT (dic)->operand.symOperand; - IC_LEFT (ic)->key = IC_RIGHT (dic)->operand.symOperand->key; + OP_SYMBOL(IC_LEFT (ic))=OP_SYMBOL(IC_RIGHT (dic)); + IC_LEFT (ic)->key = OP_SYMBOL(IC_RIGHT (dic))->key; remiCodeFromeBBlock (ebp, dic); hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); change++; @@ -1896,13 +1886,15 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) /* only upto 2 bytes since we cannot predict the usage of b, & acc */ - if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2) && - ic->op != RETURN && + if (getSize (operandType (op)) > (fReturnSizeMCS51 - 2)) + return NULL; + + if (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 && @@ -1924,6 +1916,16 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) bitVectFirstBit (OP_DEFS (op))))) return NULL; + /* if that only usage is a cast */ + if (dic->op == CAST) { + /* to a bigger type */ + if (getSize(OP_SYM_TYPE(IC_RESULT(dic))) > + getSize(OP_SYM_TYPE(IC_RIGHT(dic)))) { + /* than we can not, since we cannot predict the usage of b & acc */ + return NULL; + } + } + /* found the definition now check if it is local */ if (dic->seq < ebp->fSeq || dic->seq > ebp->lSeq) @@ -2151,6 +2153,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)))) @@ -2158,6 +2164,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 && @@ -2183,8 +2190,6 @@ accuse: /*-----------------------------------------------------------------*/ /* packForPush - hueristics to reduce iCode for pushing */ /*-----------------------------------------------------------------*/ -catchMe() {} - static void packForPush (iCode * ic, eBBlock * ebp) { @@ -2220,8 +2225,7 @@ packForPush (iCode * ic, eBBlock * ebp) sym_link *ditype=operandType(IC_RIGHT(dic)); if (SPEC_USIGN(itype)!=SPEC_USIGN(ditype) || - SPEC_SHORT(itype)!=SPEC_SHORT(ditype) || - SPEC_USIGN(itype)!=SPEC_USIGN(ditype)) + SPEC_LONG(itype)!=SPEC_LONG(ditype)) return; } /* extend the live range of replaced operand if needed */ @@ -2268,7 +2272,7 @@ packRegisters (eBBlock * ebp) for (ic = ebp->sch; ic; ic = ic->next) { - /* if this is an itemp & result of a address of a true sym + /* if this is an itemp & result of an address of a true sym then mark this as rematerialisable */ if (ic->op == ADDRESS_OF && IS_ITEMP (IC_RESULT (ic)) && @@ -2289,6 +2293,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) { @@ -2298,14 +2303,29 @@ packRegisters (eBBlock * ebp) 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 */ if ((ic->op == '+' || ic->op == '-') && (IS_SYMOP (IC_LEFT (ic)) && IS_ITEMP (IC_RESULT (ic)) && + IS_OP_LITERAL (IC_RIGHT (ic))) && OP_SYMBOL (IC_LEFT (ic))->remat && - bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1 && - IS_OP_LITERAL (IC_RIGHT (ic)))) + (!IS_SYMOP (IC_RIGHT (ic)) || !IS_CAST_ICODE(OP_SYMBOL (IC_RIGHT (ic))->rematiCode)) && + bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) == 1) { OP_SYMBOL (IC_RESULT (ic))->remat = 1; OP_SYMBOL (IC_RESULT (ic))->rematiCode = ic; @@ -2343,20 +2363,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 @@ -2371,7 +2377,6 @@ packRegisters (eBBlock * ebp) OP_SYMBOL (IC_RESULT (ic))->regType = REG_CND; continue; } -#endif /* reduce for support function calls */ if (ic->supportRtn || ic->op == '+' || ic->op == '-') @@ -2445,7 +2450,7 @@ 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); @@ -2482,6 +2487,7 @@ 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 == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic))) @@ -2504,12 +2510,7 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) setToNull ((void *) &_G.funcrUsed); mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; - /* if not register extentions then reduce number - of registers */ - if (options.regExtend) - mcs51_nRegs = 13; - else - mcs51_nRegs = 8; + mcs51_nRegs = 8; /* change assignments this will remove some live ranges reducing some register pressure */ @@ -2517,7 +2518,7 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) 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 */ @@ -2550,8 +2551,8 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) if (options.dump_rassgn) { - dumpEbbsToFileExt (".dumprassgn", ebbs, count); - dumpLiveRanges (".dumplrange", liveRanges); + dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count); + dumpLiveRanges (DUMP_LRANGE, liveRanges); } /* do the overlaysegment stuff SDCCmem.c */ @@ -2560,7 +2561,6 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) /* now get back the chain */ ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count)); - gen51Code (ic); /* free up any _G.stackSpil locations allocated */