X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fralloc.c;h=82ff7c8dc70c3ae045f188f36262a9e536ddd417;hb=a1028493f3e38ab0704267390c50f09d63fdc3aa;hp=5ec469bab7a86bc72b1b541145d1393d8ed58151;hpb=6401e66edb7cff7794e45b323eddab1a5de0e0af;p=fw%2Fsdcc diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index 5ec469ba..82ff7c8d 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -51,6 +51,7 @@ static struct bitVect *funcrUsed; /* registers used in a function */ int stackExtend; int dataExtend; + bitVect *allBitregs; /* all bit registers */ } _G; @@ -61,26 +62,34 @@ int mcs51_ptrRegReq; /* one byte pointer register required */ regs regs8051[] = { - {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, 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_BIT, B0_IDX, REG_BIT, "b0", "b0", "bits", 0, 1}, + {REG_BIT, B1_IDX, REG_BIT, "b1", "b1", "bits", 1, 1}, + {REG_BIT, B2_IDX, REG_BIT, "b2", "b2", "bits", 2, 1}, + {REG_BIT, B3_IDX, REG_BIT, "b3", "b3", "bits", 3, 1}, + {REG_BIT, B4_IDX, REG_BIT, "b4", "b4", "bits", 4, 1}, + {REG_BIT, B5_IDX, REG_BIT, "b5", "b5", "bits", 5, 1}, + {REG_BIT, B6_IDX, REG_BIT, "b6", "b6", "bits", 6, 1}, + {REG_BIT, B7_IDX, REG_BIT, "b7", "b7", "bits", 7, 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", "psw", "0xd0", 0, 1}, - {0, DPL_IDX, 0, "dpl", "dpl", "0x82", 0, 0}, - {0, DPH_IDX, 0, "dph", "dph", "0x83", 0, 0}, - {0, B_IDX, 0, "b", "b", "0xf0", 0, 0}, - {0, A_IDX, 0, "a", "acc", "0xe0", 0, 0}, + {REG_CND, CND_IDX, REG_CND, "C", "psw", "0xd0", 0, 1}, + {0, DPL_IDX, 0, "dpl", "dpl", "0x82", 0, 0}, + {0, DPH_IDX, 0, "dph", "dph", "0x83", 0, 0}, + {0, B_IDX, 0, "b", "b", "0xf0", 0, 0}, + {0, A_IDX, 0, "a", "acc", "0xe0", 0, 0}, }; -int mcs51_nRegs = 17; +int mcs51_nRegs = 16; static void spillThis (symbol *); static void freeAllRegs (); @@ -238,6 +247,15 @@ computeSpillable (iCode * ic) } +/*-----------------------------------------------------------------*/ +/* bitType - will return 1 if the symbol has type REG_BIT */ +/*-----------------------------------------------------------------*/ +static int +bitType (symbol * sym, eBBlock * ebp, iCode * ic) +{ + return (sym->regType == REG_BIT ? 1 : 0); +} + /*-----------------------------------------------------------------*/ /* noSpilLoc - return true if a variable has no spil location */ /*-----------------------------------------------------------------*/ @@ -257,7 +275,7 @@ hasSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic) } /*-----------------------------------------------------------------*/ -/* directSpilLoc - will return 1 if the splilocation is in direct */ +/* directSpilLoc - will return 1 if the spillocation is in direct */ /*-----------------------------------------------------------------*/ static int directSpilLoc (symbol * sym, eBBlock * ebp, iCode * ic) @@ -360,7 +378,7 @@ leastUsedLR (set * sset) { /* if usage is the same then prefer - the spill the smaller of the two */ + to spill the smaller of the two */ if (lsym->used == sym->used) if (getSize (lsym->type) < getSize (sym->type)) sym = lsym; @@ -505,7 +523,10 @@ createStackSpil (symbol * sym) /* set the type to the spilling symbol */ sloc->type = copyLinkChain (sym->type); sloc->etype = getSpec (sloc->type); - SPEC_SCLS (sloc->etype) = S_DATA; + if (!IS_BIT (sloc->etype)) + { + SPEC_SCLS (sloc->etype) = S_DATA; + } SPEC_EXTR (sloc->etype) = 0; SPEC_STAT (sloc->etype) = 0; SPEC_VOLATILE(sloc->etype) = 0; @@ -620,8 +641,6 @@ spillThis (symbol * sym) return; } - - /*-----------------------------------------------------------------*/ /* selectSpil - select a iTemp to spil : rather a simple procedure */ /*-----------------------------------------------------------------*/ @@ -635,10 +654,20 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* get the spillable live ranges */ lrcs = computeSpillable (ic); - /* get all live ranges that are rematerizable */ - if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic))) + /* remove incompatible registers */ + if ((forSym->regType == REG_PTR) || (forSym->regType == REG_GPR)) + { + selectS = liveRangesWith (lrcs, bitType, ebp, ic); + + for (sym = setFirstItem (selectS); sym; sym = setNextItem (selectS)) { + bitVectUnSetBit (lrcs, sym->key); + } + } + /* get all live ranges that are rematerializable */ + if ((selectS = liveRangesWith (lrcs, rematable, ebp, ic))) + { /* return the least used of these */ return leastUsedLR (selectS); } @@ -660,7 +689,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* 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 */ if (!_G.blockSpil && (selectS = liveRangesWith (lrcs, notUsedInBlock, ebp, ic))) @@ -697,7 +725,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* find live ranges with spillocation && not used as pointers */ if ((selectS = liveRangesWith (lrcs, hasSpilLocnoUptr, ebp, ic))) { - sym = leastUsedLR (selectS); /* mark this as allocation required */ sym->usl.spillLoc->allocreq++; @@ -707,7 +734,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* find live ranges with spillocation */ if ((selectS = liveRangesWith (lrcs, hasSpilLoc, ebp, ic))) { - sym = leastUsedLR (selectS); sym->usl.spillLoc->allocreq++; return sym; @@ -718,7 +744,6 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) used ofcourse */ if ((selectS = liveRangesWith (lrcs, noSpilLoc, ebp, ic))) { - /* return a created spil location */ sym = createStackSpil (leastUsedLR (selectS)); sym->usl.spillLoc->allocreq++; @@ -865,7 +890,22 @@ tryAgain: } /*-----------------------------------------------------------------*/ -/* getRegPtrNoSpil - get it cannot split */ +/* getRegBit - will try for Bit if not spill this */ +/*-----------------------------------------------------------------*/ +static regs *getRegBit (symbol * sym) +{ + regs *reg; + + /* try for a bit type */ + if ((reg = allocReg (REG_BIT))) + return reg; + + spillThis (sym); + return 0; +} + +/*-----------------------------------------------------------------*/ +/* getRegPtrNoSpil - get it cannot be spilt */ /*-----------------------------------------------------------------*/ static regs *getRegPtrNoSpil() { @@ -886,7 +926,7 @@ static regs *getRegPtrNoSpil() } /*-----------------------------------------------------------------*/ -/* getRegGprNoSpil - get it cannot split */ +/* getRegGprNoSpil - get it cannot be spilt */ /*-----------------------------------------------------------------*/ static regs *getRegGprNoSpil() { @@ -905,6 +945,27 @@ static regs *getRegGprNoSpil() return 0; } +/*-----------------------------------------------------------------*/ +/* getRegBitNoSpil - get it cannot be spilt */ +/*-----------------------------------------------------------------*/ +static regs *getRegBitNoSpil() +{ + regs *reg; + + /* try for a ptr type */ + if ((reg = allocReg (REG_BIT))) + return reg; + + /* try for gpr type */ + if ((reg = allocReg (REG_GPR))) + return reg; + + assert(0); + + /* just to make the compiler happy */ + return 0; +} + /*-----------------------------------------------------------------*/ /* symHasReg - symbol has a given register */ /*-----------------------------------------------------------------*/ @@ -920,6 +981,29 @@ symHasReg (symbol * sym, regs * reg) return FALSE; } +/*-----------------------------------------------------------------*/ +/* updateRegUsage - update the registers in use at the start of */ +/* this icode */ +/*-----------------------------------------------------------------*/ +static void +updateRegUsage (iCode * ic) +{ + int reg; + + for (reg=0; regriu &= ~(1<riu |= (1<= 8); + } + } +} + /*-----------------------------------------------------------------*/ /* deassignLRs - check the live to and if they have registers & are */ /* not spilt then free up the registers */ @@ -1053,8 +1137,8 @@ reassignLR (operand * op) static int willCauseSpill (int nr, int rt) { - /* first check if there are any avlb registers - of te type required */ + /* first check if there are any available registers + of the type required */ if (rt == REG_PTR) { /* special case for pointer type @@ -1065,6 +1149,11 @@ willCauseSpill (int nr, int rt) if (nFreeRegs (REG_GPR) >= nr) return 0; } + else if (rt == REG_BIT) + { + if (nFreeRegs (rt) >= nr) + return 0; + } else { if (mcs51_ptrRegReq) @@ -1169,21 +1258,11 @@ serialRegAssign (eBBlock ** ebbs, int count) ebbs[i]->entryLabel != returnLabel)) continue; - /* of all instructions do */ + /* for all instructions do */ for (ic = ebbs[i]->sch; ic; ic = ic->next) { -#if 1 - int reg; - - // update the registers in use at the start of this icode - for (reg=0; regriu &= ~(1<riu |= (1<op == IPOP) @@ -1216,6 +1295,13 @@ serialRegAssign (eBBlock ** ebbs, int count) int j; int ptrRegSet = 0; + /* Make sure any spill location is definitely allocated */ + if (sym->isspilt && !sym->remat && sym->usl.spillLoc && + !sym->usl.spillLoc->allocreq) + { + sym->usl.spillLoc->allocreq++; + } + /* if it does not need or is spilt or is already assigned to registers or will not live beyond this instructions */ @@ -1232,11 +1318,20 @@ serialRegAssign (eBBlock ** ebbs, int count) spillThis (sym); continue; } + + willCS = willCauseSpill (sym->nRegs, sym->regType); + /* if this is a bit variable then don't use precious registers + along with expensive bit-to-char conversions but just spill + it */ + if (willCS && SPEC_NOUN(sym->etype) == V_BIT) { + spillThis (sym); + continue; + } + /* if trying to allocate this will cause a spill and there is nothing to spill or this one is rematerializable then spill this one */ - willCS = willCauseSpill (sym->nRegs, sym->regType); spillable = computeSpillable (ic); if (sym->remat || (willCS && bitVectIsZero (spillable))) { spillThis (sym); @@ -1301,13 +1396,15 @@ serialRegAssign (eBBlock ** ebbs, int count) sym->regs[j] = NULL; if (sym->regType == REG_PTR) sym->regs[j] = getRegPtr (ic, ebbs[i], sym); + else if (sym->regType == REG_BIT) + sym->regs[j] = getRegBit (sym); else { if (ic->op == CAST && IS_SYMOP (IC_RIGHT (ic))) { symbol * right = OP_SYMBOL (IC_RIGHT (ic)); - if (right->regs[j]) + if (right->regs[j] && (right->regType != REG_BIT)) sym->regs[j] = allocThisReg (right->regs[j]); } if (!sym->regs[j]) @@ -1318,6 +1415,7 @@ serialRegAssign (eBBlock ** ebbs, int count) this was spilt then break */ if (!sym->regs[j]) { + int i; for (i=0; i < sym->nRegs ; i++ ) sym->regs[i] = NULL; break; @@ -1440,11 +1538,13 @@ static void fillGaps() } } - D(printf("Atemping fillGaps on %s: [",sym->name)); + D(printf("Attempting fillGaps on %s: [",sym->name)); /* THERE IS HOPE !!!! */ for (i=0; i < sym->nRegs ; i++ ) { if (sym->regType == REG_PTR) sym->regs[i] = getRegPtrNoSpil (); + else if (sym->regType == REG_BIT) + sym->regs[i] = getRegBitNoSpil (); else { sym->regs[i] = NULL; @@ -1553,6 +1653,33 @@ static void fillGaps() } } +/*-----------------------------------------------------------------*/ +/* findAllBitregs :- returns bit vector of all bit registers */ +/*-----------------------------------------------------------------*/ +static bitVect * +findAllBitregs (void) +{ + bitVect *rmask = newBitVect (mcs51_nRegs); + int j; + + for (j = 0; j < mcs51_nRegs; j++) + { + if (regs8051[j].type == REG_BIT) + rmask = bitVectSetBit (rmask, regs8051[j].rIdx); + } + + return rmask; +} + +/*-----------------------------------------------------------------*/ +/* mcs51_allBitregs :- returns bit vector of all bit registers */ +/*-----------------------------------------------------------------*/ +bitVect * +mcs51_allBitregs (void) +{ + return _G.allBitregs; +} + /*-----------------------------------------------------------------*/ /* rUmaskForOp :- returns register mask for an operand */ /*-----------------------------------------------------------------*/ @@ -1579,8 +1706,7 @@ mcs51_rUmaskForOp (operand * op) for (j = 0; j < sym->nRegs; j++) { if (sym->regs[j]) /* EEP - debug */ - rumask = bitVectSetBit (rumask, - sym->regs[j]->rIdx); + rumask = bitVectSetBit (rumask, sym->regs[j]->rIdx); } return rumask; @@ -1809,13 +1935,12 @@ regTypeNum (eBBlock *ebbs) } /* determine the type of register required */ - if (sym->nRegs == 1 && - IS_PTR (sym->type) && - sym->uptr) + if (sym->nRegs == 1 && IS_PTR (sym->type) && sym->uptr) sym->regType = REG_PTR; + else if (IS_BIT(sym->type)) + sym->regType = REG_BIT; else sym->regType = REG_GPR; - } else /* for the first run we don't provide */ @@ -2344,7 +2469,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) /* 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 + that definition is either a return value from a function or does not contain any variables in far space */ if (bitVectnBitsOn (OP_USES (op)) > 1) @@ -2712,7 +2837,7 @@ accuse: } /*-----------------------------------------------------------------*/ -/* packForPush - hueristics to reduce iCode for pushing */ +/* packForPush - heuristics to reduce iCode for pushing */ /*-----------------------------------------------------------------*/ static void packForPush (iCode * ic, eBBlock ** ebpp, int blockno) @@ -2812,6 +2937,47 @@ packRegisters (eBBlock ** ebpp, int blockno) for (ic = ebp->sch; ic; ic = ic->next) { + /* Fix for bug #979599: */ + /* P0 &= ~1; */ + + /* Look for two subsequent iCodes with */ + /* iTemp := _c; */ + /* _c = iTemp & op; */ + /* and replace them by */ + /* iTemp := _c; */ + /* _c = _c & op; */ + if ((ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') && + ic->prev && + ic->prev->op == '=' && + IS_ITEMP (IC_LEFT (ic)) && + IC_LEFT (ic) == IC_RESULT (ic->prev) && + isOperandEqual (IC_RESULT(ic), IC_RIGHT(ic->prev))) + { + iCode* ic_prev = ic->prev; + symbol* prev_result_sym = OP_SYMBOL (IC_RESULT (ic_prev)); + + ReplaceOpWithCheaperOp (&IC_LEFT (ic), IC_RESULT (ic)); + if (IC_RESULT (ic_prev) != IC_RIGHT (ic)) + { + bitVectUnSetBit (OP_USES (IC_RESULT (ic_prev)), ic->key); + if (/*IS_ITEMP (IC_RESULT (ic_prev)) && */ + prev_result_sym->liveTo == ic->seq) + { + prev_result_sym->liveTo = ic_prev->seq; + } + } + bitVectSetBit (OP_USES (IC_RESULT (ic)), ic->key); + + bitVectSetBit (ic->rlive, IC_RESULT (ic)->key); + + if (bitVectIsZero (OP_USES (IC_RESULT (ic_prev)))) + { + bitVectUnSetBit (ic->rlive, IC_RESULT (ic)->key); + bitVectUnSetBit (OP_DEFS (IC_RESULT (ic_prev)), ic_prev->key); + remiCodeFromeBBlock (ebp, ic_prev); + hTabDeleteItem (&iCodehTab, ic_prev->key, ic_prev, DELETE_ITEM, NULL); + } + } /* if this is an itemp & result of an address of a true sym then mark this as rematerialisable */ @@ -2924,8 +3090,7 @@ packRegisters (eBBlock ** ebpp, int blockno) this is the only usage then mark the itemp as a conditional */ if ((IS_CONDITIONAL (ic) || - (IS_BITWISE_OP(ic) && isBitwiseOptimizable (ic)) || - (POINTER_GET (ic) && getSize (operandType (IC_RESULT (ic))) <=1)) && + (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)) && @@ -2980,8 +3145,8 @@ packRegisters (eBBlock ** ebpp, int blockno) packRegsForOneuse (ic, IC_LEFT (ic), ebp); - /* if this is cast for intergral promotion then - check if only use of the definition of the + /* if this is a cast for intergral promotion then + check if it's the only use of the definition of the operand being casted/ if yes then replace the result of that arithmetic operation with this result and get rid of the cast */ @@ -3072,8 +3237,10 @@ packRegisters (eBBlock ** ebpp, int blockno) /* assignRegisters - assigns registers to each live range as need */ /*-----------------------------------------------------------------*/ void -mcs51_assignRegisters (eBBlock ** ebbs, int count) +mcs51_assignRegisters (ebbIndex * ebbi) { + eBBlock ** ebbs = ebbi->bbOrder; + int count = ebbi->count; iCode *ic; int i; @@ -3081,7 +3248,16 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) setToNull ((void *) &_G.regAssigned); setToNull ((void *) &_G.totRegAssigned); mcs51_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; + if ((currFunc && IFFUNC_ISREENT (currFunc->type)) || options.stackAuto) + { + mcs51_nRegs = 16; + } + else + { mcs51_nRegs = 8; + } + _G.allBitregs = findAllBitregs (); + /* change assignments this will remove some live ranges reducing some register pressure */ @@ -3094,7 +3270,7 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) recomputeLiveRanges (ebbs, count); if (options.dump_pack) - dumpEbbsToFileExt (DUMP_PACK, ebbs, count); + dumpEbbsToFileExt (DUMP_PACK, ebbi); /* first determine for each live range the number of registers & the type of registers required for each */ @@ -3142,7 +3318,7 @@ mcs51_assignRegisters (eBBlock ** ebbs, int count) if (options.dump_rassgn) { - dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count); + dumpEbbsToFileExt (DUMP_RASSGN, ebbi); dumpLiveRanges (DUMP_LRANGE, liveRanges); }