| 292 | } // namespace |
| 293 | |
| 294 | void GraphView::SetScopedAllocatorAttrs( |
| 295 | const std::vector<const Node*>& sa_nodes) { |
| 296 | for (const Node* sa : sa_nodes) { |
| 297 | NodeItem* sa_item = node(sa->id()); |
| 298 | AllocatorAttributes* sa_attrs = sa_item->output_attr_base(); |
| 299 | // Control edges out of the ScopedAllocator should be use instances, but may |
| 300 | // include a few other nodes. |
| 301 | for (const auto& e : sa->out_edges()) { |
| 302 | if (IsSink(e->dst()) || !e->IsControlEdge()) { |
| 303 | continue; |
| 304 | } |
| 305 | Node* use_node = e->dst(); |
| 306 | NodeItem* item = node(use_node->id()); |
| 307 | AllocatorAttributes* use_attrs = item->output_attr_base(); |
| 308 | std::vector<int> scoped_allocator_attrs; |
| 309 | Status s = GetNodeAttr(use_node->attrs(), "_scoped_allocator", |
| 310 | &scoped_allocator_attrs); |
| 311 | if (!s.ok()) { |
| 312 | VLOG(2) << "Failed to find expected ScopedAllocator attr on " |
| 313 | << use_node->name(); |
| 314 | continue; |
| 315 | } |
| 316 | // There can be more than one output using ScopedAllocation, but this |
| 317 | // analysis assumes they use the same ScopedAllocator. |
| 318 | for (const auto& e : use_node->out_edges()) { |
| 319 | if (IsSink(e->dst()) || !e->IsControlEdge()) { |
| 320 | AllocatorAttributes attr; |
| 321 | if (ExtractScopedAllocatorAttr(scoped_allocator_attrs, |
| 322 | e->src_output(), &attr)) { |
| 323 | // Set the scope_id on this use instance node. |
| 324 | (use_attrs + e->src_output())->Merge(attr); |
| 325 | // Propagate the other attributes of this node back to the SA node. |
| 326 | attr = *(use_attrs + e->src_output()); |
| 327 | attr.scope_id = 0; |
| 328 | sa_attrs->Merge(attr); |
| 329 | } |
| 330 | } |
| 331 | } |
| 332 | } |
| 333 | } |
| 334 | } |
| 335 | |
| 336 | namespace { |
| 337 | Status InferAllocAttr(const Node* n, const Node* dst, |
nothing calls this directly
no test coverage detected