I'd like to be able to have "weak" references to global variables.
Now,
currently LLVM allows global values to have "weak" linkage type (and
variants thereof), but this is a different meaning of the word "weak"
- what
I'm thinking of is similar to the concept of weak references in Java and
other languages that support garbage collection, except that the
"collection" I'm talking about is the dead global elimination
pass. In other
words, I'd like to be able to have a reference to a global variable that
doesn't prevent that global from being deleted by the dead global pass, but
which retains that reference if there are other "strong" references to
that
global. If the global does get deleted, the "weak" reference is
replaced
with a NULL pointer.
To avoid confusion, I'll use the term "fragile" or
"tenuous" instead of
"weak" to refer to these kinds of references. This
"fragility" is a is not a
property of the global, but rather a property of the pointer to that global.
An example of a use case for fragile references relates to generating
reflection data. There are a lot of cases where one would like to be able to
iterate at runtime over all of the classes or functions in a module or
package. In order to do this, there has to be some table or other data
structure that contains references to all of the class or function objects.
However, the very existence of that table prevents the dead global
elimination pass from removing classes and functions that aren't needed.
What we really want to have is the set of class or function objects that are
left over after the dead globals have been eliminated.
A similar use case is for trace tables for static roots, and other kinds of
metadata which are associated with a function or global.
Here's how this could be implemented: A new type of constant expression
"fragile(ptr)" would be introduced. This is simply a wrapper around a
pointer, which returns the value of that pointer. The dead global
elimination pass could be modified to look for instances of this expression
type when traversing the constant structures. The pass would replace the
argument of fragile() with NULL if the global value was deleted.
There would also be a new pass that would normalize all of the fragile
references - removing the call to fragile() and replacing it with it's
contents. This would typically be run after all of the various global
optimizations were finished. In addition, this pass could also remove array
elements from arrays with appending linkage - that is, rather than replacing
fragile(NULL) with NULL, it would simply delete the array element entirely.
I'd be curious to know if anyone else would find something like this useful.
--
-- Talin
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20111026/5a62f1e5/attachment.html>