X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fz80%2Fralloc.c;h=076277902ed9216c408ae3adb6653b85e6b26e5a;hb=877c9a93ee346a15f3650f34ba425c02aaf7bfda;hp=72331e49b3828f3162218cdc32ae48e10588acc3;hpb=95499d5d9525e155075240e5ce2a2711652a4808;p=fw%2Fsdcc diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index 72331e49..07627790 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 }; @@ -356,7 +356,7 @@ leastUsedLR (set * sset) } - setToNull ((void **) &sset); + setToNull ((void *) &sset); sym->blockSpil = 0; return sym; } @@ -763,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: @@ -779,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 */ @@ -880,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 */ @@ -1040,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. @@ -1137,6 +1169,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) { @@ -1200,6 +1243,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); + } + } + } /*-----------------------------------------------------------------*/ @@ -1607,26 +1684,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; + } + } } @@ -1675,7 +1783,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; } @@ -2880,6 +2988,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 && @@ -2963,9 +3072,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. */ @@ -3012,6 +3122,10 @@ 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); @@ -3062,8 +3176,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 ();