1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-23 19:29:37 +00:00

Allow enabling/disabline optimizer steps by file

git-svn-id: svn://svn.cc65.org/cc65/trunk@831 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-07-29 20:38:15 +00:00
parent 750cf445f7
commit d341565ddc
3 changed files with 200 additions and 80 deletions

View File

@ -1662,67 +1662,78 @@ static unsigned OptPtrLoad2 (CodeSeg* S)
/* Types of optimization steps */
enum {
optPre, /* Repeated once */
optPreMain, /* Repeated more than once */
optMain, /* dito */
optPostMain, /* dito */
optPost /* Repeated once */
};
/* Table with all the optimization functions */ /* Table with all the optimization functions */
typedef struct OptFunc OptFunc; typedef struct OptFunc OptFunc;
struct OptFunc { struct OptFunc {
unsigned (*Func) (CodeSeg*);/* Optimizer function */ unsigned (*Func) (CodeSeg*); /* Optimizer function */
const char* Name; /* Name of optimizer step */ const char* Name; /* Name of optimizer step */
char Disabled; /* True if pass disabled */ unsigned char Type; /* Type of this step */
char Disabled; /* True if pass disabled */
}; };
/* Macro that builds a table entry */
#define OptEntry(func,type) { func, #func, type, 0 }
/* Table with optimizer steps */
/* Table with optimizer steps - are called in this order */
static OptFunc OptFuncs [] = { static OptFunc OptFuncs [] = {
/* Optimizes stores through pointers */ /* Optimizes stores through pointers */
{ OptPtrStore1, "OptPtrStore1", 0 }, OptEntry (OptPtrStore1, optPre),
/* Optimize loads through pointers */ /* Optimize loads through pointers */
{ OptPtrLoad1, "OptPtrLoad1", 0 }, OptEntry (OptPtrLoad1, optMain),
{ OptPtrLoad2, "OptPtrLoad2", 0 }, OptEntry (OptPtrLoad2, optMain),
/* Optimize subtractions */
{ OptSub1, "OptSub1", 0 },
{ OptSub2, "OptSub2", 0 },
/* Optimize additions */
{ OptAdd1, "OptAdd1", 0 },
/* Optimize jump cascades */
{ OptJumpCascades, "OptJumpCascades", 0 },
/* Remove dead jumps */
{ OptDeadJumps, "OptDeadJumps", 0 },
/* Change jsr/rts to jmp */
{ OptRTS, "OptRTS", 0 },
/* Remove dead code */
{ OptDeadCode, "OptDeadCode", 0 },
/* Optimize jump targets */
{ OptJumpTarget, "OptJumpTarget", 0 },
/* Optimize conditional branches */
{ OptCondBranches, "OptCondBranches", 0 },
/* Replace jumps to RTS by RTS */
{ OptRTSJumps, "OptRTSJumps", 0 },
/* Remove calls to the bool transformer subroutines */
{ OptBoolTransforms, "OptBoolTransforms", 0 },
/* Optimize calls to nega */ /* Optimize calls to nega */
{ OptNegA1, "OptNegA1", 0 }, OptEntry (OptNegA1, optPre),
{ OptNegA2, "OptNegA2", 0 }, OptEntry (OptNegA2, optPre),
/* Optimize calls to negax */ /* Optimize calls to negax */
{ OptNegAX1, "OptNegAX1", 0 }, OptEntry (OptNegAX1, optPre),
{ OptNegAX2, "OptNegAX2", 0 }, OptEntry (OptNegAX2, optPre),
{ OptNegAX3, "OptNegAX3", 0 }, OptEntry (OptNegAX3, optPre),
{ OptNegAX4, "OptNegAX4", 0 }, OptEntry (OptNegAX4, optPre),
/* Optimize subtractions */
OptEntry (OptSub1, optMain),
OptEntry (OptSub2, optMain),
/* Optimize additions */
OptEntry (OptAdd1, optMain),
/* Optimize jump cascades */
OptEntry (OptJumpCascades, optMain),
/* Remove dead jumps */
OptEntry (OptDeadJumps, optMain),
/* Change jsr/rts to jmp */
OptEntry (OptRTS, optMain),
/* Remove dead code */
OptEntry (OptDeadCode, optMain),
/* Optimize jump targets */
OptEntry (OptJumpTarget, optMain),
/* Optimize conditional branches */
OptEntry (OptCondBranches, optMain),
/* Replace jumps to RTS by RTS */
OptEntry (OptRTSJumps, optMain),
/* Remove calls to the bool transformer subroutines */
OptEntry (OptBoolTransforms, optMain),
/* Optimize compares */ /* Optimize compares */
{ OptCmp1, "OptCmp1", 0 }, OptEntry (OptCmp1, optMain),
{ OptCmp2, "OptCmp2", 0 }, OptEntry (OptCmp2, optMain),
{ OptCmp3, "OptCmp3", 0 }, OptEntry (OptCmp3, optMain),
{ OptCmp4, "OptCmp4", 0 }, OptEntry (OptCmp4, optMain),
{ OptCmp5, "OptCmp5", 0 }, OptEntry (OptCmp5, optMain),
{ OptCmp6, "OptCmp6", 0 }, OptEntry (OptCmp6, optMain),
/* Optimize tests */ /* Optimize tests */
{ OptTest1, "OptTest1", 0 }, OptEntry (OptTest1, optMain),
/* Remove unused loads */ /* Remove unused loads */
{ OptUnusedLoads, "OptUnusedLoads", 0 }, OptEntry (OptUnusedLoads, optMain),
{ OptDuplicateLoads, "OptDuplicateLoads", 0 }, OptEntry (OptDuplicateLoads, optMain),
{ OptStoreLoad, "OptStoreLoad", 0 }, OptEntry (OptStoreLoad, optMain),
/* Optimize branch distance */ /* Optimize branch distance */
{ OptBranchDist, "OptBranchDist", 0 }, OptEntry (OptBranchDist, optMain),
}; };
@ -1756,7 +1767,7 @@ void DisableOpt (const char* Name)
unsigned I; unsigned I;
for (I = 0; I < sizeof(OptFuncs)/sizeof(OptFuncs[0]); ++I) { for (I = 0; I < sizeof(OptFuncs)/sizeof(OptFuncs[0]); ++I) {
OptFuncs[I].Disabled = 1; OptFuncs[I].Disabled = 1;
} }
} else { } else {
OptFunc* F = FindOptStep (Name); OptFunc* F = FindOptStep (Name);
F->Disabled = 1; F->Disabled = 1;
@ -1781,13 +1792,66 @@ void EnableOpt (const char* Name)
void RunOpt (CodeSeg* S) void ListOptSteps (FILE* F)
/* Run the optimizer */ /* List all optimization steps */
{
unsigned I;
for (I = 0; I < sizeof(OptFuncs)/sizeof(OptFuncs[0]); ++I) {
fprintf (F, "%s\n", OptFuncs[I].Name);
}
}
static void RepeatOptStep (CodeSeg* S, unsigned char Type, unsigned Max)
/* Repeat the optimizer step of type Type at may Max times */
{ {
unsigned I; unsigned I;
unsigned Pass = 0; unsigned Pass = 0;
unsigned OptChanges; unsigned OptChanges;
/* Repeat max times of until there are no more changes */
do {
/* Reset the number of changes */
OptChanges = 0;
/* Keep the user hapy */
Print (stdout, 1, " Optimizer pass %u:\n", ++Pass);
/* Run all optimization steps */
for (I = 0; I < sizeof(OptFuncs)/sizeof(OptFuncs[0]); ++I) {
/* Get the table entry */
const OptFunc* F = OptFuncs + I;
/* Check if the type matches */
if (F->Type != Type) {
/* Skip it */
continue;
}
/* Print the name of the following optimizer step */
Print (stdout, 1, " %s:%*s", F->Name, (int) (30-strlen(F->Name)), "");
/* Check if the step is disabled */
if (F->Disabled) {
Print (stdout, 1, "Disabled\n");
} else {
unsigned Changes = F->Func (S);
OptChanges += Changes;
Print (stdout, 1, "%u Changes\n", Changes);
}
}
} while (--Max > 0 && OptChanges > 0);
}
void RunOpt (CodeSeg* S)
/* Run the optimizer */
{
/* If we shouldn't run the optimizer, bail out */ /* If we shouldn't run the optimizer, bail out */
if (!Optimize) { if (!Optimize) {
return; return;
@ -1801,31 +1865,11 @@ void RunOpt (CodeSeg* S)
} }
/* Repeat all steps until there are no more changes */ /* Repeat all steps until there are no more changes */
do { RepeatOptStep (S, optPre, 1);
/* Reset the number of changes */ RepeatOptStep (S, optPreMain, 0xFFFF);
OptChanges = 0; RepeatOptStep (S, optMain, 0xFFFF);
RepeatOptStep (S, optPostMain, 0xFFFF);
/* Keep the user hapy */ RepeatOptStep (S, optPost, 1);
Print (stdout, 1, " Optimizer pass %u:\n", ++Pass);
/* Run all optimization steps */
for (I = 0; I < sizeof(OptFuncs)/sizeof(OptFuncs[0]); ++I) {
/* Print the name of the following optimizer step */
Print (stdout, 1, " %s:%*s", OptFuncs[I].Name,
(int) (30-strlen(OptFuncs[I].Name)), "");
/* Check if the step is disabled */
if (OptFuncs[I].Disabled) {
Print (stdout, 1, "Disabled\n");
} else {
unsigned Changes = OptFuncs[I].Func (S);
OptChanges += Changes;
Print (stdout, 1, "%u Changes\n", Changes);
}
}
} while (OptChanges > 0);
} }

View File

@ -43,12 +43,6 @@
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
@ -61,6 +55,9 @@ void DisableOpt (const char* Name);
void EnableOpt (const char* Name); void EnableOpt (const char* Name);
/* Enable the optimization with the given name */ /* Enable the optimization with the given name */
void ListOptSteps (FILE* F);
/* List all optimization steps */
void RunOpt (CodeSeg* S); void RunOpt (CodeSeg* S);
/* Run the optimizer */ /* Run the optimizer */

View File

@ -104,10 +104,12 @@ static void Usage (void)
" --data-name seg\tSet the name of the DATA segment\n" " --data-name seg\tSet the name of the DATA segment\n"
" --debug\t\tDebug mode\n" " --debug\t\tDebug mode\n"
" --debug-info\t\tAdd debug info to object file\n" " --debug-info\t\tAdd debug info to object file\n"
" --debug-opt name\tDebug optimization steps\n"
" --disable-opt name\tDisable an optimization step\n" " --disable-opt name\tDisable an optimization step\n"
" --enable-opt name\tEnable an optimization step\n" " --enable-opt name\tEnable an optimization step\n"
" --help\t\tHelp (this text)\n" " --help\t\tHelp (this text)\n"
" --include-dir dir\tSet an include directory search path\n" " --include-dir dir\tSet an include directory search path\n"
" --list-opt-steps\tList all optimizer steps\n"
" --rodata-name seg\tSet the name of the RODATA segment\n" " --rodata-name seg\tSet the name of the RODATA segment\n"
" --signed-chars\tDefault characters are signed\n" " --signed-chars\tDefault characters are signed\n"
" --static-locals\tMake local variables static\n" " --static-locals\tMake local variables static\n"
@ -380,6 +382,73 @@ static void OptDebugInfo (const char* Opt, const char* Arg)
static void OptDebugOpt (const char* Opt, const char* Arg)
/* Debug optimization steps */
{
char Buf [128];
char* Line;
/* Open the file */
FILE* F = fopen (Arg, "r");
if (F == 0) {
AbEnd ("Cannot open `%s': %s", Arg, strerror (errno));
}
/* Read line by line, ignore empty lines and switch optimization
* steps on/off.
*/
while (fgets (Buf, sizeof (Buf), F) != 0) {
/* Remove trailing control chars. This will also remove the
* trailing newline.
*/
unsigned Len = strlen (Buf);
while (Len > 0 && IsControl (Buf[Len-1])) {
--Len;
}
Buf[Len] = '\0';
/* Get a pointer to the buffer and remove leading white space */
Line = Buf;
while (IsBlank (*Line)) {
++Line;
}
/* Check the first character and enable/disable the step or
* ignore the line
*/
switch (*Line) {
case '\0':
case '#':
case ';':
/* Empty or comment line */
continue;
case '-':
DisableOpt (Line+1);
break;
case '+':
++Line;
/* FALLTHROUGH */
default:
EnableOpt (Line);
break;
}
}
/* Close the file, no error check here since we were just reading and
* this is only a debug function.
*/
(void) fclose (F);
}
static void OptDisableOpt (const char* Opt, const char* Arg) static void OptDisableOpt (const char* Opt, const char* Arg)
/* Disable an optimization step */ /* Disable an optimization step */
{ {
@ -413,6 +482,14 @@ static void OptIncludeDir (const char* Opt, const char* Arg)
static void OptListOptSteps (const char* Opt, const char* Arg)
/* List all optimizer steps */
{
ListOptSteps (stdout);
}
static void OptRodataName (const char* Opt, const char* Arg) static void OptRodataName (const char* Opt, const char* Arg)
/* Handle the --rodata-name option */ /* Handle the --rodata-name option */
{ {
@ -482,10 +559,12 @@ int main (int argc, char* argv[])
{ "--data-name", 1, OptDataName }, { "--data-name", 1, OptDataName },
{ "--debug", 0, OptDebug }, { "--debug", 0, OptDebug },
{ "--debug-info", 0, OptDebugInfo }, { "--debug-info", 0, OptDebugInfo },
{ "--debug-opt", 1, OptDebugOpt },
{ "--disable-opt", 1, OptDisableOpt }, { "--disable-opt", 1, OptDisableOpt },
{ "--enable-opt", 1, OptEnableOpt, }, { "--enable-opt", 1, OptEnableOpt, },
{ "--help", 0, OptHelp }, { "--help", 0, OptHelp },
{ "--include-dir", 1, OptIncludeDir }, { "--include-dir", 1, OptIncludeDir },
{ "--list-opt-steps", 0, OptListOptSteps },
{ "--rodata-name", 1, OptRodataName }, { "--rodata-name", 1, OptRodataName },
{ "--signed-chars", 0, OptSignedChars }, { "--signed-chars", 0, OptSignedChars },
{ "--static-locals", 0, OptStaticLocals }, { "--static-locals", 0, OptStaticLocals },