Files
clang-p2996/mlir/test/python/ir/blocks.py
Rahul Kayaith 514dddbeba [mlir][python] Allow specifying block arg locations
Currently blocks are always created with UnknownLoc's for their arguments. This
adds an `arg_locs` argument to all block creation APIs, which takes an optional
sequence of locations to use, one per block argument. If no locations are
supplied, the current Location context is used.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D150084
2023-05-24 21:55:51 -04:00

141 lines
4.6 KiB
Python

# RUN: %PYTHON %s | FileCheck %s
import gc
import io
import itertools
from mlir.ir import *
from mlir.dialects import builtin
from mlir.dialects import cf
from mlir.dialects import func
def run(f):
print("\nTEST:", f.__name__)
f()
gc.collect()
assert Context._get_live_count() == 0
return f
# CHECK-LABEL: TEST: testBlockCreation
# CHECK: func @test(%[[ARG0:.*]]: i32 loc("arg0"), %[[ARG1:.*]]: i16 loc("arg1"))
# CHECK: cf.br ^bb1(%[[ARG1]] : i16)
# CHECK: ^bb1(%[[PHI0:.*]]: i16 loc("middle")):
# CHECK: cf.br ^bb2(%[[ARG0]] : i32)
# CHECK: ^bb2(%[[PHI1:.*]]: i32 loc("successor")):
# CHECK: return
@run
def testBlockCreation():
with Context() as ctx, Location.unknown():
module = builtin.ModuleOp()
with InsertionPoint(module.body):
f_type = FunctionType.get(
[IntegerType.get_signless(32),
IntegerType.get_signless(16)], [])
f_op = func.FuncOp("test", f_type)
entry_block = f_op.add_entry_block([Location.name("arg0"), Location.name("arg1")])
i32_arg, i16_arg = entry_block.arguments
successor_block = entry_block.create_after(i32_arg.type, arg_locs=[Location.name("successor")])
with InsertionPoint(successor_block) as successor_ip:
assert successor_ip.block == successor_block
func.ReturnOp([])
middle_block = successor_block.create_before(i16_arg.type, arg_locs=[Location.name("middle")])
with InsertionPoint(entry_block) as entry_ip:
assert entry_ip.block == entry_block
cf.BranchOp([i16_arg], dest=middle_block)
with InsertionPoint(middle_block) as middle_ip:
assert middle_ip.block == middle_block
cf.BranchOp([i32_arg], dest=successor_block)
module.print(enable_debug_info=True)
# Ensure region back references are coherent.
assert entry_block.region == middle_block.region == successor_block.region
# CHECK-LABEL: TEST: testBlockCreationArgLocs
@run
def testBlockCreationArgLocs():
with Context() as ctx:
ctx.allow_unregistered_dialects = True
f32 = F32Type.get()
op = Operation.create("test", regions=1, loc=Location.unknown())
blocks = op.regions[0].blocks
with Location.name("default_loc"):
blocks.append(f32)
blocks.append()
# CHECK: ^bb0(%{{.+}}: f32 loc("default_loc")):
# CHECK-NEXT: ^bb1:
op.print(enable_debug_info=True)
try:
blocks.append(f32)
except RuntimeError as err:
# CHECK: Missing loc: An MLIR function requires a Location but none was provided
print("Missing loc:", err)
try:
blocks.append(f32, f32, arg_locs=[Location.unknown()])
except ValueError as err:
# CHECK: Wrong loc count: Expected 2 locations, got: 1
print("Wrong loc count:", err)
# CHECK-LABEL: TEST: testFirstBlockCreation
# CHECK: func @test(%{{.*}}: f32 loc("arg_loc"))
# CHECK: return
@run
def testFirstBlockCreation():
with Context() as ctx, Location.unknown():
module = builtin.ModuleOp()
f32 = F32Type.get()
with InsertionPoint(module.body):
f = func.FuncOp("test", ([f32], []))
entry_block = Block.create_at_start(f.operation.regions[0],
[f32], [Location.name("arg_loc")])
with InsertionPoint(entry_block):
func.ReturnOp([])
module.print(enable_debug_info=True)
assert module.verify()
assert f.body.blocks[0] == entry_block
# CHECK-LABEL: TEST: testBlockMove
# CHECK: %0 = "realop"() ({
# CHECK: ^bb0([[ARG0:%.+]]: f32):
# CHECK: "ret"([[ARG0]]) : (f32) -> ()
# CHECK: }) : () -> f32
@run
def testBlockMove():
with Context() as ctx, Location.unknown():
ctx.allow_unregistered_dialects = True
module = Module.create()
f32 = F32Type.get()
with InsertionPoint(module.body):
dummy = Operation.create("dummy", regions=1)
block = Block.create_at_start(dummy.operation.regions[0], [f32])
with InsertionPoint(block):
ret_op = Operation.create("ret", operands=[block.arguments[0]])
realop = Operation.create("realop",
results=[r.type for r in ret_op.operands],
regions=1)
block.append_to(realop.operation.regions[0])
dummy.operation.erase()
print(module)
# CHECK-LABEL: TEST: testBlockHash
@run
def testBlockHash():
with Context() as ctx, Location.unknown():
ctx.allow_unregistered_dialects = True
module = Module.create()
f32 = F32Type.get()
with InsertionPoint(module.body):
dummy = Operation.create("dummy", regions=1)
block1 = Block.create_at_start(dummy.operation.regions[0], [f32])
block2 = Block.create_at_start(dummy.operation.regions[0], [f32])
assert hash(block1) != hash(block2)