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:
Oliver Schmidt
2017-04-03 23:20:26 +02:00
parent cbb2833c01
commit 02daf9f8b5
9 changed files with 1033 additions and 868 deletions

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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;

File diff suppressed because it is too large Load Diff