From 9a49451124a781a2cd032b6e7616c67a7815fe57 Mon Sep 17 00:00:00 2001 From: PMunch Date: Fri, 25 Feb 2022 10:43:03 +0100 Subject: [PATCH] Remove volatiles when compiling with ARC/ORC (#19545) This removes volatiles on ARC/ORC targets in NimMain and PreMainInner. This avoids an issue where they couldn't be optimised out on microcontrollers leading to larger code. Since the stack bottom doesn't have to be initialised this way when using ARC or ORC (or None, which is also covered by this PR) these can be safely removed. --- compiler/cgen.nim | 68 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 10b4b55d0f..b78ad10c43 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1363,16 +1363,25 @@ proc genMainProc(m: BModule) = # The use of a volatile function pointer to call Pre/NimMainInner # prevents inlining of the NimMainInner function and dependent # functions, which might otherwise merge their stack frames. - PreMainBody = "$N" & + + PreMainVolatileBody = + "\tvoid (*volatile inner)(void);$N" & + "\tinner = PreMainInner;$N" & + "$1" & + "\t(*inner)();$N" + + PreMainNonVolatileBody = + "$1" & + "\tPreMainInner();$N" + + PreMainBodyStart = "$N" & "N_LIB_PRIVATE void PreMainInner(void) {$N" & "$2" & "}$N$N" & PosixCmdLine & - "N_LIB_PRIVATE void PreMain(void) {$N" & - "\tvoid (*volatile inner)(void);$N" & - "\tinner = PreMainInner;$N" & - "$1" & - "\t(*inner)();$N" & + "N_LIB_PRIVATE void PreMain(void) {$N" + + PreMainBodyEnd = "}$N$N" MainProcs = @@ -1385,17 +1394,32 @@ proc genMainProc(m: BModule) = "$1" & "}$N$N" - NimMainProc = - "N_CDECL(void, $5NimMain)(void) {$N" & - "\tvoid (*volatile inner)(void);$N" & - "$4" & - "\tinner = NimMainInner;$N" & - "$2" & - "\t(*inner)();$N" & + NimMainVolatileBody = + "\tvoid (*volatile inner)(void);$N" & + "$4" & + "\tinner = NimMainInner;$N" & + "$2" & + "\t(*inner)();$N" + + NimMainNonVolatileBody = + "$4" & + "$2" & + "\tNimMainInner();$N" + + NimMainProcStart = + "N_CDECL(void, $5NimMain)(void) {$N" + + NimMainProcEnd = "}$N$N" + NimMainProc = NimMainProcStart & NimMainVolatileBody & NimMainProcEnd + + NimSlimMainProc = NimMainProcStart & NimMainNonVolatileBody & NimMainProcEnd + NimMainBody = NimMainInner & NimMainProc + NimSlimMainBody = NimMainInner & NimSlimMainProc + PosixCMain = "int main(int argc, char** args, char** env) {$N" & "\tcmdLine = args;$N" & @@ -1456,10 +1480,13 @@ proc genMainProc(m: BModule) = m.includeHeader("") let initStackBottomCall = - if m.config.target.targetOS == osStandalone or m.config.selectedGC == gcNone: "".rope + if m.config.target.targetOS == osStandalone or m.config.selectedGC in {gcNone, gcArc, gcOrc}: "".rope else: ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", []) inc(m.labels) - appcg(m, m.s[cfsProcs], PreMainBody, [m.g.mainDatInit, m.g.otherModsInit]) + if m.config.selectedGC notin {gcNone, gcArc, gcOrc}: + appcg(m, m.s[cfsProcs], PreMainBodyStart & PreMainVolatileBody & PreMainBodyEnd, [m.g.mainDatInit, m.g.otherModsInit]) + else: + appcg(m, m.s[cfsProcs], PreMainBodyStart & PreMainNonVolatileBody & PreMainBodyEnd, [m.g.mainDatInit, m.g.otherModsInit]) if m.config.target.targetOS == osWindows and m.config.globalOptions * {optGenGuiApp, optGenDynLib} != {}: @@ -1484,9 +1511,14 @@ proc genMainProc(m: BModule) = appcg(m, m.s[cfsProcs], nimMain, [m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix]) else: - const nimMain = NimMainBody - appcg(m, m.s[cfsProcs], nimMain, - [m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix]) + if m.config.selectedGC notin {gcNone, gcArc, gcOrc}: + const nimMain = NimMainBody + appcg(m, m.s[cfsProcs], nimMain, + [m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix]) + else: + const nimMain = NimSlimMainBody + appcg(m, m.s[cfsProcs], nimMain, + [m.g.mainModInit, initStackBottomCall, m.labels, preMainCode, m.config.nimMainPrefix]) if optNoMain notin m.config.globalOptions: if m.config.cppCustomNamespace.len > 0: