X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fz80%2Fralloc.c;h=ca66aa9a051220df8cab5cacc5f01c94fbc61ea6;hb=c2f2abbf9d58d7f0def3509779547f50ade2e2ab;hp=b23b4b221e41543f502ba3d71f37643eaa8d7238;hpb=9248424afe9fba758b93efc95507178dc2d15442;p=fw%2Fsdcc diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index b23b4b22..ca66aa9a 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -53,7 +53,7 @@ enum DISABLE_PACK_ACC = 0, DISABLE_PACK_ASSIGN = 0, DISABLE_PACK_ONE_USE = 0, - DISABLE_PACK_HL = 0, + DISABLE_PACK_HL = 1, DISABLE_PACK_IY = 0 }; @@ -229,34 +229,6 @@ useReg (regs * reg) reg->isFree = 0; } -#if 0 -/*-----------------------------------------------------------------*/ -/* allDefsOutOfRange - all definitions are out of a range */ -/*-----------------------------------------------------------------*/ -static bool -allDefsOutOfRange (bitVect * defs, int fseq, int toseq) -{ - 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; -} -#endif - /*-----------------------------------------------------------------*/ /* computeSpillable - given a point find the spillable live ranges */ /*-----------------------------------------------------------------*/ @@ -384,7 +356,7 @@ leastUsedLR (set * sset) } - setToNull ((void **) &sset); + setToNull ((void *) &sset); sym->blockSpil = 0; return sym; } @@ -587,17 +559,6 @@ hasSpilLocnoUptr (symbol * sym, eBBlock * ebp, iCode * ic) return ((sym->usl.spillLoc && !sym->uptr) ? 1 : 0); } -/*-----------------------------------------------------------------*/ -/* 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 */ /*-----------------------------------------------------------------*/ @@ -802,6 +763,7 @@ regs * getRegGpr (iCode * ic, eBBlock * ebp, symbol * sym) { regs *reg; + int j; D (D_ALLOC, ("getRegGpr: on ic %p\n", ic)); tryAgain: @@ -818,6 +780,11 @@ tryAgain: D (D_ALLOC, ("getRegGpr: have to spill.\n")); return NULL; } + + /* make sure partially assigned registers aren't reused */ + for (j=0; j<=sym->nRegs; j++) + if (sym->regs[j]) + sym->regs[j]->isFree = 0; /* this looks like an infinite loop but in really selectSpil will abort */ @@ -835,6 +802,9 @@ static regs *getRegGprNoSpil() return reg; } assert(0); + + /* just to make the compiler happy */ + return 0; } /** Symbol has a given register. @@ -916,6 +886,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */ result->liveTo > ic->seq && /* and will live beyond this */ result->liveTo <= ebp->lSeq && /* does not go beyond this block */ + result->liveFrom == ic->seq && /* does not start before here */ result->regType == sym->regType && /* same register types */ result->nRegs && /* which needs registers */ !result->isspilt && /* and does not already have them */ @@ -1076,6 +1047,31 @@ tryAllocatingRegPair (symbol * sym) return FALSE; } +/*------------------------------------------------------------------*/ +/* verifyRegsAssigned - make sure an iTemp is properly initialized; */ +/* it should either have registers or have beed spilled. Otherwise, */ +/* there was an uninitialized variable, so just spill this to get */ +/* the operand in a valid state. */ +/*------------------------------------------------------------------*/ +static void +verifyRegsAssigned (operand *op, iCode * ic) +{ + symbol * sym; + + if (!op) return; + if (!IS_ITEMP (op)) return; + + sym = OP_SYMBOL (op); + if (sym->isspilt) return; + if (!sym->nRegs) return; + if (sym->regs[0]) return; + + werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, + sym->prereqv ? sym->prereqv->name : sym->name); + spillThis (sym); +} + + /** Serially allocate registers to the variables. This is the main register allocation function. It is called after packing. @@ -1135,6 +1131,13 @@ serialRegAssign (eBBlock ** ebbs, int count) int j; D (D_ALLOC, ("serialRegAssign: in loop on result %p\n", sym)); + + /* Make sure any spill location is definately 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 @@ -1173,6 +1176,17 @@ serialRegAssign (eBBlock ** ebbs, int count) } + /* If the live range preceeds the point of definition + then ideally we must take into account registers that + have been allocated after sym->liveFrom but freed + before ic->seq. This is complicated, so spill this + symbol instead and let fillGaps handle the allocation. */ + if (sym->liveFrom < ic->seq) + { + spillThis (sym); + continue; + } + /* if it has a spillocation & is used less than all other live ranges then spill this */ if (willCS) { @@ -1236,6 +1250,40 @@ serialRegAssign (eBBlock ** ebbs, int count) } } } + + /* Check for and fix any problems with uninitialized operands */ + for (i = 0; i < count; i++) + { + iCode *ic; + + if (ebbs[i]->noPath && + (ebbs[i]->entryLabel != entryLabel && + ebbs[i]->entryLabel != returnLabel)) + continue; + + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + if (SKIP_IC2 (ic)) + continue; + + if (ic->op == IFX) + { + verifyRegsAssigned (IC_COND (ic), ic); + continue; + } + + if (ic->op == JUMPTABLE) + { + verifyRegsAssigned (IC_JTCOND (ic), ic); + continue; + } + + verifyRegsAssigned (IC_RESULT (ic), ic); + verifyRegsAssigned (IC_LEFT (ic), ic); + verifyRegsAssigned (IC_RIGHT (ic), ic); + } + } + } /*-----------------------------------------------------------------*/ @@ -1267,7 +1315,8 @@ static void fillGaps() bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */ continue ; - assert (clr = hTabItemWithKey(liveRanges,i)); + clr = hTabItemWithKey(liveRanges,i); + assert(clr); /* mark these registers as used */ for (k = 0 ; k < clr->nRegs ; k++ ) @@ -1308,10 +1357,25 @@ static void fillGaps() 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 = 0; + sym->isspilt = 1; for (i=0; i < sym->nRegs ; i++ ) { sym->regs[i] = NULL; } @@ -1627,26 +1691,57 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) if (SKIP_IC2 (dic)) continue; - if (IS_SYMOP (IC_RESULT (dic)) && - IC_RESULT (dic)->key == IC_RIGHT (ic)->key) - { - break; - } + if (dic->op == IFX) + { + if (IS_SYMOP (IC_COND (dic)) && + (IC_COND (dic)->key == IC_RESULT (ic)->key || + IC_COND (dic)->key == IC_RIGHT (ic)->key)) + { + dic = NULL; + break; + } + } + else + { + if (IS_TRUE_SYMOP (IC_RESULT (dic)) && + IS_OP_VOLATILE (IC_RESULT (dic))) + { + dic = NULL; + break; + } - if (IS_SYMOP (IC_RIGHT (dic)) && - (IC_RIGHT (dic)->key == IC_RESULT (ic)->key || - IC_RIGHT (dic)->key == IC_RIGHT (ic)->key)) - { - dic = NULL; - break; - } + if (IS_SYMOP (IC_RESULT (dic)) && + IC_RESULT (dic)->key == IC_RIGHT (ic)->key) + { + if (POINTER_SET (dic)) + dic = NULL; - if (IS_SYMOP (IC_LEFT (dic)) && - (IC_LEFT (dic)->key == IC_RESULT (ic)->key || - IC_LEFT (dic)->key == IC_RIGHT (ic)->key)) - { - dic = NULL; - break; + break; + } + + if (IS_SYMOP (IC_RIGHT (dic)) && + (IC_RIGHT (dic)->key == IC_RESULT (ic)->key || + IC_RIGHT (dic)->key == IC_RIGHT (ic)->key)) + { + dic = NULL; + break; + } + + if (IS_SYMOP (IC_LEFT (dic)) && + (IC_LEFT (dic)->key == IC_RESULT (ic)->key || + IC_LEFT (dic)->key == IC_RIGHT (ic)->key)) + { + dic = NULL; + break; + } + + if (IS_SYMOP (IC_RESULT (dic)) && + IC_RESULT (dic)->key == IC_RESULT (ic)->key) + { + dic = NULL; + break; + } + } } @@ -1695,7 +1790,7 @@ pack: // PENDING: Check vs mcs51 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; } @@ -2427,6 +2522,12 @@ packRegsForIYUse (iCode * lic, operand * op, eBBlock * ebp) return NULL; } + if (getSize (operandType (op)) != 2) + { + D (D_ACCUSE2, (" + Dropping as operation has size is too big\n")); + return FALSE; + } + /* Nothing else that clashes with this is using the scratch register. Scan through all of the intermediate instructions and see if any of them could nuke HL. @@ -2894,6 +2995,7 @@ packRegisters (eBBlock * ebp) /* if pointer get */ if (!DISABLE_PACK_ONE_USE && POINTER_GET (ic) && + IS_SYMOP (IC_LEFT (ic)) && /* MLH: dont have far space !isOperandInFarSpace(IC_RESULT(ic))&& */ !OP_SYMBOL (IC_LEFT (ic))->remat && @@ -2913,10 +3015,16 @@ packRegisters (eBBlock * ebp) if (!DISABLE_PACK_HL && IS_ITEMP (IC_RESULT (ic))) { + /* PENDING */ if (IS_GB) - packRegsForHLUse (ic); + { + if (0) + packRegsForHLUse (ic); + } else - packRegsForHLUse3 (ic, IC_RESULT (ic), ebp); + { + packRegsForHLUse3 (ic, IC_RESULT (ic), ebp); + } } if (!DISABLE_PACK_IY && IS_ITEMP (IC_RESULT (ic)) && IS_Z80) @@ -2971,9 +3079,10 @@ joinPushes (iCode *lic) first = (int)operandLitValue ( IC_LEFT (ic)); second = (int)operandLitValue ( IC_LEFT (uic)); - sprintf (buffer, "%u", ((first << 8) | (second & 0xFF)) & 0xFFFFU); + sprintf (buffer, "%uu", ((first << 8) | (second & 0xFF)) & 0xFFFFU); val = constVal (buffer); SPEC_NOUN (val->type) = V_INT; + IC_LEFT (ic) = operandFromOperand (IC_LEFT (ic)); IC_LEFT (ic)->operand.valOperand = val; /* Now remove the second one from the list. */ @@ -2992,8 +3101,10 @@ joinPushes (iCode *lic) /* assignRegisters - assigns registers to each live range as need */ /*-----------------------------------------------------------------*/ void -z80_assignRegisters (eBBlock ** ebbs, int count) +z80_assignRegisters (ebbIndex * ebbi) { + eBBlock ** ebbs = ebbi->bbOrder; + int count = ebbi->count; iCode *ic; int i; @@ -3020,8 +3131,12 @@ z80_assignRegisters (eBBlock ** ebbs, int count) for (i = 0; i < count; i++) packRegisters (ebbs[i]); + /* liveranges probably changed by register packing + so we compute them again */ + 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 */ @@ -3049,7 +3164,7 @@ z80_assignRegisters (eBBlock ** ebbs, int count) } if (options.dump_rassgn) { - dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count); + dumpEbbsToFileExt (DUMP_RASSGN, ebbi); dumpLiveRanges (DUMP_LRANGE, liveRanges); } @@ -3070,8 +3185,8 @@ z80_assignRegisters (eBBlock ** ebbs, int count) /* free up any stackSpil locations allocated */ applyToSet (_G.stackSpil, deallocStackSpil); _G.slocNum = 0; - setToNull ((void **) &_G.stackSpil); - setToNull ((void **) &_G.spiltSet); + setToNull ((void *) &_G.stackSpil); + setToNull ((void *) &_G.spiltSet); /* mark all registers as free */ freeAllRegs ();