When deduplicating unions, for each union we compare each successor
with all other successors. However, the same successor node might be
reachable by more than one edge from the parent.
This can cause problems when a node gets merged while the comparison is
still ongoing. In particular, since the comparison is done using a copy
of the successor list, to avoid iterator invalidation, the links in
the worklist are not updated when a node gets merged, causing links to
the merged node to have an invalid destination.
The fix here is to keep a list of **nodes** to visit, and a list of
**edges** that have already been visited, so that, if a node is merged
through one of its links, we are not visiting other links connected to
the same node after the merge.
Add a step that recognizes if two subtrees of a union node are
topologically equivalent and merges them. This corresponds to removing
duplicate fields in unions.
This deduplication was prevously done while emitting layouts.
A check is inserted into DLAMakeLayouts to assert that, after
constructing unions, no union has only one child, which could be the
case if we didn't deduplicate union fields in the graph.
Since the reasoning behind single child collapsing can be reused in
other points of the DLA pipeline, move the logic that acts on a single
node in a static function out of the CollapseSingleChild step.
* Inheritance straight lines are now collapsed by CollapseSingleChild
* Don't collapse if parent has more than one parent or if the child has
more than one parent
* Allow the possibility to construct single-member struct: if this
struct is inherited by many other structs, "flattening" the struct is not
the most sensible thing to do, since inheritance information is something
we want to preserve in these cases.
While doing thie, also drop `printAccessNode()` from DLA DebugPrinter.
The information about which LLVM instruction originated a given access
node is already available in the csv generated by the `dla-accesses-log`
logger.