bypass indirection through pointer objects to access stdin/out/err
authorRich Felker <dalias@aerifal.cx>
Thu, 18 Oct 2018 03:57:28 +0000 (23:57 -0400)
committerRich Felker <dalias@aerifal.cx>
Thu, 18 Oct 2018 04:32:20 +0000 (00:32 -0400)
by ABI, the public stdin/out/err macros use extern pointer objects,
and this is necessary to avoid copy relocations that would be
expensive and make the size of the FILE structure part of the ABI.
however, internally it makes sense to access the underlying FILE
objects directly. this avoids both an indirection through the GOT to
find the address of the stdin/out/err pointer objects (which can't be
computed PC-relative because they may have been moved to the main
program by copy relocations) and an indirection through the resulting
pointer object.

in most places this is just a minor optimization, but in the case of
getchar and putchar (and the unlocked versions thereof), ipa constant
propagation makes all accesses to members of stdin/out PC-relative or
GOT-relative, possibly reducing register pressure as well.

src/include/stdio.h [new file with mode: 0644]
src/stdio/stderr.c
src/stdio/stdin.c
src/stdio/stdout.c

diff --git a/src/include/stdio.h b/src/include/stdio.h
new file mode 100644 (file)
index 0000000..534c690
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef STDIO_H
+#define STDIO_H
+
+#include "../../include/stdio.h"
+
+#undef stdin
+#undef stdout
+#undef stderr
+
+extern hidden FILE __stdin_FILE;
+extern hidden FILE __stdout_FILE;
+extern hidden FILE __stderr_FILE;
+
+#define stdin (&__stdin_FILE)
+#define stdout (&__stdout_FILE)
+#define stderr (&__stderr_FILE)
+
+#endif
index 229c8651dd5bd14e31ada5bb542f0c62f19a55bf..f2bc4648d6f0af2f0e8c2ced2531fcef940ad56f 100644 (file)
@@ -1,7 +1,9 @@
 #include "stdio_impl.h"
 
+#undef stderr
+
 static unsigned char buf[UNGET];
-static FILE f = {
+hidden FILE __stderr_FILE = {
        .buf = buf+UNGET,
        .buf_size = 0,
        .fd = 2,
@@ -12,5 +14,5 @@ static FILE f = {
        .close = __stdio_close,
        .lock = -1,
 };
-FILE *const stderr = &f;
-FILE *volatile __stderr_used = &f;
+FILE *const stderr = &__stderr_FILE;
+FILE *volatile __stderr_used = &__stderr_FILE;
index 171ff22a9842dc74db9ccf1be15df17cfc2af2c3..5aa5262c2a5c8822f9006431898887789421c6e1 100644 (file)
@@ -1,7 +1,9 @@
 #include "stdio_impl.h"
 
+#undef stdin
+
 static unsigned char buf[BUFSIZ+UNGET];
-static FILE f = {
+hidden FILE __stdin_FILE = {
        .buf = buf+UNGET,
        .buf_size = sizeof buf-UNGET,
        .fd = 0,
@@ -11,5 +13,5 @@ static FILE f = {
        .close = __stdio_close,
        .lock = -1,
 };
-FILE *const stdin = &f;
-FILE *volatile __stdin_used = &f;
+FILE *const stdin = &__stdin_FILE;
+FILE *volatile __stdin_used = &__stdin_FILE;
index 6b188942dced8dec953b5f5a7d00a0c78f4a0f0b..4985a417bdda733de44f88defcc849eeac9fb427 100644 (file)
@@ -1,7 +1,9 @@
 #include "stdio_impl.h"
 
+#undef stdout
+
 static unsigned char buf[BUFSIZ+UNGET];
-static FILE f = {
+hidden FILE __stdout_FILE = {
        .buf = buf+UNGET,
        .buf_size = sizeof buf-UNGET,
        .fd = 1,
@@ -12,5 +14,5 @@ static FILE f = {
        .close = __stdio_close,
        .lock = -1,
 };
-FILE *const stdout = &f;
-FILE *volatile __stdout_used = &f;
+FILE *const stdout = &__stdout_FILE;
+FILE *volatile __stdout_used = &__stdout_FILE;