Lets extract some useful results from my gcc plugin for collecting cross-references: 1, 2, 3, 4, 5, 6, 7 & 8.
I've noticed that plugin worked unbearably slowly on big source files (like compiling itself) - something above 30 minutes, so I add profiling to it (see details here). Profiler showed that consumed user-time was only 18 seconds - this is glare sign that plugin spending most of time on some kind of lock. After some meditation (and strace/ltrace) I finally found that root of problem was in sqlite - it sleeping in fdatasync on each data writing to its DB! The cure is to executePRAGMA synchronous=OFF
this gives a non-illusory x100 speed up. Can I now consider myself as one of mythical "x100 programmer", he-he?
The next problem is how to store data from multiple gcc processes into single sqlite DB (like parallel make -j X). I've decided to use Apache Thrift - old and unfashionable but it really works and you can make multithreaded RPC server in 500 lines of c++ code. Server just listen on some port and stores all data from RPC clients into sqlite DB. Command line arguments path2db port_number .To shutdown RPC server use rpcq port_number. Of course you can make your own implementation of RPC server, for example with PHP & DB/2 (unfortunately Thrift does not supports Cobol)
As a consequence now plugin has 3 implementations for data storing:
- in plain text files, self-test takes 14s
- into sqlite, self-test takes 18s
- in sqlite via RPC server listened on some arbitrary TCP port. Self-test takes 23s. Connection string looks like -fplugin-arg-gptest-db=localhost:port_number
Btw sqlite version has size 2.67Mb, Thrift rpc client - 4.65Mb. Something is fundamentally wrong with "modern frameworks"
DB schema
is very simple - in essence it consists of two tables:symtab for storing symbols
- id - primary key
- mangled name of symbol/function or value of literal
- fname - for functions this is name of file where they were declared
- bcount - amount of basic blocks of function, can be used as some complexity metric
xrefs to link symbols and functions from which they are referred
- id of function
- bb - index of basic block
- arg - if non-zero - index of function's argument
- what - id of referred symbol
- kind - one letter type of xref:
- 'c' - function call
- 'v' - call of virtual method
- 'l' - literal
- 'r' - just reference to some global symbol
- 'f' - field of some struct/class/union
- 'F' - constant (with -fplugin-arg-gptest-ic option)
Fetching results