How best to time passes using the API instead of opt? Also, memory leaks when trying to do timing in the API.

I have some PassManagers, and I would like to output timing data for
how long each pass takes to execute with a separate application using
the API, rather than through an llvm tool. Unfortunately, I'm having
trouble seeing how to use the existing facilities without using opt.
Setting llvm::TimePassesIsEnabled before creating the PassManagers
doesn't seem to output anything, though it is making Timers and
TimerGroups. Even if I call llvm::getPassTimer for one of the passes
(and I do get a timer that is initialized), I can't figure out to get
to its TimerGroup (TG is private, but if I use a debugger, I can get
it and call printAll successfully). Looking through the code,
TimerGroup's removeTimer (also called in it's destructor) appears to
print everything out to the info-output-file (stderr) when its Timers
are all removed but I see no output, however I'm able to call
llvm::CreateInfoOutputFile myself, pipe to it, and stuff shows up on
stderr. In PassManager.cpp, TheTimeInfo (which is a TimingInfo), gets
assigned once, and as far as I can tell never gets deleted, thus its
destructor is never called, the Timers are never deleted, and the
timing data is never output. Valgrind shows these Timers, TimerGroup,
and TimingInfo as being memory leaks for my application when I enable
llvm::TimePassesIsEnabled. Is there a way in the API to delete
TheTimeInfo myself, even though TheTimeInfo is static? Also, if this
is a bug/deficiency, I'm willing to patch this with some guidance,
e.g. is putting "delete TheTimingInfo; TheTimeInfo = 0"; in
PMTopLevelManager's destructor appropriate? Or is there a much easier
solution that I'm just missing?


I got it working with this:

     int argc = 2;
     const char *argv[2] = {"myopt", "-time-passes"};

     cl::ParseCommandLineOptions(argc, (char **)argv, "my optimizer");

Thanks for the reply! Unfortunately, that seems to have the same
effect as setting llvm::TimePassesIsEnabled myself, and all my same
problems still apply as the TimingInfo's destructor (PassManager.cpp)
is still never called. Running it in the debugger shows that
TimerGroup's removeTimer method is never called, nor is it's
destructor (but it's constructor is).

Oh, you probably also need to create a static llvm_shutdown_obj.

Yes, thank you, that's basically what I have missing. I had seen
ManagedStatic crop up a few times but hadn't explored it. It seems
there are a lot of hidden gems in llvm/Support like this.