X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fds390%2Fralloc.c;h=042eb5009109fada2b0d36957caa48e67fdedada;hb=d8c236efd1a19e0622511f35efb1de0c181eab29;hp=d6206f52eeeaede71afeefb64af3a989047399a6;hpb=20d011f428a26a3ae0546e7dbc0c1f89ded856ce;p=fw%2Fsdcc diff --git a/src/ds390/ralloc.c b/src/ds390/ralloc.c index d6206f52..042eb500 100644 --- a/src/ds390/ralloc.c +++ b/src/ds390/ralloc.c @@ -362,7 +362,7 @@ leastUsedLR (set * sset) } - setToNull ((void **) &sset); + setToNull ((void *) &sset); sym->blockSpil = 0; return sym; } @@ -605,12 +605,12 @@ spillThis (symbol * sym) sym->regs[i] = NULL; } - /* if spilt on stack then free up r0 & r1 + /* if spilt on stack then free up r0 & r1 if they could have been assigned to some LIVE ranges */ - if (!ds390_ptrRegReq && isSpiltOnStack (sym)) + if (!ds390_ptrRegReq && isSpiltOnStack (sym) && !options.stack10bit) { - ds390_ptrRegReq += !options.stack10bit; + ds390_ptrRegReq ++; spillLRWithPtrReg (sym); } @@ -1337,17 +1337,25 @@ serialRegAssign (eBBlock ** ebbs, int count) if (!sym->regs[j]) break; } - /* if it shares registers with operands make sure + + /* if it shares registers with operands make sure that they are in the same position */ - if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) && - OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') - positionRegs (OP_SYMBOL (IC_RESULT (ic)), - OP_SYMBOL (IC_LEFT (ic))); - /* do the same for the right operand */ - if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) && - OP_SYMBOL (IC_RIGHT (ic))->nRegs) - positionRegs (OP_SYMBOL (IC_RESULT (ic)), - OP_SYMBOL (IC_RIGHT (ic))); + if (!POINTER_SET(ic) && !POINTER_GET(ic)) + { + if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) && + OP_SYMBOL (IC_LEFT (ic))->nRegs) + { + positionRegs (OP_SYMBOL (IC_RESULT (ic)), + OP_SYMBOL (IC_LEFT (ic))); + } + /* do the same for the right operand */ + if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) && + OP_SYMBOL (IC_RIGHT (ic))->nRegs) + { + positionRegs (OP_SYMBOL (IC_RESULT (ic)), + OP_SYMBOL (IC_RIGHT (ic))); + } + } if (ptrRegSet) { @@ -1369,6 +1377,7 @@ static void fillGaps() symbol *sym =NULL; int key =0; int loop = 0, change; + int pass; if (getenv("DISABLE_FILL_GAPS")) return; @@ -1460,44 +1469,53 @@ static void fillGaps() sym->regs[i] = getRegGprNoSpil (); } - /* for all its definitions & uses check if the registers + /* For all its definitions check if the registers allocated needs positioning NOTE: we can position only ONCE if more than One positioning required - then give up */ + then give up. + We may need to perform the checks twice; once to + position the registers as needed, the second to + verify any register repositioning is still + compatible. + */ sym->isspilt = 0; - for (i = 0 ; i < sym->defs->size ; i++ ) { - if (bitVectBitValue(sym->defs,i)) { - iCode *ic; - if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ; - if (SKIP_IC(ic)) continue; - assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */ - /* if left is assigned to registers */ - if (IS_SYMOP(IC_LEFT(ic)) && - bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) { - pdone += positionRegs(sym,OP_SYMBOL(IC_LEFT(ic))); + for (pass=0; pass<2; pass++) { + for (i = 0 ; i < sym->defs->size ; i++ ) { + if (bitVectBitValue(sym->defs,i)) { + iCode *ic; + if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ; + if (SKIP_IC(ic)) continue; + assert(isSymbolEqual(sym,OP_SYMBOL(IC_RESULT(ic)))); /* just making sure */ + /* if left is assigned to registers */ + if (IS_SYMOP(IC_LEFT(ic)) && + bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_LEFT(ic))->key)) { + pdone += (positionRegs(sym,OP_SYMBOL(IC_LEFT(ic)))>0); + } + if (IS_SYMOP(IC_RIGHT(ic)) && + bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) { + pdone += (positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic)))>0); + } + if (pdone > 1) break; } - if (IS_SYMOP(IC_RIGHT(ic)) && - bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(IC_RIGHT(ic))->key)) { - pdone += positionRegs(sym,OP_SYMBOL(IC_RIGHT(ic))); + } + 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 (POINTER_SET(ic) || POINTER_GET(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)))>0); + } + if (pdone > 1) break; } - 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; - } - } + } + if (pdone == 0) break; /* second pass only if regs repositioned */ + if (pdone > 1) break; + } /* had to position more than once GIVE UP */ if (pdone > 1) { /* UNDO all the changes we made to try this */ @@ -1653,7 +1671,7 @@ createRegMask (eBBlock ** ebbs, int count) "createRegMask cannot find live range"); exit (0); } - +#if 0 /* special case for ruonly */ if (sym->ruonly && sym->liveFrom != sym->liveTo) { int size = getSize(sym->type); @@ -1662,6 +1680,7 @@ createRegMask (eBBlock ** ebbs, int count) ic->rMask = bitVectSetBit (ic->rMask, j++); continue ; } +#endif /* if no register assigned to it */ if (!sym->nRegs || sym->isspilt) continue; @@ -2292,6 +2311,30 @@ static int packRegsDPTRnuse( operand *op , int dptr) nfs++; } + // Check that no other ops in this range have been assigned to dptr1. + // I don't understand why this is not caught by the first check, above. + // But it isn't always, see bug 769624. + if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && + (OP_SYMBOL(IC_RESULT(ic))->dptr == 1)) + { + //fprintf(stderr, "dptr1 already in use in live range #1\n"); + return 0; + } + + if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && + (OP_SYMBOL(IC_LEFT(ic))->dptr == 1)) + { + //fprintf(stderr, "dptr1 already in use in live range # 2\n"); + return 0; + } + + if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && + (OP_SYMBOL(IC_RIGHT(ic))->dptr == 1)) + { + //fprintf(stderr, "dptr1 already in use in live range # 3\n"); + return 0; + } + if (nfs && IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && OP_SYMBOL(IC_RESULT(ic))->ruonly) return 0; @@ -2983,6 +3026,10 @@ ds390_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); @@ -3018,7 +3065,8 @@ ds390_assignRegisters (eBBlock ** ebbs, int count) createRegMask (ebbs, count); /* redo that offsets for stacked automatic variables */ - redoStackOffsets (); + if (currFunc) + redoStackOffsets (); if (options.dump_rassgn) { dumpEbbsToFileExt (DUMP_RASSGN, ebbs, count); @@ -3037,8 +3085,8 @@ ds390_assignRegisters (eBBlock ** ebbs, int count) /* free up any _G.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 */ ds390_nRegs = 8; freeAllRegs ();