A recent change to the way metadata works has broken my StaticRoots pass, and I need some advice.
I was using metadata to store information about static roots because of a convenient feature of metadata nodes: the arguments to an MDNode are treated as weak references, which means that a metadata node that points to a global value won’t prevent the dead global pass from removing that global. This is very handy for managing static garbage collection roots, because ordinarily the static roots table contains pointers to the global variables, and those pointers would prevent the global from being considered dead - which means that your final executable would have a bunch of unused cruft in it. But by storing the static roots in metadata, and then constructing the root table from that metadata after the global elimination pass has finished, we end up with a roots table that only includes the roots that are actually used.
So my first question is - am I abusing the metadata system by doing this? That is, am I relying on undefined behavior here? The reason I ask this is because the scheme I outlined in the previous paragraph no longer works with the current LLVM tip - the metadata nodes that used to contain references to global variables are now all NULL, regardless of whether the global variable was dead or not.
My second question is, if metadata is not the right way to do this, then what is? An alternate approach would be to have two passes, one which runs before the dead global pass, and one which runs after. The first pass removes the static roots table from the module (so that it won’t cause dead globals to become live), and the second pass adds it back, minus the global vars that were removed. The problem is guaranteeing that the passes are executed in the right order - that is, I want pass A to execute before the dead global pass, and pass B to execute after it. Is there any way I can get the pass manager to schedule my passes like this? I would prefer not to have to manually specify the order of passes on the command line, I’d rather just have the pass manager do it’s work.