+2004-04-13 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
+
+ * 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 <bernhard AT bernhardheld.de>
* src/SDCCast.c (decorateType): fixed bug #898889,
}
}
+/*-----------------------------------------------------------------*/
+/* 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 */
if (options.dump_raw)
dumpEbbsToFileExt (DUMP_RAW1, ebbs, count);
+ optimizeCastCast (ebbs, saveCount);
+
/* do common subexpression elimination for each block */
change = cseAllBlocks (ebbs, saveCount, FALSE);
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 */
/*-----------------------------------------------------------------*/
}
}
#endif
-
/* if this is an ipop that means some live
range will have to be assigned again */
if (ic->op == IPOP)
_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 */
symbol *sym =NULL;
int key =0;
int pass;
+ iCode *ic = NULL;
if (getenv("DISABLE_FILL_GAPS")) return;
clr = hTabItemWithKey(liveRanges,i);
assert(clr);
-
+
/* mark these registers as used */
for (k = 0 ; k < clr->nRegs ; k++ )
useReg(clr->regs[k]);
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"));
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;
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--;