On Linux if you just

  echo 'int main(int ac,char**av){return 0;}' >/dev/shm/true.c

And then time (with high resolution) `tcc -run /dev/shm/true.c`,
you get execution time about 2X longer than the same with `tcc -c`.
Running strace on the linking revealed hundreds of read(,,1)'s.
Looking into it further, these are all from tccelf.c:ld_inp()
which it seems was added by grischka in 2019 for multi-threading.
I might even guess the unbuffered reads were a "placeholder" that
never got replaced.

If you first apply the attached patch and do the same thing, most
unneeded system call overhead vanishes and the end-to-end time (of,
yes, that trivial program) gets 1.35X better (on an i7-6700k it goes
down to 750 microsec from 1000 microsec with statistical errors
around +-10 microsec).  The size expansion of TCCState is not so
bad -- 272 bytes added to the 1808 byte struct or +15%.

cb
diff --git a/tcc.h b/tcc.h
index 687fb607..71cf4e5a 100644
--- a/tcc.h
+++ b/tcc.h
@@ -1002,6 +1002,8 @@ struct TCCState {
     int argc;
     char **argv;
     CString linker_arg; /* collect -Wl options */
+    int  ioBufN;          /* number of bytes used in ioBuf */
+    char ioBuf[256], *ioBufP;    /* A small IO buffer & ptr */
 };
 
 struct filespec {
diff --git a/tccelf.c b/tccelf.c
index 8e11c1bf..cd588b8e 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -3799,17 +3799,25 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
 #define LD_TOK_NAME 256
 #define LD_TOK_EOF  (-1)
 
+static char ioBufFill(TCCState *s1) {
+    int m = read(s1->fd, s1->ioBuf, sizeof s1->ioBuf);
+    if (m > 0) {
+        s1->ioBufP = &s1->ioBuf[1];
+        s1->ioBufN = m - 1;
+        return s1->ioBuf[0];
+    }
+    return CH_EOF;
+}
+#define TCC_GETCH(s1) ((s1)->ioBufN-- > 0 ? *(s1)->ioBufP++ : ioBufFill((s1)))
+
 static int ld_inp(TCCState *s1)
 {
-    char b;
     if (s1->cc != -1) {
         int c = s1->cc;
         s1->cc = -1;
         return c;
     }
-    if (1 == read(s1->fd, &b, 1))
-        return b;
-    return CH_EOF;
+    return TCC_GETCH(s1);
 }
 
 /* return next ld script token */
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to