Thanks, Ben.

>From the outside, looking from the GC-inclined perspective, it seems
unfortunate that LLVM doesn't have a distinguished register class in the IR
for object references as opposed to pointers. This would go a long way
toward solving the stack map problem. On the other hand, I haven't thought
hard enough about whether the presence of GCREAD/GCWRITE coupled with local
dataflow might be enough.

The "no objects in registers" rule, though, is *very* expensive. At first
glance, it would seem to restrict the compiler to the Henderson-style
approach. The overhead of those spills has been measured. It's pretty big.

There is a stage in LLVM where hard registers are selected. Do the
GCREAD/GCWRITE annotations survive to that point?

As I understand matters, the original plan in rust was to use type
inference on the LLVM IL to maintain information about the root set. If
what we have to work from is GCREAD/GCWRITE, then of course data flow
analysis is required, but that doesn't seem insurmountable.

The thing is: *given* that it's not insurmountable, it makes me nervous
that the Rust folks gave up on that approach and forked LLVM.

Addendum: there are actually *other* reasons to want a distinguished
register class for object references. There are some pointer incrementing
optimizations that you want to disable for this register class, so
distinguishing it as a separate class is actually useful as a signal to
various optimization passes.

Power to weight ratio is a subjective metric. :-)



On Thu, Oct 17, 2013 at 10:47 AM, Ben Karel <[email protected]> wrote:

> LLVM has gcread and gcwrite primitives, which a GC plugin can
> override/expand into load/store GC barriers. The docs specifically mention
> reference counting as one such barrier enabled by the primitives.
>
> I think the unqualified word "register" is best avoided in this context --
> for one, it's overloaded (SSA vs machine); besides that, I think it's also
> just the wrong way to think about GC in LLVM.
>
> Here's my model:
>
> For precise collection, LLVM requires that every live reference exist in
> memory when a GC occurs. This is pretty reasonable -- after all, the
> collector is going to have a function somewhere with a signature like  void
> update_root(void** root, void* new_ref).  The question is then: who is
> responsible for maintaining this invariant, LLVM or the front-end? The
> answer is a function of who knows the most about where GCs might occur.
> LLVM's current implementation has no concept of where actual GC points are.
> (Don't confuse safe points with GC points. Safe points are a superset of GC
> points. A call to a function which cannot GC is a safe point but not a GC
> point). Since efficiently enforcing the in-memory requirement requires
> knowledge of GC points, LLVM leaves it to the front-end to decide how to
> most efficiently do the enforcement.
>
> On the one hand, this means that front-ends must do more work -- i.e.
> dataflow analysis -- for "optimal" precise GC-related codegen than in the
> non-GC case. On the other hand, I would argue that any frontend which cares
> about the performance delta between "optimal" and conservative root
> treatment needs to be doing its own dataflow analysis anyways, and so it's
> not a significant cost on the front-end side.  The tradeoff also happens to
> be a significant local maxima of the design space in terms of
> power-to-weight ratio on the LLVM side. (AFAICT as an outsider, Rust's
> GC-related fork of LLVM significantly regressed that ratio, which seems
> like a major reason it wasn't upstreamed).
>
> -- The Other Ben K.
>
>
> On Thu, Oct 17, 2013 at 11:48 AM, Jonathan S. Shapiro <[email protected]>wrote:
>
>> So with the possible revival of the reference counting discussion, LLVM
>> may become viable as an interim back end again. The main thing it's missing
>> (and I haven't checked, so it may have been added) is support for
>> LDREF/STREF in the LLVM instruction set. There are techniques that can
>> compensate for that. Most of them are expensive in terms of performance,
>> but something is certainly better than nothing.
>>
>> Does anyone happen to know how LLVM handles object references that live
>> in registers?  I'm hazarding a guess that the answer amounts to "use
>> conservative marking on registers and don't let the target objects move so
>> that you don't have to adjust the register values".
>>
>> But does anybody here actually *know*?
>>
>> shap
>>
>> _______________________________________________
>> bitc-dev mailing list
>> [email protected]
>> http://www.coyotos.org/mailman/listinfo/bitc-dev
>>
>>
>
> _______________________________________________
> bitc-dev mailing list
> [email protected]
> http://www.coyotos.org/mailman/listinfo/bitc-dev
>
>
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to