Future compiler note
If ir ever grows a compiler/backend path, treat dynamic dispatch as a control-flow lowering problem rather than automatically routing it through a large generic runtime abstraction.
R's S3 dispatch is the motivating example: a call such as print(x) chooses print.<class> from runtime information. Once the applicable method has been resolved (or a valid inline/cache fast path has established it), the backend should aim to lower the actual transfer of control as directly as the target allows:
- direct branch/call when the method is statically known;
- compact compare/branch or jump-table structure when the candidate set is small and known;
- indirect branch/call through a resolved function address when the target is genuinely runtime-selected;
- consider monomorphic/polymorphic inline caches if they preserve R semantics and materially reduce repeated lookup.
The point is not to pretend S3 method lookup itself is free. R semantics such as class vectors, method replacement, inheritance/NextMethod, environments, and invalidation still have to be respected. The compiler opportunity is to avoid adding unnecessary layers after the dispatch target can safely be determined.
A useful eventual benchmark would compare:
- ordinary interpreter/runtime S3 dispatch;
- cached method resolution plus indirect branch;
- statically resolved direct call where legal;
- a small multi-method case suitable for explicit branch/jump-table lowering.
Keep this as a compiler-design note for now; ir does not need a compiler backend merely to pursue this issue.
Future compiler note
If
irever grows a compiler/backend path, treat dynamic dispatch as a control-flow lowering problem rather than automatically routing it through a large generic runtime abstraction.R's S3 dispatch is the motivating example: a call such as
print(x)choosesprint.<class>from runtime information. Once the applicable method has been resolved (or a valid inline/cache fast path has established it), the backend should aim to lower the actual transfer of control as directly as the target allows:The point is not to pretend S3 method lookup itself is free. R semantics such as class vectors, method replacement, inheritance/
NextMethod, environments, and invalidation still have to be respected. The compiler opportunity is to avoid adding unnecessary layers after the dispatch target can safely be determined.A useful eventual benchmark would compare:
Keep this as a compiler-design note for now;
irdoes not need a compiler backend merely to pursue this issue.