From: epetrich Date: Tue, 13 Apr 2004 04:06:32 +0000 (+0000) Subject: * src/mcs51/ralloc.c (serialRegAssign, fillGaps, allocThisReg): try X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=46c123c612c63aa8c410e3d559d88a3255d83325;p=fw%2Fsdcc * src/mcs51/ralloc.c (serialRegAssign, fillGaps, allocThisReg): try harder to keep the same registers during a CAST iCode * src/SDCCopt.c (optimizeCastCast, eBBlockFromiCode): casts of char to long via int can be done in a single cast, if the signedness is correct. * support/regression/tests/bug-927659.c: fixed to avoid conflict with putchar() in tinibios.c in ds390's library git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3287 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index d133523b..f63f8f79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2004-04-13 Erik Petrich + + * src/mcs51/ralloc.c (serialRegAssign, fillGaps, allocThisReg): try + harder to keep the same registers during a CAST iCode + * src/SDCCopt.c (optimizeCastCast, eBBlockFromiCode): casts of char to + long via int can be done in a single cast, if the signedness is + correct. + * support/regression/tests/bug-927659.c: fixed to avoid conflict with + putchar() in tinibios.c in ds390's library + 2004-04-12 Bernhard Held * src/SDCCast.c (decorateType): fixed bug #898889, diff --git a/src/SDCCopt.c b/src/SDCCopt.c index 8ae80be0..cfb416d9 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -995,6 +995,76 @@ discardDeadParamReceives (eBBlock ** ebbs, int count) } } +/*-----------------------------------------------------------------*/ +/* optimizeCastCast - remove unneeded intermediate casts. */ +/* Integer promotion may cast (un)signed char to int and then */ +/* recast the int to (un)signed long. If the signedness of the */ +/* char and long are the same, the cast can be safely performed in */ +/* a single step. */ +/*-----------------------------------------------------------------*/ +static void +optimizeCastCast (eBBlock ** ebbs, int count) +{ + int i; + iCode *ic; + iCode *uic; + sym_link * type1; + sym_link * type2; + sym_link * type3; + symbol * sym; + + for (i = 0; i < count; i++) + { + for (ic = ebbs[i]->sch; ic; ic = ic->next) + { + + if (ic->op == CAST && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic))) + { + type1 = operandType (IC_RIGHT (ic)); + type2 = operandType (IC_RESULT (ic)); + + /* Look only for a cast from an integer type to an */ + /* integer type that has no loss of bits */ + if (!IS_INTEGRAL (type1) || !IS_INTEGRAL (type2)) + continue; + if (getSize (type2) < getSize (type1)) + continue; + + /* There must be only one use of this first result */ + if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1) + continue; + + /* This use must be a second cast */ + uic = hTabItemWithKey (iCodehTab, + bitVectFirstBit (OP_USES (IC_RESULT (ic)))); + if (!uic || uic->op != CAST) + continue; + + /* It must be a cast to another integer type that */ + /* has no loss of bits */ + type3 = operandType (IC_RESULT (uic)); + if (!IS_INTEGRAL (type3)) + continue; + if (getSize (type3) < getSize (type2)) + continue; + + /* The signedness between the first and last types */ + /* must match */ + if (SPEC_USIGN (type3) != SPEC_USIGN (type1)) + continue; + + /* Change the first cast to a simple assignment and */ + /* let the second cast do all the work */ + ic->op = '='; + IC_LEFT (ic) = NULL; + sym = OP_SYMBOL (IC_RESULT (ic)); + sym->type = copyLinkChain (type1); + sym->etype = getSpec (sym->type); + } + } + } +} + /*-----------------------------------------------------------------*/ /* eBBlockFromiCode - creates extended basic blocks from iCode */ /* will return an array of eBBlock pointers */ @@ -1052,6 +1122,8 @@ eBBlockFromiCode (iCode * ic) if (options.dump_raw) dumpEbbsToFileExt (DUMP_RAW1, ebbs, count); + optimizeCastCast (ebbs, saveCount); + /* do common subexpression elimination for each block */ change = cseAllBlocks (ebbs, saveCount, FALSE); diff --git a/src/mcs51/ralloc.c b/src/mcs51/ralloc.c index c81c2158..d7708eae 100644 --- a/src/mcs51/ralloc.c +++ b/src/mcs51/ralloc.c @@ -121,6 +121,23 @@ allocReg (short type) return NULL; } +/*-----------------------------------------------------------------*/ +/* allocThisReg - allocates a particular register (if free) */ +/*-----------------------------------------------------------------*/ +static regs * +allocThisReg (regs * reg) +{ + if (!reg->isFree) + return NULL; + + reg->isFree = 0; + if (currFunc) + currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx); + + return reg; +} + + /*-----------------------------------------------------------------*/ /* mcs51_regWithIdx - returns pointer to register wit index number */ /*-----------------------------------------------------------------*/ @@ -1162,7 +1179,6 @@ serialRegAssign (eBBlock ** ebbs, int count) } } #endif - /* if this is an ipop that means some live range will have to be assigned again */ if (ic->op == IPOP) @@ -1267,18 +1283,32 @@ serialRegAssign (eBBlock ** ebbs, int count) _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key); for (j = 0; j < sym->nRegs; j++) { + sym->regs[j] = NULL; if (sym->regType == REG_PTR) sym->regs[j] = getRegPtr (ic, ebbs[i], sym); else - sym->regs[j] = getRegGpr (ic, ebbs[i], sym); + { /* + if (ic->op == CAST && IS_SYMOP (IC_RIGHT (ic))) + { + symbol * right = OP_SYMBOL (IC_RIGHT (ic)); + + if (right->regs[j]) + sym->regs[j] = allocThisReg (right->regs[j]); + } + if (!sym->regs[j]) */ + sym->regs[j] = getRegGpr (ic, ebbs[i], sym); + } /* if the allocation failed which means this was spilt then break */ - if (!sym->regs[j]) { - break; - } + if (!sym->regs[j]) + { + for (i=0; i < sym->nRegs ; i++ ) + sym->regs[i] = NULL; + break; + } } - + if (!POINTER_SET(ic) && !POINTER_GET(ic)) { /* if it shares registers with operands make sure that they are in the same position */ @@ -1346,6 +1376,7 @@ static void fillGaps() symbol *sym =NULL; int key =0; int pass; + iCode *ic = NULL; if (getenv("DISABLE_FILL_GAPS")) return; @@ -1370,7 +1401,7 @@ static void fillGaps() clr = hTabItemWithKey(liveRanges,i); assert(clr); - + /* mark these registers as used */ for (k = 0 ; k < clr->nRegs ; k++ ) useReg(clr->regs[k]); @@ -1382,13 +1413,36 @@ static void fillGaps() continue ; } + ic = NULL; + for (i = 0 ; i < sym->defs->size ; i++ ) + { + if (bitVectBitValue(sym->defs,i)) + { + if (!(ic = hTabItemWithKey(iCodehTab,i))) + continue; + if (ic->op == CAST) + break; + } + } + D(printf("Atemping 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 - sym->regs[i] = getRegGprNoSpil (); + { + sym->regs[i] = NULL; + if (ic && ic->op == CAST && IS_SYMOP (IC_RIGHT (ic))) + { + symbol * right = OP_SYMBOL (IC_RIGHT (ic)); + + if (right->regs[i]) + sym->regs[i] = allocThisReg (right->regs[i]); + } + if (!sym->regs[i]) + sym->regs[i] = getRegGprNoSpil (); + } D(printf("%s ", sym->regs[i]->name)); } D(printf("]\n")); @@ -1407,7 +1461,6 @@ static void fillGaps() D(printf(" checking definitions\n")); for (i = 0 ; i < sym->defs->size ; i++ ) { if (bitVectBitValue(sym->defs,i)) { - iCode *ic; if (!(ic = hTabItemWithKey(iCodehTab,i))) continue ; D(printf(" ic->seq = %d\n", ic->seq)); if (SKIP_IC(ic)) continue; @@ -1477,6 +1530,7 @@ static void fillGaps() continue ; } D(printf ("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN")); + _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key); sym->isspilt = sym->spillA = 0 ; sym->usl.spillLoc->allocreq--; diff --git a/support/regression/tests/bug-927659.c b/support/regression/tests/bug-927659.c index dde1e77d..dac64e04 100644 --- a/support/regression/tests/bug-927659.c +++ b/support/regression/tests/bug-927659.c @@ -34,7 +34,7 @@ testReverse(void) /*************************************************************/ -#ifndef PORT_HOST +#if !defined(PORT_HOST) && !defined(SDCC_ds390) void putchar (char c) { c;