@@ -171,21 +171,22 @@ class PartitionOp {
171171 void print (llvm::raw_ostream &os) const {
172172 switch (OpKind) {
173173 case PartitionOpKind::Assign:
174- os << " assign %%" << OpArgs[0 ] << " = %%" << OpArgs[1 ] << " \n " ;
174+ os << " assign %%" << OpArgs[0 ] << " = %%" << OpArgs[1 ];
175175 break ;
176176 case PartitionOpKind::AssignFresh:
177- os << " assign_fresh %%" << OpArgs[0 ] << " \n " ;
177+ os << " assign_fresh %%" << OpArgs[0 ];
178178 break ;
179179 case PartitionOpKind::Transfer:
180- os << " transfer %%" << OpArgs[0 ] << " \n " ;
180+ os << " transfer %%" << OpArgs[0 ];
181181 break ;
182182 case PartitionOpKind::Merge:
183- os << " merge %%" << OpArgs[0 ] << " with %%" << OpArgs[1 ] << " \n " ;
183+ os << " merge %%" << OpArgs[0 ] << " with %%" << OpArgs[1 ];
184184 break ;
185185 case PartitionOpKind::Require:
186- os << " require %%" << OpArgs[0 ] << " \n " ;
186+ os << " require %%" << OpArgs[0 ];
187187 break ;
188188 }
189+ os << " : " << *getSourceInst (true );
189190 }
190191};
191192
@@ -408,7 +409,9 @@ class Partition {
408409 [](const PartitionOp &, Element) {},
409410 ArrayRef<Element> nonconsumables = {},
410411 llvm::function_ref<void (const PartitionOp &, Element)>
411- handleConsumeNonConsumable = [](const PartitionOp &, Element) {}) {
412+ handleConsumeNonConsumable = [](const PartitionOp &, Element) {},
413+ llvm::function_ref<bool (Element)> isActorDerived = nullptr ) {
414+
412415 REGIONBASEDISOLATION_VERBOSE_LOG (llvm::dbgs () << " Applying: " ;
413416 op.print (llvm::dbgs ()));
414417 REGIONBASEDISOLATION_VERBOSE_LOG (llvm::dbgs () << " Before: " ;
@@ -444,7 +447,7 @@ class Partition {
444447 fresh_label = Region (fresh_label + 1 );
445448 canonical = false ;
446449 break ;
447- case PartitionOpKind::Transfer:
450+ case PartitionOpKind::Transfer: {
448451 assert (op.OpArgs .size () == 1 &&
449452 " Consume PartitionOp should be passed 1 argument" );
450453 assert (labels.count (op.OpArgs [0 ]) &&
@@ -464,12 +467,26 @@ class Partition {
464467 }
465468 }
466469
467- // ensure region is transferred
470+ // If this value is actor derived or if any elements in its region are
471+ // actor derived, we need to treat as non-consumable.
472+ if (isActorDerived && isActorDerived (op.OpArgs [0 ]))
473+ return handleConsumeNonConsumable (op, op.OpArgs [0 ]);
474+ Region elementRegion = labels.at (op.OpArgs [0 ]);
475+ if (llvm::any_of (labels,
476+ [&](const std::pair<Element, Region> &pair) -> bool {
477+ if (pair.second != elementRegion)
478+ return false ;
479+ return isActorDerived && isActorDerived (pair.first );
480+ }))
481+ return handleConsumeNonConsumable (op, op.OpArgs [0 ]);
482+
483+ // Ensure if the region is transferred...
468484 if (!isTransferred (op.OpArgs [0 ]))
469- // mark region as transferred
485+ // that all elements associated with the region are marked as
486+ // transferred.
470487 horizontalUpdate (labels, op.OpArgs [0 ], Region::transferred ());
471-
472488 break ;
489+ }
473490 case PartitionOpKind::Merge:
474491 assert (op.OpArgs .size () == 2 &&
475492 " Merge PartitionOp should be passed 2 arguments" );
0 commit comments