Skip to content

Speed improvement in Lift_constants#860

Merged
mshinwell merged 3 commits intoocaml:trunkfrom
mshinwell:lift_constants_speed
Dec 9, 2016
Merged

Speed improvement in Lift_constants#860
mshinwell merged 3 commits intoocaml:trunkfrom
mshinwell:lift_constants_speed

Conversation

@mshinwell
Copy link
Contributor

The Flambda pass that identifies and lifts constants is quite slow. This small modification seems to help a fair amount by preventing unnecessary rebuilding of terms.

Are we happy with the use of physical equality or not?

@mshinwell mshinwell added this to the 4.05-or-later milestone Oct 13, 2016
@gasche
Copy link
Member

gasche commented Oct 13, 2016

The assertion corresponds to specific domain knowledge about the resolution process. I would expect maybe a comment to explain it (to make the code easier to follow locally). Another option would be to use the more robust

| Symbol s1, Symbol s2 when s1 == s2 -> resolved
| Const c1, Const c2 when c1 == c2 -> resolved
| <rest of the cases>

In that case it is locally obvious that the physical equality is an optimization that does not change the program semantics.

(My first idea was to rewrite the called functions to not re-allocate the same constructor (turn | Const s -> Const s into Const _ as c -> c) and then check named == resolved, but that does not work as the types differ -- the two Const constructors involved are at different types.)

@mshinwell
Copy link
Contributor Author

mshinwell commented Oct 13, 2016

The point about physical equality was actually whether this is a valid use. I think it's undefined behaviour strictly speaking even if it does the right thing at the moment... (Since the things being compared are immutable.)

@gasche
Copy link
Member

gasche commented Oct 13, 2016

I'm not sure I get the point. Is there something particularly bad about this specific use of physical equality? While it is correct that its behavior is currently not defined, it is not "specified as an undefined behavior" either. In particular, any specification should imply that for types where structural equality is defined, two values are only physically equal when they are also structurally equal. With my when .. == .. variant, it should then be clear that the code is correct as the branch-is-taken-more-often when .. = .. code is functionally correct. (For the assertion presentation, of course this specification does not guarantee you that the assertion will pass.)

@alainfrisch
Copy link
Contributor

any specification should imply that for types where structural equality is defined, two values are only physically equal when they are also structurally equal

Only if you define structurally equal with Pervasives.compare .. .. = 0 (because (nan == nan, nan = nan)).

What about dropping the physical equality check altogether? It is only used as a proxy for checking the real invariant which matters, semantically (structural equality of the strings).

What might actually be more problematic is the use of physical equality as an optimization in the generic mapping functions, but this is not affected by this patch and I think this is fine.

@alainfrisch
Copy link
Contributor

You could keep the code is before, and change the generic mapping function to use a custom equality testing instead of using physical equality (something faster than structural equality, but "larger" than physical equality). This would also serve other occurrences, it seems.

@chambart
Copy link
Contributor

@alainfrisch I do not see the problem of physical equality in the mapping function. This only shortcuts some useless computation when the mapping is the identity. This does not affect the semantics, only compilation speed. Also, using any kind of real equality (that needs to traverse completely the values), would result in something quadratic.

@mshinwell Physical equality is not well defined, but I would consider this to be almost equivalent to the property asserted in Set.add. I don't know the right definition, but if it breaks here, I'd prefer to be aware. So I would suggest keeping it.

@alainfrisch
Copy link
Contributor

I did not say there is a problem with using the physical equality in the mapping function: it's just that given the definition of the physical equality and since the flambda IR is immutable, the compiler would be allowed to copy values, which would break the optimization. As said, I really don't think that this is problematic, but if one wonders about the implication of the lack of full specification for the physical equality, this is a more interesting question than the one raised by this patch (where the check could be dropped altogether).

using any kind of real equality (that needs to traverse completely the values), would result in something quadratic.

What I had in mind was something which would check the equality of constructors and physical equality of their arguments. This would cover the case added by this patch, but also, apprently more of the same kind (cf other instances of Symbol s -> Symbol s or Const c -> Const c in lift_constants.ml). And it seems better that all "optimizations" based on physical equality are located in a single place.

@mshinwell mshinwell merged commit 2ff3569 into ocaml:trunk Dec 9, 2016
nojb pushed a commit to nojb/ocaml that referenced this pull request Dec 29, 2016
camlspotter pushed a commit to camlspotter/ocaml that referenced this pull request Oct 17, 2017
stedolan added a commit to stedolan/ocaml that referenced this pull request Oct 25, 2022
sadiqj pushed a commit to sadiqj/ocaml that referenced this pull request Feb 21, 2023
stedolan pushed a commit to stedolan/ocaml that referenced this pull request Mar 21, 2023
25188da flambda-backend: Missed comment from PR802 (ocaml#887)
9469765 flambda-backend: Improve the semantics of asynchronous exceptions (new simpler version) (ocaml#802)
d9e4dd0 flambda-backend: Fix `make runtest` on NixOS (ocaml#874)
4bbde7a flambda-backend: Simpler symbols (ocaml#753)
ef37262 flambda-backend: Add opaqueness to Obj.magic under Flambda 2 (ocaml#862)
a9616e9 flambda-backend: Add build system hooks for ocaml-jst (ocaml#869)
045ef67 flambda-backend: Allow the compiler to build with stock Dune (ocaml#868)
3cac5be flambda-backend: Simplify Makefile logic for natdynlinkops (ocaml#866)
c5b12bf flambda-backend: Remove unnecessary install lines (ocaml#860)
ff12bbe flambda-backend: Fix unused variable warning in st_stubs.c (ocaml#861)
c84976c flambda-backend: Static check for noalloc: attributes (ocaml#825)
ca56052 flambda-backend: Build system refactoring for ocaml-jst (ocaml#857)
39eb7f9 flambda-backend: Remove integer comparison involving nonconstant polymorphic variants (ocaml#854)
c102688 flambda-backend: Fix soundness bug by using currying information from typing (ocaml#850)
6a96b61 flambda-backend: Add a primitive to enable/disable the tick thread (ocaml#852)
f64370b flambda-backend: Make Obj.dup use a new primitive, %obj_dup (ocaml#843)
9b78eb2 flambda-backend: Add test for ocaml#820 (include functor soundness bug) (ocaml#841)
8f24346 flambda-backend: Add `-dtimings-precision` flag (ocaml#833)
65c2f22 flambda-backend: Add test for ocaml#829 (ocaml#831)
7b27a49 flambda-backend: Follow-up PR#829 (comballoc fixes for locals) (ocaml#830)
ad7ec10 flambda-backend: Use a custom condition variable implementation (ocaml#787)
3ee650c flambda-backend: Fix soundness bug in include functor (ocaml#820)
2f57378 flambda-backend: Static check noalloc (ocaml#778)
aaad625 flambda-backend: Emit begin/end region only when stack allocation is enabled (ocaml#812)
17c7173 flambda-backend: Fix .cmt for included signatures (ocaml#803)
e119669 flambda-backend: Increase delays in tests/lib-threads/beat.ml (ocaml#800)
ccc356d flambda-backend: Prevent dynamic loading of the same .cmxs twice in private mode, etc. (ocaml#784)
14eb572 flambda-backend: Make local extension point equivalent to local_ expression (ocaml#790)
487d11b flambda-backend: Fix tast_iterator and tast_mapper for include functor. (ocaml#795)
a50a818 flambda-backend: Reduce closure allocation in List (ocaml#792)
96c9c60 flambda-backend: Merge ocaml-jst
a775b88 flambda-backend: Fix ocaml/otherlibs/unix 32-bit build (ocaml#767)
f7c2679 flambda-backend: Create object files internally to avoid invoking GAS (ocaml#757)
c7a46bb flambda-backend: Bugfix for Cmmgen.expr_size with locals (ocaml#756)
b337cb6 flambda-backend: Fix build_upstream for PR749 (ocaml#750)
8e7e81c flambda-backend: Differentiate is_int primitive between generic and variant-only versions (ocaml#749)

git-subtree-dir: ocaml
git-subtree-split: 25188da
EmileTrotignon pushed a commit to EmileTrotignon/ocaml that referenced this pull request Jan 12, 2024
* Remove unused mkdir_p function

* Add end of file newline

Co-authored-by: Cuihtlauac ALVARADO <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants