1# RUN: %PYTHON %s 2# It is sufficient that this doesn't assert. 3 4from mlir.ir import * 5 6 7def createDetachedModule(): 8 module = Module.create() 9 with InsertionPoint(module.body): 10 # TODO: Python bindings are currently unaware that modules are also 11 # operations, so having a module erased won't trigger the cascading 12 # removal of live operations (#93337). Use a non-module operation 13 # instead. 14 nested = Operation.create("test.some_operation", regions=1) 15 16 # When the operation is detached from parent, it is considered to be 17 # owned by Python. It will therefore be erased when the Python object 18 # is destroyed. 19 nested.detach_from_parent() 20 21 # However, we create and maintain references to operations within 22 # `nested`. These references keep the corresponding operations in the 23 # "live" list even if they have been erased in C++, making them 24 # "zombie". If the C++ allocator reuses one of the address previously 25 # used for a now-"zombie" operation, this used to result in an 26 # assertion "cannot create detached operation that already exists" from 27 # the bindings code. Erasing the detached operation should result in 28 # removing all nested operations from the live list. 29 # 30 # Note that the assertion is not guaranteed since it depends on the 31 # behavior of the allocator on the C++ side, so this test mail fail 32 # intermittently. 33 with InsertionPoint(nested.regions[0].blocks.append()): 34 a = [Operation.create("test.some_other_operation") for i in range(100)] 35 return a 36 37 38def createManyDetachedModules(): 39 with Context() as ctx, Location.unknown(): 40 ctx.allow_unregistered_dialects = True 41 for j in range(100): 42 a = createDetachedModule() 43 44 45if __name__ == "__main__": 46 createManyDetachedModules() 47