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

Generate constant structures for constructions all of whose inputs are constant #352

Open
pschachte opened this issue Aug 22, 2022 · 4 comments
Labels
enhancement New feature or request performance Issues related to performance of generated code

Comments

@pschachte
Copy link
Owner

This would mean that something like [1,2,3,4,5] in Wybe code would be put into a constant in the code segment, so it wouldn't have to be constructed every time that code runs.

@pschachte pschachte added enhancement New feature or request performance Issues related to performance of generated code labels Aug 22, 2022
@jimbxb
Copy link
Collaborator

jimbxb commented Sep 26, 2022

One issue with a structure such as [1,2] is that the structure is not flat, and would have internal pointers, ala ?t0 = [2 | []]; ?t = [1 | t0], which would complicate a constant code segment. Having numerous cons cells that are each self referential, however, would work.

There would also have repercussions if CTGC decided to reuse the memory, as a code segment, to my knowledge, is for constants. Perhaps I am wrong here though, as global variables are a thing.

@jimbxb
Copy link
Collaborator

jimbxb commented Sep 26, 2022

Another very simple optimisation that we could implement is to pull multiple heap allocations together, allocating one large structure, and using segments of the allocated memory for each of the separate allocations.

I'm not sure of the repercussions of this on the GC, as it would change the allocation pattern from lots of small allocations to less larger allocations.

This could also be extended to allocating all memory for a proc at the start of the call, pulling all allocations over every branch, using different offsets for each branch if necessary. If branches use drastically different amounts of memory, this would likely be less desirable, so some heuristic could be involved.

Paul Bone did a write up that may be useful for considerations here
https://paul.bone.id.au/blog/2016/10/08/memory-fragmentation-in-boehmgc/

@pschachte
Copy link
Owner Author

pschachte commented Sep 27, 2022

One issue with a structure such as [1,2] is that the structure is not flat, and would have internal pointers, ala ?t0 = [2 | []]; ?t = [1 | t0], which would complicate a constant code segment.

Not really. The optimisation just needs to work bottom-up, but since structures need to be built bottom-up, an optimisation that works forward through the code should handle this naturally. If this is handled in BodyBuilder, it would need to recognise a sequence of allocation followed by enough mutate instructions to fill the entire allocation with constants, and generate a constant structure (similar to what we do for C strings), replacing the final mutate instruction with an instruction to move the address of the constant structure to the output variable (the backward pass would remove the allocation and mutate instructions as unneeded code). Then this variable will be considered to be a constant, so when it's stored by a later mutate instruction, the structure it is part of will be eligible for this same optimisation, so entire constant structures would be turned into constants.

There would also have repercussions if CTGC decided to reuse the memory, as a code segment, to my knowledge, is for constants. Perhaps I am wrong here though, as global variables are a thing.

Yes, this needs to be considered carefully when this optimisation is made. It does mean that in some instances that could be handled destructively will be transformed not to be destructive. In a single occurrence, I think this optimisation is still beneficial, since it only builds one copy of the structure at runtime, instead of building one and then mutating it. But in a recursive case, it could be terrible (instead of building a structure once and destructively updating it 1000 times, you'd be copying it 1000 times). So this needs some good heuristics.

@pschachte
Copy link
Owner Author

pschachte commented Sep 27, 2022

Another very simple optimisation that we could implement is to pull multiple heap allocations together, allocating one large structure, and using segments of the allocated memory for each of the separate allocations.

That's a nice idea. But it's not really related to this issue, because this is about fully constant structures. Could you post this as a separate issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request performance Issues related to performance of generated code
Projects
None yet
Development

No branches or pull requests

2 participants