I'm noticing that DSA graphs are not created for library functions like "puts". The bytecode file runs with lli, so I think I did my linking okay. Is this normal, or does it mean I'm somehow not giving the algorithm the complete program information it needs?
Unless you compile a bytecode version of the C standard library, and
link it in, then yes.
This may not be incredibly worthwhile on Linux or MacOS but it should make a big difference for embedded platforms, especially those running w/o an OS.
Is it easy to get this running, and to enable IPO across the whole apps+libs blob? Is there a tutorial or some notes anywhere on doing this with newlib, glibc, etc.?
Not that I know of. For KLEE we did it for uclibc and used that as our
libc without too much trouble. It should be much easier now that we
have wider availability of LTO, in theory compiling with llvm-gcc and
-flto will produce bitcode versions of the libraries out-of-the-box.
In practice, libc implementations use various "interesting" techniques
to get their work done, IIRC glibc doesn't currently build with
llvm-gcc, for example.