newAst_VALUE (valueFromLit ((float) i))),
newAst_VALUE (valueFromLit (*s))));
- // now we don't need iexpr's symbol anymore
- {
- symbol *sym=AST_SYMBOL(iexpr);
- memmap *segment=SPEC_OCLS(sym->etype);
- deleteSetItem(&segment->syms, sym);
- }
+ // now WE don't need iexpr's symbol anymore
+ freeStringSymbol(AST_SYMBOL(iexpr));
+
return decorateType (resolveSymbols (rast));
}
return init;
}
+/*-----------------------------------------------------------------*/
+/* freeStringSymbol - delete a literal string if no more usage */
+/*-----------------------------------------------------------------*/
+void freeStringSymbol(symbol *sym) {
+ /* make sure this is a literal string */
+ assert (sym->isstrlit);
+ if (--sym->isstrlit == 0) { // lower the usage count
+ memmap *segment=SPEC_OCLS(sym->etype);
+ if (segment) {
+ deleteSetItem(&segment->syms, sym);
+ }
+ }
+}
+
/*-----------------------------------------------------------------*/
/* stringToSymbol - creates a symbol from a literal string */
/*-----------------------------------------------------------------*/
char name[SDCC_NAME_MAX + 1];
static int charLbl = 0;
symbol *sym;
+ set *sp;
+
+ // have we heard this before?
+ for (sp=statsg->syms; sp; sp=sp->next) {
+ sym=sp->item;
+ if (sym->isstrlit &&
+ !strcmp(SPEC_CVAL(sym->etype).v_char, SPEC_CVAL(val->etype).v_char)) {
+ // yes, this is old news. Don't publish it again.
+ sym->isstrlit++; // but raise the usage count
+ return symbolVal(sym);
+ }
+ }
sprintf (name, "_str_%d", charLbl++);
sym = newSymbol (name, 0); /* make it @ level 0 */
// a function's address will never change
return TRUE;
}
+ if (IS_AST_SYM_VALUE(cexpr) && IS_ARRAY(AST_SYMBOL(cexpr)->type)) {
+ // an array's address will never change
+ return TRUE;
+ }
if (IS_AST_SYM_VALUE(cexpr) &&
IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
// a symbol in code space will never change
resolveIvalSym (sym->ival);
printIval (sym, sym->type, sym->ival, out);
noAlloc--;
+ // if sym->ival is a string, WE don't need it anymore
+ if (IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
+ list2val(sym->ival)->sym->isstrlit) {
+ freeStringSymbol(list2val(sym->ival)->sym);
+ }
}
else {
/* allocate space */
unsigned isref:1; /* has been referenced */
unsigned isind:1; /* is a induction variable */
unsigned isinvariant:1; /* is a loop invariant */
- unsigned isstrlit:1; /* is a string literal */
unsigned cdef:1; /* compiler defined symbol */
unsigned addrtaken:1; /* address of the symbol was taken */
unsigned isreqv:1; /* is the register quivalent of a symbol */
unsigned spildir:1; /* spilt in direct space */
unsigned ptrreg:1; /* this symbol assigned to a ptr reg */
unsigned noSpilLoc:1; /* cannot be assigned a spil location */
+ unsigned isstrlit; /* is a string literal and it's usage count */
unsigned accuse; /* can be left in the accumulator
On the Z80 accuse is devided into
ACCUSE_A and ACCUSE_HL as the idea