New option and #pragma --local-strings that causes string literals to be

output immediately.


git-svn-id: svn://svn.cc65.org/cc65/trunk@4504 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz
2009-12-08 20:35:24 +00:00
parent 2bca737f57
commit 7d94dc50a1
8 changed files with 113 additions and 35 deletions

View File

@@ -410,8 +410,8 @@ void FinishCompile (void)
Func = Func->NextSym;
}
/* Dump the literal pool */
DumpLiteralPool ();
/* Output the literal pool */
OutputLiteralPool ();
/* Write imported/exported symbols */
EmitExternals ();

View File

@@ -51,6 +51,7 @@ unsigned RegisterSpace = 6; /* Space available for register vars */
/* Stackable options */
IntStack WritableStrings = INTSTACK(0); /* Literal strings are r/w */
IntStack LocalStrings = INTSTACK(0); /* Emit string literals immediately */
IntStack InlineStdFuncs = INTSTACK(0); /* Inline some known functions */
IntStack EnableRegVars = INTSTACK(0); /* Enable register variables */
IntStack AllowRegVarAddr = INTSTACK(0); /* Allow taking addresses of register vars */
@@ -62,4 +63,3 @@ IntStack Optimize = INTSTACK(0); /* Optimize flag */
IntStack CodeSizeFactor = INTSTACK(100);/* Size factor for generated code */

View File

@@ -58,6 +58,7 @@ extern unsigned RegisterSpace; /* Space available for register
/* Stackable options */
extern IntStack WritableStrings; /* Literal strings are r/w */
extern IntStack LocalStrings; /* Emit string literals immediately */
extern IntStack InlineStdFuncs; /* Inline some known functions */
extern IntStack EnableRegVars; /* Enable register variables */
extern IntStack AllowRegVarAddr; /* Allow taking addresses of register vars */

View File

@@ -62,6 +62,7 @@
struct Literal {
unsigned Label; /* Asm label for this literal */
int RefCount; /* Reference count */
int Output; /* True if output has been generated */
StrBuf Data; /* Literal data */
};
@@ -100,6 +101,7 @@ static Literal* NewLiteral (const void* Buf, unsigned Len)
/* Initialize the fields */
L->Label = GetLocalLabel ();
L->RefCount = 0;
L->Output = 0;
SB_Init (&L->Data);
SB_AppendBuf (&L->Data, Buf, Len);
@@ -121,10 +123,43 @@ static void FreeLiteral (Literal* L)
static void OutputLiteral (Literal* L)
/* Output one literal to the currently active data segment */
{
/* Translate the literal into the target charset */
TranslateLiteral (L);
/* Define the label for the literal */
g_defdatalabel (L->Label);
/* Output the literal data */
g_defbytes (SB_GetConstBuf (&L->Data), SB_GetLen (&L->Data));
/* Mark the literal as output */
L->Output = 1;
}
Literal* UseLiteral (Literal* L)
/* Increase the reference counter for the literal and return it */
{
/* Increase the reference count */
++L->RefCount;
/* If --local-strings was given, immediately output the literal */
if (IS_Get (&LocalStrings)) {
/* Switch to the proper data segment */
if (IS_Get (&WritableStrings)) {
g_usedata ();
} else {
g_userodata ();
}
/* Output the literal */
OutputLiteral (L);
}
/* Return the literal */
return L;
}
@@ -133,7 +168,8 @@ Literal* UseLiteral (Literal* L)
void ReleaseLiteral (Literal* L)
/* Decrement the reference counter for the literal */
{
CHECK (--L->RefCount >= 0);
--L->RefCount;
CHECK (L->RefCount >= 0 && (L->RefCount > 0 || !L->Output));
}
@@ -276,8 +312,10 @@ static void MoveLiterals (Collection* Source, Collection* Target)
/* Get the literal */
Literal* L = CollAt (Source, I);
/* If it is referenced, add it to the Target pool, otherwise free it */
if (L->RefCount) {
/* If it is referenced and not output, add it to the Target pool,
* otherwise free it
*/
if (L->RefCount && !L->Output) {
CollAppend (Target, L);
} else {
FreeLiteral (L);
@@ -302,8 +340,8 @@ void MoveLiteralPool (LiteralPool* LocalPool)
static void DumpWritableLiterals (Collection* Literals)
/* Dump the given writable literals */
static void OutputWritableLiterals (Collection* Literals)
/* Output the given writable literals */
{
unsigned I;
@@ -318,30 +356,21 @@ static void DumpWritableLiterals (Collection* Literals)
/* Emit all literals that have a reference */
for (I = 0; I < CollCount (Literals); ++I) {
/* Get the next literal */
Literal* L = CollAt (Literals, I);
/* Get a pointer to the literal */
Literal* L = CollAtUnchecked (Literals, I);
/* Ignore it, if it doesn't have references */
if (L->RefCount == 0) {
continue;
/* Output this one, if it has references and wasn't already output */
if (L->RefCount > 0 && !L->Output) {
OutputLiteral (L);
}
/* Translate the literal into the target charset */
TranslateLiteral (L);
/* Define the label for the literal */
g_defdatalabel (L->Label);
/* Output the literal data */
g_defbytes (SB_GetConstBuf (&L->Data), SB_GetLen (&L->Data));
}
}
static void DumpReadOnlyLiterals (Collection* Literals)
/* Dump the given readonly literals merging (even partial) duplicates */
static void OutputReadOnlyLiterals (Collection* Literals)
/* Output the given readonly literals merging (even partial) duplicates */
{
unsigned I;
@@ -365,8 +394,8 @@ static void DumpReadOnlyLiterals (Collection* Literals)
/* Get the next literal */
Literal* L = CollAt (Literals, I);
/* Ignore it, if it doesn't have references */
if (L->RefCount == 0) {
/* Ignore it, if it doesn't have references or was already output */
if (L->RefCount == 0 || L->Output) {
continue;
}
@@ -408,7 +437,6 @@ static void DumpReadOnlyLiterals (Collection* Literals)
/* This literal is part of a longer literal, merge them */
g_aliasdatalabel (L->Label, C->Label, GetLiteralSize (C) - GetLiteralSize (L));
} else {
/* Define the label for the literal */
@@ -418,17 +446,20 @@ static void DumpReadOnlyLiterals (Collection* Literals)
g_defbytes (SB_GetConstBuf (&L->Data), SB_GetLen (&L->Data));
}
/* Mark the literal */
L->Output = 1;
}
}
void DumpLiteralPool (void)
/* Dump the global literal pool */
void OutputLiteralPool (void)
/* Output the global literal pool */
{
/* Dump both sorts of literals */
DumpWritableLiterals (&GlobalPool->WritableLiterals);
DumpReadOnlyLiterals (&GlobalPool->ReadOnlyLiterals);
/* Output both sorts of literals */
OutputWritableLiterals (&GlobalPool->WritableLiterals);
OutputReadOnlyLiterals (&GlobalPool->ReadOnlyLiterals);
}

View File

@@ -113,8 +113,8 @@ void MoveLiteralPool (LiteralPool* LocalPool);
* function will free LocalPool after moving the used string literals.
*/
void DumpLiteralPool (void);
/* Dump the literal pool */
void OutputLiteralPool (void);
/* Output the literal pool */
Literal* AddLiteral (const char* S);
/* Add a literal string to the literal pool. Return the literal. */

View File

@@ -121,7 +121,8 @@ static void Usage (void)
" --help\t\tHelp (this text)\n"
" --include-dir dir\tSet an include directory search path\n"
" --list-opt-steps\tList all optimizer steps and exit\n"
" --memory-model model\tSet the memory model\n"
" --local-strings\tEmit string literals immediately\n"
" --memory-model model\tSet the memory model\n"
" --register-space b\tSet space available for register variables\n"
" --register-vars\tEnable register variables\n"
" --rodata-name seg\tSet the name of the RODATA segment\n"
@@ -556,6 +557,15 @@ static void OptListOptSteps (const char* Opt attribute ((unused)),
static void OptLocalStrings (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Emit string literals immediately */
{
IS_Set (&LocalStrings, 1);
}
static void OptMemoryModel (const char* Opt, const char* Arg)
/* Set the memory model */
{
@@ -751,6 +761,7 @@ int main (int argc, char* argv[])
{ "--help", 0, OptHelp },
{ "--include-dir", 1, OptIncludeDir },
{ "--list-opt-steps", 0, OptListOptSteps },
{ "--local-strings", 0, OptLocalStrings },
{ "--memory-model", 1, OptMemoryModel },
{ "--register-space", 1, OptRegisterSpace },
{ "--register-vars", 0, OptRegisterVars },

View File

@@ -73,6 +73,7 @@ typedef enum {
PRAGMA_CODESIZE,
PRAGMA_DATA_NAME,
PRAGMA_DATASEG, /* obsolete */
PRAGMA_LOCAL_STRINGS,
PRAGMA_OPTIMIZE,
PRAGMA_REGVARADDR,
PRAGMA_REGISTER_VARS,
@@ -104,6 +105,7 @@ static const struct Pragma {
{ "codesize", PRAGMA_CODESIZE },
{ "data-name", PRAGMA_DATA_NAME },
{ "dataseg", PRAGMA_DATASEG }, /* obsolete */
{ "local-strings", PRAGMA_LOCAL_STRINGS },
{ "optimize", PRAGMA_OPTIMIZE },
{ "register-vars", PRAGMA_REGISTER_VARS },
{ "regvaraddr", PRAGMA_REGVARADDR },
@@ -727,6 +729,10 @@ static void ParsePragma (void)
SegNamePragma (&B, SEG_DATA);
break;
case PRAGMA_LOCAL_STRINGS:
FlagPragma (&B, &LocalStrings);
break;
case PRAGMA_OPTIMIZE:
FlagPragma (&B, &Optimize);
break;