Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0007259OCamlmiddle end (typedtree to clambda)public2016-05-15 04:252017-10-13 20:50
Reporteromion 
Assigned Tochambart 
PrioritynormalSeverityminorReproducibilityalways
StatusresolvedResolutionfixed 
PlatformOSOS Version
Product Version4.03.0 
Target Version4.06.0 +dev/beta1/beta2/rc1Fixed in Version4.06.0 +dev/beta1/beta2/rc1 
Summary0007259: flambda does not collapse pattern matching in some cases
DescriptionIn a program I've been writing, I have a few functions which return the same field of of an inline record, no matter which of the variants are chosen. For example:

type node =
    | Branch of {parent : node; bv : int; dv : int}
    | Leaf of {parent : node; bv : int; dv : int; mutable rc : int}
let ret_p n = match n with
    | Leaf {parent} | Branch {parent} -> parent

Without flambda, my computer creates the following CMM code:
(function camlTest__ret_p_1227 (n/1228: val)
 (catch (exit 5 (load val n/1228)) with(5 parent/1229) parent/1229))

With flambda (-O3), my computer creates this:
(function camlTest__ret_p_29 (n_31/1267: val)
 (catch
   (let switcher/1283 (load unsigned int8 (+a n_31/1267 -8))
     (if (!= switcher/1283 0)
       (let staticraise_arg_37/1270 (load val n_31/1267)
         (exit 9 staticraise_arg_37/1270))
       (let staticraise_arg_35/1269 (load val n_31/1267)
         (exit 9 staticraise_arg_35/1269))))
 with(9 parent_32/1268) parent_32/1268))

Essentially, the first version sees that parent is always the first field, so it simplifies the function down to a simple pointer lookup. The second version checks the tag and loads the first field in both branches.

The issue is the same when not using inline records (other than an extra pointer load that inline records avoid), and in this case 4.02.0 seems to be the same as 4.03.0 without flambda. This issue seems to be a regression in flambda, though I don't presume to know why.
Additional InformationThere are some cases when this doesn't happen though: if no fields that after the shortest record's end are mutable, the problem goes away. That is, leaving Branch alone and adding whatever you want to Leaf won't make this happen UNLESS one of the fields after dv are mutable.

This was tested on 64-bit Mac OS-X 10.11 and 64-bit MSVC-compiled Windows 10 installs.
TagsNo tags attached.
Attached Files

- Relationships

-  Notes
(0015938)
chambart (developer)
2016-05-17 16:29

With flambda there is an intermediate let in both branches. Those have different identifiers, hence are not detected by cmmgen as equal.

When there are no mutable field, the translation from parsedtree to lambda already does the sharing.

This simple case could be fixed by some improvement in the un-anf pass to get rid of the let. A more general fix would be to do a better equality check.
(0015939)
chambart (developer)
2016-05-17 16:40

In fact this involves filling Flambda_utils.Switch_storer
(0015965)
chambart (developer)
2016-06-02 15:07

fix in https://github.com/ocaml/ocaml/pull/603 [^]

- Issue History
Date Modified Username Field Change
2016-05-15 04:25 omion New Issue
2016-05-17 16:23 chambart Assigned To => chambart
2016-05-17 16:23 chambart Status new => assigned
2016-05-17 16:29 chambart Note Added: 0015938
2016-05-17 16:40 chambart Note Added: 0015939
2016-06-02 15:07 chambart Note Added: 0015965
2016-09-07 16:48 shinwell Target Version => 4.05.0 +dev/beta1/beta2/beta3/rc1
2017-02-23 16:42 doligez Category Ocaml optimization => -Ocaml optimization
2017-02-23 17:13 doligez Category -Ocaml optimization => middle end (typedtree to clambda)
2017-06-09 11:19 doligez Target Version 4.05.0 +dev/beta1/beta2/beta3/rc1 => 4.06.0 +dev/beta1/beta2/rc1
2017-10-13 20:50 frisch Status assigned => resolved
2017-10-13 20:50 frisch Fixed in Version => 4.06.0 +dev/beta1/beta2/rc1
2017-10-13 20:50 frisch Resolution open => fixed


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker