Skip to content

Fix a bug in the handling of regions with exclaves#1784

Closed
stedolan wants to merge 1 commit intooxcaml:mainfrom
stedolan:fix-exclave-regions
Closed

Fix a bug in the handling of regions with exclaves#1784
stedolan wants to merge 1 commit intooxcaml:mainfrom
stedolan:fix-exclave-regions

Conversation

@stedolan
Copy link
Copy Markdown
Contributor

There is a well-named field in Typedtree.Texp_function called region: it is true if this function has a region.

There is a badly-named field in Lambda.lfunction called region: it is true if this function cannot allocate locals in its caller's region.

These two ideas used to coincide, but they don't since the addition of exclaves, which allow a function with a region (Texp_function{region = true}) to allocate locals in its caller's region inside an exclave_. This means it is incorrect to directly initialise the region field of lfunction with that of Texp_function.

This patch fixes the issue by computing the region field of lfunction by examining the body. It also weakens the invariants slightly on lfunction: it is no longer the case that region=false implies nlocals>0. (This only mattered to inhibit a function-merging optimisation in Simplif that is not valid in this case, but that optimisation is already inhibited by region=false alone).

Texp_function {region} indicates whether the function has a region,
but Lfunction {region} indicates whether the function may allocate
locals into the region of its caller. These used to coincide, but do
not since exclaves were added, so need to be computed differently.
@ncik-roberts
Copy link
Copy Markdown
Contributor

It's worth mentioning that we'd like to rename the badly-named region field in Lambda.lfunction, but we'll do so after I finish n-ary lambdas, a PR with which such a rename would conflict substantially. Stephen suggests (eventually):

  • add a type Lambda.exclave_status = May_allocate_in_caller | Never_allocates_in_caller
  • use this type in Lambda.lfunction.region instead of bool
  • use this type in Lambda.Lapply.ap_mode instead of alloc_mode

Copy link
Copy Markdown
Collaborator

@lpw25 lpw25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. One small suggestion.

~tail:(loop ~depth)
~non_tail:ignore (* Exclaves are in tail position *)
in
loop ~depth:0 lam
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this part is no different than the original code other than supporting nested Lregion. Note that nested regions are not currently supported and would break in a few places in lambda, so this is isn't strictly necessary.

let loc = of_location ~scopes e.exp_loc in
let body = if region then maybe_region_layout return body else body in
let lam = lfunction ~kind ~params ~return ~body ~attr ~loc ~mode ~region in
let may_locally_allocate_in_parent = may_allocate_in_region body in
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels a bit wasteful in the case where the function has a region and does no local allocations: we end up looking at all it's allocations twice. Is there a simple way to only do one traversal here?

@mshinwell
Copy link
Copy Markdown
Collaborator

I believe this has been merged as part of another PR.

@mshinwell mshinwell closed this Jan 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working middle end

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants