Date: Fri, 19 Jan 2018 09:25:34 -0800 From: Conrad Meyer <cem@freebsd.org> To: "Rodney W. Grimes" <rgrimes@freebsd.org> Cc: src-committers <src-committers@freebsd.org>, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r327354 - head/sys/vm Message-ID: <CAG6CVpVQqyhub0g-iOjKbZYEaEqAy87WdrocoQ_MxYhvbz1k%2BQ@mail.gmail.com> In-Reply-To: <201801191704.w0JH4rgT072967@pdx.rh.CN85.dnsmgr.net> References: <601ee1a2-8f4e-518d-4c86-89871cd652af@vangyzen.net> <201801191704.w0JH4rgT072967@pdx.rh.CN85.dnsmgr.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, Jan 19, 2018 at 9:04 AM, Rodney W. Grimes <freebsd@pdx.rh.cn85.dnsmgr.net> wrote: > BUT I do not believe this bit of "style" has anything to do with > readability of code, and has more to do with how code runs on a > processor and stack frames. If you defer the declaration of > "int i" in the above code does that compiler emmit code to allocate > a new stack frame, or does it just add space to the function stack > frame for this? > > What happens if you do > for (int i =3D 0; i < pages;) { } > > for (int i =3D 1; i < pages;) { } > as 2 seperate loops, do we allocate 2 i's on the stack at > function startup, or do we defer and allacte each one > only when that basic block runs, or do we allocate 1 i > and reuse it, I know that the compiler makes functional > code but how is that functionality done? The current > style leaves no doubt about how things are done from > that perspective. Modern (and I'm using that word very loosely here =E2=80=94 think GCC did t= his 10+ years ago) optimizing compilers do something called liveness tracking[0] for variables to determine the scope they are used in (something like the region between last write and last read). So in that sense, optimizing compilers do not care whether you declare the variable at function scope or local scope =E2=80=94 they always determine t= he local scope the variable is alive in. (Other than for shadowing, which we strongly discourage and is considered bad style.) Liveness analysis is part of register allocation[1], which typically uses a graph coloring algorithm to determine the minimal number of distinct registers needed to hold live values. If the number of registers needed is more than the machine provides, some values must be spilled to the stack. (On modern x86 it doesn't matter too much what you spill to the stack, because the top few words of the stack region is actually quite fast, but clever compilers targeting other platforms may attempt to spill less frequently accessed values.) I think I recall Clang and other LLVM frontends do something nutty when they emit intermediary representation, like using a new register for each assignment. This relies on the register allocater to reduce that to something sane for the target machine. Best, Conrad [0]: https://en.wikipedia.org/wiki/Live_variable_analysis [1]: https://en.wikipedia.org/wiki/Register_allocation
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAG6CVpVQqyhub0g-iOjKbZYEaEqAy87WdrocoQ_MxYhvbz1k%2BQ>