[repacker] recursively duplicate nodes during isolation.

If a node is duplicated during isolation then any children it has will have incoming links from outside the subgraph (from the duplicated node and the original node), so they must be duplicated too.
This commit is contained in:
Garret Rieger 2021-09-08 13:44:25 -07:00
parent 41bbf2812e
commit 7147f169d6
1 changed files with 18 additions and 2 deletions

View File

@ -364,11 +364,11 @@ struct graph_t
const auto& node = vertices_[entry.first]; const auto& node = vertices_[entry.first];
unsigned subgraph_incoming_edges = entry.second; unsigned subgraph_incoming_edges = entry.second;
if (entry.first != root_idx && subgraph_incoming_edges < node.incoming_edges) if (subgraph_incoming_edges < node.incoming_edges)
{ {
// Only de-dup objects with incoming links from outside the subgraph. // Only de-dup objects with incoming links from outside the subgraph.
made_changes = true; made_changes = true;
index_map.set (entry.first, duplicate (entry.first)); duplicate_subgraph (entry.first, index_map);
} }
} }
@ -392,6 +392,22 @@ struct graph_t
find_subgraph (link.objidx, subgraph); find_subgraph (link.objidx, subgraph);
} }
/*
* duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign
* links. index_map is updated with mappings from old id to new id. If a duplication has already
* been performed for a given index, then it will be skipped.
*/
void duplicate_subgraph (unsigned node_idx, hb_hashmap_t<unsigned, unsigned>& index_map)
{
if (index_map.has (node_idx))
return;
index_map.set (node_idx, duplicate (node_idx));
for (const auto& l : object (node_idx).links) {
duplicate_subgraph (l.objidx, index_map);
}
}
/* /*
* Creates a copy of node_idx and returns it's new index. * Creates a copy of node_idx and returns it's new index.
*/ */