From d8279302a947f26f248929eac552c7ed0c465cee Mon Sep 17 00:00:00 2001 From: cuz Date: Tue, 15 Jun 2004 20:29:49 +0000 Subject: [PATCH] Make the -O and --codesize options stackable. Copy the current optimization settings into a code segment on creation. git-svn-id: svn://svn.cc65.org/cc65/trunk@3129 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/codegen.c | 32 ++++++++++++++++---------------- src/cc65/codeopt.c | 6 +++--- src/cc65/codeseg.c | 7 ++++++- src/cc65/codeseg.h | 8 ++++++-- src/cc65/compile.c | 7 ++++--- src/cc65/expr.c | 2 +- src/cc65/global.c | 5 ++--- src/cc65/global.h | 7 +++---- src/cc65/main.c | 14 ++++++++------ src/cc65/stdfunc.c | 4 ++-- 10 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 88cebe9a4..14297e928 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -511,7 +511,7 @@ void g_swap_regvars (int StackOffs, int RegOffs, unsigned Bytes) /* Generate code */ if (Bytes == 1) { - if (CodeSizeFactor < 165) { + if (IS_Get (&CodeSizeFactor) < 165) { ldyconst (StackOffs); ldxconst (RegOffs); AddCodeLine ("jsr regswap1"); @@ -601,7 +601,7 @@ void g_restore_regvars (int StackOffs, int RegOffs, unsigned Bytes) AddCodeLine ("lda (sp),y"); AddCodeLine ("sta regbank%+d", RegOffs+1); - } else if (Bytes == 3 && CodeSizeFactor >= 133) { + } else if (Bytes == 3 && IS_Get (&CodeSizeFactor) >= 133) { ldyconst (StackOffs); AddCodeLine ("lda (sp),y"); @@ -915,7 +915,7 @@ void g_leasp (int offs) AddCodeLine ("lda sp"); AddCodeLine ("ldx sp+1"); } else { - if (CodeSizeFactor < 300) { + if (IS_Get (&CodeSizeFactor) < 300) { ldaconst (offs); /* Load A with offset value */ AddCodeLine ("jsr leaasp"); /* Load effective address */ } else { @@ -963,7 +963,7 @@ void g_leavariadic (int Offs) AddCodeLine ("lda (sp),y"); /* Add the value of the stackpointer */ - if (CodeSizeFactor > 250) { + if (IS_Get (&CodeSizeFactor) > 250) { unsigned L = GetLocalLabel(); AddCodeLine ("ldx sp+1"); AddCodeLine ("clc"); @@ -1060,7 +1060,7 @@ void g_putlocal (unsigned Flags, int Offs, long Val) } AddCodeLine ("sta (sp),y"); } else { - if ((Flags & CF_NOKEEP) == 0 || CodeSizeFactor < 160) { + if ((Flags & CF_NOKEEP) == 0 || IS_Get (&CodeSizeFactor) < 160) { ldyconst (Offs); AddCodeLine ("jsr staxysp"); } else { @@ -1258,7 +1258,7 @@ void g_reglong (unsigned Flags) if (Flags & CF_FORCECHAR) { /* Conversion is from char */ if (Flags & CF_UNSIGNED) { - if (CodeSizeFactor >= 200) { + if (IS_Get (&CodeSizeFactor) >= 200) { AddCodeLine ("ldx #$00"); AddCodeLine ("stx sreg"); AddCodeLine ("stx sreg+1"); @@ -1266,7 +1266,7 @@ void g_reglong (unsigned Flags) AddCodeLine ("jsr aulong"); } } else { - if (CodeSizeFactor >= 366) { + if (IS_Get (&CodeSizeFactor) >= 366) { L = GetLocalLabel(); AddCodeLine ("ldx #$00"); AddCodeLine ("cmp #$80"); @@ -1284,7 +1284,7 @@ void g_reglong (unsigned Flags) case CF_INT: if (Flags & CF_UNSIGNED) { - if (CodeSizeFactor >= 200) { + if (IS_Get (&CodeSizeFactor) >= 200) { ldyconst (0); AddCodeLine ("sty sreg"); AddCodeLine ("sty sreg+1"); @@ -1425,7 +1425,7 @@ void g_scale (unsigned flags, long val) /* FALLTHROUGH */ case CF_INT: - if (CodeSizeFactor >= (p2+1)*130U) { + if (IS_Get (&CodeSizeFactor) >= (p2+1)*130) { AddCodeLine ("stx tmp1"); while (p2--) { AddCodeLine ("asl a"); @@ -1487,7 +1487,7 @@ void g_scale (unsigned flags, long val) case CF_INT: if (flags & CF_UNSIGNED) { - if (CodeSizeFactor >= (p2+1)*130U) { + if (IS_Get (&CodeSizeFactor) >= (p2+1)*130) { AddCodeLine ("stx tmp1"); while (p2--) { AddCodeLine ("lsr tmp1"); @@ -1498,7 +1498,7 @@ void g_scale (unsigned flags, long val) AddCodeLine ("jsr lsrax%d", p2); } } else { - if (CodeSizeFactor >= (p2+1)*150U) { + if (IS_Get (&CodeSizeFactor) >= (p2+1)*150) { AddCodeLine ("stx tmp1"); while (p2--) { AddCodeLine ("cpx #$80"); @@ -1788,7 +1788,7 @@ void g_addeqlocal (unsigned flags, int offs, unsigned long val) case CF_INT: ldyconst (offs); if (flags & CF_CONST) { - if (CodeSizeFactor >= 400) { + if (IS_Get (&CodeSizeFactor) >= 400) { AddCodeLine ("clc"); AddCodeLine ("lda #$%02X", (int)(val & 0xFF)); AddCodeLine ("adc (sp),y"); @@ -1848,7 +1848,7 @@ void g_addeqind (unsigned flags, unsigned offs, unsigned long val) break; case CF_INT: - if (CodeSizeFactor >= 200) { + if (IS_Get (&CodeSizeFactor) >= 200) { /* Lots of code, use only if size is not important */ AddCodeLine ("sta ptr1"); AddCodeLine ("stx ptr1+1"); @@ -2062,7 +2062,7 @@ void g_subeqind (unsigned flags, unsigned offs, unsigned long val) break; case CF_INT: - if (CodeSizeFactor >= 200) { + if (IS_Get (&CodeSizeFactor) >= 200) { /* Lots of code, use only if size is not important */ AddCodeLine ("sta ptr1"); AddCodeLine ("stx ptr1+1"); @@ -3272,7 +3272,7 @@ void g_inc (unsigned flags, unsigned long val) AddCodeLine ("bne %s", LocalLabelName (L)); AddCodeLine ("inx"); g_defcodelabel (L); - } else if (CodeSizeFactor < 200) { + } else if (IS_Get (&CodeSizeFactor) < 200) { /* Use jsr calls */ if (val <= 8) { AddCodeLine ("jsr incax%lu", val); @@ -3360,7 +3360,7 @@ void g_dec (unsigned flags, unsigned long val) /* FALLTHROUGH */ case CF_INT: - if (CodeSizeFactor < 200) { + if (IS_Get (&CodeSizeFactor) < 200) { /* Use subroutines */ if (val <= 8) { AddCodeLine ("jsr decax%d", (int) val); diff --git a/src/cc65/codeopt.c b/src/cc65/codeopt.c index 7d1109a6f..fefd001f2 100644 --- a/src/cc65/codeopt.c +++ b/src/cc65/codeopt.c @@ -1908,7 +1908,7 @@ static unsigned RunOptFunc (CodeSeg* S, OptFunc* F, unsigned Max) /* Don't run the function if it is disabled or if it is prohibited by the * code size factor */ - if (F->Disabled || F->CodeSizeFactor > CodeSizeFactor) { + if (F->Disabled || F->CodeSizeFactor > S->CodeSizeFactor) { return 0; } @@ -2093,7 +2093,7 @@ static unsigned RunOptGroup6 (CodeSeg* S) unsigned Changes = 0; unsigned C; - if (CodeSizeFactor <= 100) { + if (S->CodeSizeFactor <= 100) { /* Optimize for size, that is replace operations by shorter ones, even * if this does hinder further optimizations (no problem since we're * done soon). @@ -2142,7 +2142,7 @@ void RunOpt (CodeSeg* S) const char* StatFileName; /* If we shouldn't run the optimizer, bail out */ - if (!Optimize) { + if (!S->Optimize) { return; } diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 1126e08ee..c27f44b3d 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -50,11 +50,12 @@ #include "asmlabel.h" #include "codeent.h" #include "codeinfo.h" +#include "codeseg.h" #include "datatype.h" #include "error.h" +#include "global.h" #include "ident.h" #include "symentry.h" -#include "codeseg.h" @@ -471,6 +472,10 @@ CodeSeg* NewCodeSeg (const char* SegName, SymEntry* Func) S->ExitRegs = REG_NONE; } + /* Copy the global optimization settings */ + S->Optimize = (unsigned char) IS_Get (&Optimize); + S->CodeSizeFactor = (unsigned) IS_Get (&CodeSizeFactor); + /* Return the new struct */ return S; } diff --git a/src/cc65/codeseg.h b/src/cc65/codeseg.h index cde8c4ff1..100bb2604 100644 --- a/src/cc65/codeseg.h +++ b/src/cc65/codeseg.h @@ -79,8 +79,12 @@ struct CodeSeg { SymEntry* Func; /* Owner function */ Collection Entries; /* List of code entries */ Collection Labels; /* Labels for next insn */ - CodeLabel* LabelHash [CS_LABEL_HASH_SIZE]; /* Label hash table */ + CodeLabel* LabelHash[CS_LABEL_HASH_SIZE]; /* Label hash table */ unsigned short ExitRegs; /* Register use on exit */ + + /* Optimization settings for this segment */ + unsigned char Optimize; /* On/off switch */ + unsigned CodeSizeFactor; }; @@ -287,7 +291,7 @@ void CS_GenRegInfo (CodeSeg* S); /* End of codeseg.h */ -#endif +#endif diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 7edd3ae17..1870b9a1c 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -295,10 +295,11 @@ void Compile (const char* FileName) * IS_Get functions access the values in effect now, regardless of any * changes using #pragma later. */ - if (Optimize) { + if (IS_Get (&Optimize)) { + long CodeSize = IS_Get (&CodeSizeFactor); DefineNumericMacro ("__OPT__", 1); - if (FavourSize == 0) { - DefineNumericMacro ("__OPT_i__", 1); + if (CodeSize > 100) { + DefineNumericMacro ("__OPT_i__", CodeSize); } if (IS_Get (&EnableRegVars)) { DefineNumericMacro ("__OPT_r__", 1); diff --git a/src/cc65/expr.c b/src/cc65/expr.c index e7c695799..6cff40326 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -367,7 +367,7 @@ static unsigned FunctionParamList (FuncDesc* Func) * (instead of pushing) is enabled. * */ - if (CodeSizeFactor >= 200) { + if (IS_Get (&CodeSizeFactor) >= 200) { /* Calculate the number and size of the parameters */ FrameParams = Func->ParamCount; diff --git a/src/cc65/global.c b/src/cc65/global.c index 2e862a894..610b80c8b 100644 --- a/src/cc65/global.c +++ b/src/cc65/global.c @@ -48,10 +48,7 @@ unsigned char DebugInfo = 0; /* Add debug info to the obj */ unsigned char CreateDep = 0; /* Create a dependency file */ unsigned char ANSI = 0; /* Strict ANSI flag */ unsigned char NoWarn = 0; /* Suppress warnings */ -unsigned char Optimize = 0; /* Optimize flag */ unsigned long OptDisable = 0; /* Optimizer passes to disable */ -unsigned char FavourSize = 1; /* Favour size over speed */ -unsigned CodeSizeFactor = 100; /* Size factor for generated code */ unsigned RegisterSpace = 6; /* Space available for register vars */ /* Stackable options */ @@ -63,6 +60,8 @@ IntStack RegVarsToCallStack = INTSTACK(0); /* Save reg variables on call stack IntStack StaticLocals = INTSTACK(0); /* Make local variables static */ IntStack SignedChars = INTSTACK(0); /* Make characters signed by default */ IntStack CheckStack = INTSTACK(0); /* Generate stack overflow checks */ +IntStack Optimize = INTSTACK(0); /* Optimize flag */ +IntStack CodeSizeFactor = INTSTACK(100);/* Size factor for generated code */ diff --git a/src/cc65/global.h b/src/cc65/global.h index 93032dae8..11ff82b3c 100644 --- a/src/cc65/global.h +++ b/src/cc65/global.h @@ -48,16 +48,13 @@ /*****************************************************************************/ - + extern unsigned char AddSource; /* Add source lines as comments */ extern unsigned char DebugInfo; /* Add debug info to the obj */ extern unsigned char CreateDep; /* Create a dependency file */ extern unsigned char ANSI; /* Strict ANSI flag */ extern unsigned char NoWarn; /* Suppress warnings */ -extern unsigned char Optimize; /* Optimize flag */ extern unsigned long OptDisable; /* Optimizer passes to disable */ -extern unsigned char FavourSize; /* Favour size over speed */ -extern unsigned CodeSizeFactor; /* Size factor for generated code */ extern unsigned RegisterSpace; /* Space available for register vars */ /* Stackable options */ @@ -69,6 +66,8 @@ extern IntStack RegVarsToCallStack; /* Save reg variables on call stack extern IntStack StaticLocals; /* Make local variables static */ extern IntStack SignedChars; /* Make characters signed by default */ extern IntStack CheckStack; /* Generate stack overflow checks */ +extern IntStack Optimize; /* Optimize flag */ +extern IntStack CodeSizeFactor; /* Size factor for generated code */ diff --git a/src/cc65/main.c b/src/cc65/main.c index bb8864698..c272902dd 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -374,12 +374,15 @@ static void OptCodeName (const char* Opt attribute ((unused)), const char* Arg) static void OptCodeSize (const char* Opt, const char* Arg) /* Handle the --codesize option */ { + unsigned Factor; + char BoundsCheck; + /* Numeric argument expected */ - if (sscanf (Arg, "%u", &CodeSizeFactor) != 1 || - CodeSizeFactor < 100 || - CodeSizeFactor > 1000) { + if (sscanf (Arg, "%u%c", &Factor, &BoundsCheck) != 1 || + Factor < 10 || Factor > 1000) { AbEnd ("Argument for %s is invalid", Opt); } + IS_Set (&CodeSizeFactor, Factor); } @@ -801,7 +804,7 @@ int main (int argc, char* argv[]) break; case 'O': - Optimize = 1; + IS_Set (&Optimize, 1); P = Arg + 2; while (*P) { switch (*P++) { @@ -809,8 +812,7 @@ int main (int argc, char* argv[]) sscanf (P, "%lx", (long*) &OptDisable); break; case 'i': - FavourSize = 0; - CodeSizeFactor = 200; + IS_Set (&CodeSizeFactor, 200); break; case 'r': IS_Set (&EnableRegVars, 1); diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 410d36e5c..74b9b8c2a 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -638,7 +638,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && ED_IsConstAbsInt (&Arg2.Expr) && - (Arg2.Expr.IVal != 0 || CodeSizeFactor > 200)) { + (Arg2.Expr.IVal != 0 || IS_Get (&CodeSizeFactor) > 200)) { /* Remove all of the generated code but the load of the first * argument. @@ -1015,7 +1015,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) * requested on the command line, and the code size factor is more than * 400 (code is 13 bytes vs. 3 for a jsr call). */ - } else if (CodeSizeFactor > 400 && IS_Get (&InlineStdFuncs)) { + } else if (IS_Get (&CodeSizeFactor) > 400 && IS_Get (&InlineStdFuncs)) { /* Load the expression into the primary */ LoadExpr (CF_NONE, &Arg);