| 369 | } // namespace |
| 370 | |
| 371 | void ContractEdge(SimpleEdge* edge, SimpleGraph* graph, |
| 372 | std::vector<const SimpleEdge*>* remove_edges) { |
| 373 | // Transfer all inputs and outputs of 'dst' to 'src' except edges |
| 374 | // connecting the two. |
| 375 | auto src = edge->src(); |
| 376 | auto dst = edge->dst(); |
| 377 | |
| 378 | // We can use '0' for input/output index because we don't need them |
| 379 | // to be accurate for the way we are using the graph. |
| 380 | std::vector<const SimpleEdge*> in_edges(dst->in_edges().begin(), |
| 381 | dst->in_edges().end()); |
| 382 | for (const SimpleEdge* in_edge : in_edges) { |
| 383 | if (in_edge->IsControlEdge()) { |
| 384 | if (in_edge->src() != src) { |
| 385 | SimpleEdge* e = const_cast<SimpleEdge*>(in_edge); |
| 386 | graph->AddControlEdge(e->src(), src); |
| 387 | } |
| 388 | } else { |
| 389 | if (in_edge->src() != src) { |
| 390 | SimpleEdge* e = const_cast<SimpleEdge*>(in_edge); |
| 391 | if (e->src() == graph->source_node()) { |
| 392 | graph->AddEdge(e->src(), e->src_output(), src, Graph::kControlSlot); |
| 393 | } else { |
| 394 | graph->AddEdge(e->src(), e->src_output(), src, 0 /* input index */); |
| 395 | } |
| 396 | } |
| 397 | } |
| 398 | } |
| 399 | |
| 400 | std::vector<const SimpleEdge*> out_edges(dst->out_edges().begin(), |
| 401 | dst->out_edges().end()); |
| 402 | for (const SimpleEdge* out_edge : out_edges) { |
| 403 | if (out_edge->IsControlEdge()) { |
| 404 | SimpleEdge* e = const_cast<SimpleEdge*>(out_edge); |
| 405 | graph->AddControlEdge(src, e->dst()); |
| 406 | } else { |
| 407 | SimpleEdge* e = const_cast<SimpleEdge*>(out_edge); |
| 408 | if (e->dst() == graph->sink_node()) { |
| 409 | VLOG(1) << " edge to sink node " << src->name() << " -> " |
| 410 | << e->dst()->name(); |
| 411 | graph->AddEdge(src, Graph::kControlSlot, e->dst(), e->dst_input()); |
| 412 | } else { |
| 413 | graph->AddEdge(src, 0 /* output index */, e->dst(), e->dst_input()); |
| 414 | } |
| 415 | } |
| 416 | } |
| 417 | |
| 418 | // Return the edges that must be removed to disconnect 'dst' from |
| 419 | // the graph. We don't actually remove 'dst' since the caller holds |
| 420 | // references to all the nodes. |
| 421 | for (const auto& in_edge : dst->in_edges()) { |
| 422 | remove_edges->push_back(in_edge); |
| 423 | } |
| 424 | for (const auto& out_edge : dst->out_edges()) { |
| 425 | remove_edges->push_back(out_edge); |
| 426 | } |
| 427 | } |
| 428 |
no test coverage detected