Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Superfluous dereferencing when accessing entries in functor arguments #6932

Closed
vicuna opened this issue Jul 17, 2015 · 3 comments
Closed

Superfluous dereferencing when accessing entries in functor arguments #6932

vicuna opened this issue Jul 17, 2015 · 3 comments

Comments

@vicuna
Copy link

vicuna commented Jul 17, 2015

Original bug ID: 6932
Reporter: @mmottl
Status: resolved (set by @damiendoligez on 2016-03-22T15:17:43Z)
Resolution: suspended
Priority: normal
Severity: tweak
Version: 4.02.2
Target version: 4.03.0+dev / +beta1
Category: middle end (typedtree to clambda)
Monitored by: @ygrek @hcarty @yakobowski @mmottl

Bug description

Consider the following functor example:


module type Arg = sig val x : int end

module Make (Arg : Arg) = struct
open Arg

let f1 () = x

let x = x
let f2 () = x
end

The definitions of f1 and f2 look identical, but the generated machine code is different. f1 actually looks up the pointer to the functor argument Arg first, then dereferences it to obtain x. f2, however, accesses the "x" that is bound in the functor body instead, which saves one instruction.

This may seem like a small deal, but if the functor argument itself has deeply nested submodules, this can lead to a lot of superfluous pointer chasing that may require the user to "lift" a lot of argument entries by hand.

It might be interesting to consider an optimization where any entries (like "x" above) in an argument module (and submodules) that are referenced from within functions in a functor body are automatically "lifted" into the functor body.

The downside would be that an instantiated functor results in a "bigger" module in terms of memory and may require a little more time to instantiate. But I think it's fair to assume that functor applications are rare whereas function calls into instantiated functors are frequent.

Even better would be inlining of functor applications / defunctorization. Not sure whether this project ever got close to that goal:

http://www.ocamlpro.com/blog/2013/07/11/inlining-progress-report.html

@vicuna
Copy link
Author

vicuna commented Mar 20, 2016

Comment author: @mmottl

As annoying as it may be, I have come to the conclusion that this problem may not be easily solved without manually binding entries for which this optimization makes sense. Unless anybody has a better idea, I think this issue can be closed.

@vicuna
Copy link
Author

vicuna commented Mar 22, 2016

Comment author: @damiendoligez

I'd like to know whether flambda solves this particular problem.

@vicuna vicuna closed this as completed Mar 22, 2016
@vicuna
Copy link
Author

vicuna commented Mar 22, 2016

Comment author: @mmottl

@doligez: Thanks for motivating me to look into Flambda some more with this problem. I had actually tried it a while back, but hadn't seen much improvement. But that was a rather sloppy test with a development version, and I didn't know as much about Flambda back then.

I have just done some more extensive testing and have seen quite favorable results. The solution was to amp up the optimization settings. Just passing "-O2" will probably do the trick in many cases. Code annotations can probably help with a more targeted approach. The compiler with Flambda produces astoundingly good code when it knows functor arguments and if you give it enough leeway to specialize and inline. It can definitely get rid of the pointer chasing observed before Flambda came along.

There are likely scenarios where Flambda cannot possibly specialize the code, e.g. when the functor argument isn't known at compile time. I guess in these cases it's up to the user to lift some frequently needed values by hand from the functor argument to avoid some dereferencing.

@vicuna vicuna added this to the 4.03.0 milestone Mar 14, 2019
@vicuna vicuna added the bug label Mar 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant