So far the built-in inlining of several known standard function was always (!) enabled and the option -Os enabled additional, potentially unsafe inlining of some of those functions.
There were two aspects of this behavior that were considered undesirable: - Although the safe inlining is in general desirable it should only be enabled if asked for it - like any other optimization. - The option name -Os implies that it is a safe option, the potentially unsafe inlining should have a more explicit name. So now: - The option -Os enables the safe inlining. - The new option --eagerly-inline-funcs enables the potentially unsafe inlining (including the safe inlining). Additionally was added: - The option --inline-stdfuncs that does like -Os enable the safe inlining but doesn't enable optimizations. - The pragma inline-stdfuncs that works identical to --inline-stdfuncs. - The pragma allow-eager-inline that enables the potentially unsafe inlining but doesn't include the safe inlining. That means that by itself it only marks code as safe for potentially unsafe inlining but doesn't actually enable any inlining.
This commit is contained in:
@@ -335,17 +335,22 @@ void Compile (const char* FileName)
|
||||
** changes using #pragma later.
|
||||
*/
|
||||
if (IS_Get (&Optimize)) {
|
||||
long CodeSize = IS_Get (&CodeSizeFactor);
|
||||
DefineNumericMacro ("__OPT__", 1);
|
||||
}
|
||||
{
|
||||
long CodeSize = IS_Get (&CodeSizeFactor);
|
||||
if (CodeSize > 100) {
|
||||
DefineNumericMacro ("__OPT_i__", CodeSize);
|
||||
}
|
||||
if (IS_Get (&EnableRegVars)) {
|
||||
DefineNumericMacro ("__OPT_r__", 1);
|
||||
}
|
||||
if (IS_Get (&InlineStdFuncs)) {
|
||||
DefineNumericMacro ("__OPT_s__", 1);
|
||||
}
|
||||
}
|
||||
if (IS_Get (&EnableRegVars)) {
|
||||
DefineNumericMacro ("__OPT_r__", 1);
|
||||
}
|
||||
if (IS_Get (&InlineStdFuncs)) {
|
||||
DefineNumericMacro ("__OPT_s__", 1);
|
||||
}
|
||||
if (IS_Get (&EagerlyInlineFuncs)) {
|
||||
DefineNumericMacro ("__EAGERLY_INLINE_FUNCS__", 1);
|
||||
}
|
||||
|
||||
/* __TIME__ and __DATE__ macros */
|
||||
|
||||
@@ -53,7 +53,8 @@ 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 InlineStdFuncs = INTSTACK(0); /* Inline some standard functions */
|
||||
IntStack EagerlyInlineFuncs = INTSTACK(0); /* Eagerly inline some known functions */
|
||||
IntStack EnableRegVars = INTSTACK(0); /* Enable register variables */
|
||||
IntStack AllowRegVarAddr = INTSTACK(0); /* Allow taking addresses of register vars */
|
||||
IntStack RegVarsToCallStack = INTSTACK(0); /* Save reg variables on call stack */
|
||||
|
||||
@@ -61,7 +61,8 @@ 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 InlineStdFuncs; /* Inline some standard functions */
|
||||
extern IntStack EagerlyInlineFuncs; /* Eagerly inline some known functions */
|
||||
extern IntStack EnableRegVars; /* Enable register variables */
|
||||
extern IntStack AllowRegVarAddr; /* Allow taking addresses of register vars */
|
||||
extern IntStack RegVarsToCallStack; /* Save reg variables on call stack */
|
||||
|
||||
@@ -88,7 +88,7 @@ static void Usage (void)
|
||||
" -O\t\t\t\tOptimize code\n"
|
||||
" -Oi\t\t\t\tOptimize code, inline more code\n"
|
||||
" -Or\t\t\t\tEnable register variables\n"
|
||||
" -Os\t\t\t\tInline some known functions\n"
|
||||
" -Os\t\t\t\tInline some standard functions\n"
|
||||
" -T\t\t\t\tInclude source as comment\n"
|
||||
" -V\t\t\t\tPrint the compiler version number\n"
|
||||
" -W warning[,...]\t\tSuppress warnings\n"
|
||||
@@ -118,9 +118,11 @@ static void Usage (void)
|
||||
" --debug-opt name\t\tDebug optimization steps\n"
|
||||
" --dep-target target\t\tUse this dependency target\n"
|
||||
" --disable-opt name\t\tDisable an optimization step\n"
|
||||
" --eagerly-inline-funcs\t\tEagerly inline some known functions\n"
|
||||
" --enable-opt name\t\tEnable an optimization step\n"
|
||||
" --help\t\t\tHelp (this text)\n"
|
||||
" --include-dir dir\t\tSet an include directory search path\n"
|
||||
" --inline-stdfuncs\t\tInline some standard functions\n"
|
||||
" --list-opt-steps\t\tList all optimizer steps and exit\n"
|
||||
" --list-warnings\t\tList available warning types for -W\n"
|
||||
" --local-strings\t\tEmit string literals immediately\n"
|
||||
@@ -581,6 +583,16 @@ static void OptDisableOpt (const char* Opt attribute ((unused)), const char* Arg
|
||||
|
||||
|
||||
|
||||
static void OptEagerlyInlineFuncs (const char* Opt attribute((unused)),
|
||||
const char* Arg attribute((unused)))
|
||||
/* Eagerly inline some known functions */
|
||||
{
|
||||
IS_Set (&InlineStdFuncs, 1);
|
||||
IS_Set (&EagerlyInlineFuncs, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptEnableOpt (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Enable an optimization step */
|
||||
{
|
||||
@@ -608,6 +620,15 @@ static void OptIncludeDir (const char* Opt attribute ((unused)), const char* Arg
|
||||
|
||||
|
||||
|
||||
static void OptInlineStdFuncs (const char* Opt attribute((unused)),
|
||||
const char* Arg attribute((unused)))
|
||||
/* Inline some standard functions */
|
||||
{
|
||||
IS_Set (&InlineStdFuncs, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptListOptSteps (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* List all optimizer steps */
|
||||
@@ -819,39 +840,41 @@ int main (int argc, char* argv[])
|
||||
{
|
||||
/* Program long options */
|
||||
static const LongOpt OptTab[] = {
|
||||
{ "--add-source", 0, OptAddSource },
|
||||
{ "--all-cdecl", 0, OptAllCDecl },
|
||||
{ "--bss-name", 1, OptBssName },
|
||||
{ "--check-stack", 0, OptCheckStack },
|
||||
{ "--code-name", 1, OptCodeName },
|
||||
{ "--codesize", 1, OptCodeSize },
|
||||
{ "--cpu", 1, OptCPU },
|
||||
{ "--create-dep", 1, OptCreateDep },
|
||||
{ "--create-full-dep", 1, OptCreateFullDep },
|
||||
{ "--data-name", 1, OptDataName },
|
||||
{ "--debug", 0, OptDebug },
|
||||
{ "--debug-info", 0, OptDebugInfo },
|
||||
{ "--debug-opt", 1, OptDebugOpt },
|
||||
{ "--debug-opt-output", 0, OptDebugOptOutput },
|
||||
{ "--dep-target", 1, OptDepTarget },
|
||||
{ "--disable-opt", 1, OptDisableOpt },
|
||||
{ "--enable-opt", 1, OptEnableOpt },
|
||||
{ "--help", 0, OptHelp },
|
||||
{ "--include-dir", 1, OptIncludeDir },
|
||||
{ "--list-opt-steps", 0, OptListOptSteps },
|
||||
{ "--list-warnings", 0, OptListWarnings },
|
||||
{ "--local-strings", 0, OptLocalStrings },
|
||||
{ "--memory-model", 1, OptMemoryModel },
|
||||
{ "--register-space", 1, OptRegisterSpace },
|
||||
{ "--register-vars", 0, OptRegisterVars },
|
||||
{ "--rodata-name", 1, OptRodataName },
|
||||
{ "--signed-chars", 0, OptSignedChars },
|
||||
{ "--standard", 1, OptStandard },
|
||||
{ "--static-locals", 0, OptStaticLocals },
|
||||
{ "--target", 1, OptTarget },
|
||||
{ "--verbose", 0, OptVerbose },
|
||||
{ "--version", 0, OptVersion },
|
||||
{ "--writable-strings", 0, OptWritableStrings },
|
||||
{ "--add-source", 0, OptAddSource },
|
||||
{ "--all-cdecl", 0, OptAllCDecl },
|
||||
{ "--bss-name", 1, OptBssName },
|
||||
{ "--check-stack", 0, OptCheckStack },
|
||||
{ "--code-name", 1, OptCodeName },
|
||||
{ "--codesize", 1, OptCodeSize },
|
||||
{ "--cpu", 1, OptCPU },
|
||||
{ "--create-dep", 1, OptCreateDep },
|
||||
{ "--create-full-dep", 1, OptCreateFullDep },
|
||||
{ "--data-name", 1, OptDataName },
|
||||
{ "--debug", 0, OptDebug },
|
||||
{ "--debug-info", 0, OptDebugInfo },
|
||||
{ "--debug-opt", 1, OptDebugOpt },
|
||||
{ "--debug-opt-output", 0, OptDebugOptOutput },
|
||||
{ "--dep-target", 1, OptDepTarget },
|
||||
{ "--disable-opt", 1, OptDisableOpt },
|
||||
{ "--eagerly-inline-funcs", 0, OptEagerlyInlineFuncs },
|
||||
{ "--enable-opt", 1, OptEnableOpt },
|
||||
{ "--help", 0, OptHelp },
|
||||
{ "--include-dir", 1, OptIncludeDir },
|
||||
{ "--inline-stdfuncs", 0, OptInlineStdFuncs },
|
||||
{ "--list-opt-steps", 0, OptListOptSteps },
|
||||
{ "--list-warnings", 0, OptListWarnings },
|
||||
{ "--local-strings", 0, OptLocalStrings },
|
||||
{ "--memory-model", 1, OptMemoryModel },
|
||||
{ "--register-space", 1, OptRegisterSpace },
|
||||
{ "--register-vars", 0, OptRegisterVars },
|
||||
{ "--rodata-name", 1, OptRodataName },
|
||||
{ "--signed-chars", 0, OptSignedChars },
|
||||
{ "--standard", 1, OptStandard },
|
||||
{ "--static-locals", 0, OptStaticLocals },
|
||||
{ "--target", 1, OptTarget },
|
||||
{ "--verbose", 0, OptVerbose },
|
||||
{ "--version", 0, OptVersion },
|
||||
{ "--writable-strings", 0, OptWritableStrings },
|
||||
};
|
||||
|
||||
unsigned I;
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
typedef enum {
|
||||
PRAGMA_ILLEGAL = -1,
|
||||
PRAGMA_ALIGN,
|
||||
PRAGMA_ALLOW_EAGER_INLINE,
|
||||
PRAGMA_BSS_NAME,
|
||||
PRAGMA_BSSSEG, /* obsolete */
|
||||
PRAGMA_CHARMAP,
|
||||
@@ -74,6 +75,7 @@ typedef enum {
|
||||
PRAGMA_CODESIZE,
|
||||
PRAGMA_DATA_NAME,
|
||||
PRAGMA_DATASEG, /* obsolete */
|
||||
PRAGMA_INLINE_STDFUNCS,
|
||||
PRAGMA_LOCAL_STRINGS,
|
||||
PRAGMA_OPTIMIZE,
|
||||
PRAGMA_REGVARADDR,
|
||||
@@ -96,31 +98,33 @@ static const struct Pragma {
|
||||
const char* Key; /* Keyword */
|
||||
pragma_t Tok; /* Token */
|
||||
} Pragmas[PRAGMA_COUNT] = {
|
||||
{ "align", PRAGMA_ALIGN },
|
||||
{ "bss-name", PRAGMA_BSS_NAME },
|
||||
{ "bssseg", PRAGMA_BSSSEG }, /* obsolete */
|
||||
{ "charmap", PRAGMA_CHARMAP },
|
||||
{ "check-stack", PRAGMA_CHECK_STACK },
|
||||
{ "checkstack", PRAGMA_CHECKSTACK }, /* obsolete */
|
||||
{ "code-name", PRAGMA_CODE_NAME },
|
||||
{ "codeseg", PRAGMA_CODESEG }, /* obsolete */
|
||||
{ "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 },
|
||||
{ "regvars", PRAGMA_REGVARS }, /* obsolete */
|
||||
{ "rodata-name", PRAGMA_RODATA_NAME },
|
||||
{ "rodataseg", PRAGMA_RODATASEG }, /* obsolete */
|
||||
{ "signed-chars", PRAGMA_SIGNED_CHARS },
|
||||
{ "signedchars", PRAGMA_SIGNEDCHARS }, /* obsolete */
|
||||
{ "static-locals", PRAGMA_STATIC_LOCALS },
|
||||
{ "staticlocals", PRAGMA_STATICLOCALS }, /* obsolete */
|
||||
{ "warn", PRAGMA_WARN },
|
||||
{ "writable-strings", PRAGMA_WRITABLE_STRINGS },
|
||||
{ "zpsym", PRAGMA_ZPSYM },
|
||||
{ "align", PRAGMA_ALIGN },
|
||||
{ "allow-eager-inline", PRAGMA_ALLOW_EAGER_INLINE },
|
||||
{ "bss-name", PRAGMA_BSS_NAME },
|
||||
{ "bssseg", PRAGMA_BSSSEG }, /* obsolete */
|
||||
{ "charmap", PRAGMA_CHARMAP },
|
||||
{ "check-stack", PRAGMA_CHECK_STACK },
|
||||
{ "checkstack", PRAGMA_CHECKSTACK }, /* obsolete */
|
||||
{ "code-name", PRAGMA_CODE_NAME },
|
||||
{ "codeseg", PRAGMA_CODESEG }, /* obsolete */
|
||||
{ "codesize", PRAGMA_CODESIZE },
|
||||
{ "data-name", PRAGMA_DATA_NAME },
|
||||
{ "dataseg", PRAGMA_DATASEG }, /* obsolete */
|
||||
{ "inline-stdfuncs", PRAGMA_INLINE_STDFUNCS },
|
||||
{ "local-strings", PRAGMA_LOCAL_STRINGS },
|
||||
{ "optimize", PRAGMA_OPTIMIZE },
|
||||
{ "register-vars", PRAGMA_REGISTER_VARS },
|
||||
{ "regvaraddr", PRAGMA_REGVARADDR },
|
||||
{ "regvars", PRAGMA_REGVARS }, /* obsolete */
|
||||
{ "rodata-name", PRAGMA_RODATA_NAME },
|
||||
{ "rodataseg", PRAGMA_RODATASEG }, /* obsolete */
|
||||
{ "signed-chars", PRAGMA_SIGNED_CHARS },
|
||||
{ "signedchars", PRAGMA_SIGNEDCHARS }, /* obsolete */
|
||||
{ "static-locals", PRAGMA_STATIC_LOCALS },
|
||||
{ "staticlocals", PRAGMA_STATICLOCALS }, /* obsolete */
|
||||
{ "warn", PRAGMA_WARN },
|
||||
{ "writable-strings", PRAGMA_WRITABLE_STRINGS },
|
||||
{ "zpsym", PRAGMA_ZPSYM },
|
||||
};
|
||||
|
||||
/* Result of ParsePushPop */
|
||||
@@ -703,6 +707,10 @@ static void ParsePragma (void)
|
||||
IntPragma (&B, &DataAlignment, 1, 4096);
|
||||
break;
|
||||
|
||||
case PRAGMA_ALLOW_EAGER_INLINE:
|
||||
FlagPragma (&B, &EagerlyInlineFuncs);
|
||||
break;
|
||||
|
||||
case PRAGMA_BSSSEG:
|
||||
Warning ("#pragma bssseg is obsolete, please use #pragma bss-name instead");
|
||||
/* FALLTHROUGH */
|
||||
@@ -739,6 +747,10 @@ static void ParsePragma (void)
|
||||
SegNamePragma (&B, SEG_DATA);
|
||||
break;
|
||||
|
||||
case PRAGMA_INLINE_STDFUNCS:
|
||||
FlagPragma (&B, &InlineStdFuncs);
|
||||
break;
|
||||
|
||||
case PRAGMA_LOCAL_STRINGS:
|
||||
FlagPragma (&B, &LocalStrings);
|
||||
break;
|
||||
|
||||
1421
src/cc65/stdfunc.c
1421
src/cc65/stdfunc.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user