19f3f6d7bSStella Laurenzo# RUN: %PYTHON %s 2>&1 | FileCheck %s
29f3f6d7bSStella Laurenzo
39f3f6d7bSStella Laurenzoimport gc, sys
49f3f6d7bSStella Laurenzofrom mlir.ir import *
59f3f6d7bSStella Laurenzofrom mlir.passmanager import *
69f3f6d7bSStella Laurenzo
79f3f6d7bSStella Laurenzo# Log everything to stderr and flush so that we have a unified stream to match
89f3f6d7bSStella Laurenzo# errors/info emitted by MLIR to stderr.
99f3f6d7bSStella Laurenzodef log(*args):
109f3f6d7bSStella Laurenzo  print(*args, file=sys.stderr)
119f3f6d7bSStella Laurenzo  sys.stderr.flush()
129f3f6d7bSStella Laurenzo
139f3f6d7bSStella Laurenzodef run(f):
149f3f6d7bSStella Laurenzo  log("\nTEST:", f.__name__)
159f3f6d7bSStella Laurenzo  f()
169f3f6d7bSStella Laurenzo  gc.collect()
179f3f6d7bSStella Laurenzo  assert Context._get_live_count() == 0
189f3f6d7bSStella Laurenzo
199f3f6d7bSStella Laurenzo# Verify capsule interop.
209f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testCapsule
219f3f6d7bSStella Laurenzodef testCapsule():
229f3f6d7bSStella Laurenzo  with Context():
239f3f6d7bSStella Laurenzo    pm = PassManager()
249f3f6d7bSStella Laurenzo    pm_capsule = pm._CAPIPtr
259f3f6d7bSStella Laurenzo    assert '"mlir.passmanager.PassManager._CAPIPtr"' in repr(pm_capsule)
269f3f6d7bSStella Laurenzo    pm._testing_release()
279f3f6d7bSStella Laurenzo    pm1 = PassManager._CAPICreate(pm_capsule)
289f3f6d7bSStella Laurenzo    assert pm1 is not None  # And does not crash.
299f3f6d7bSStella Laurenzorun(testCapsule)
309f3f6d7bSStella Laurenzo
319f3f6d7bSStella Laurenzo
329f3f6d7bSStella Laurenzo# Verify successful round-trip.
339f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testParseSuccess
349f3f6d7bSStella Laurenzodef testParseSuccess():
359f3f6d7bSStella Laurenzo  with Context():
36*5e83a5b4SStella Laurenzo    # An unregistered pass should not parse.
379f3f6d7bSStella Laurenzo    try:
38*5e83a5b4SStella Laurenzo      pm = PassManager.parse("builtin.module(func.func(not-existing-pass{json=false}))")
399f3f6d7bSStella Laurenzo      # TODO: this error should be propagate to Python but the C API does not help right now.
40*5e83a5b4SStella Laurenzo      # CHECK: error: 'not-existing-pass' does not refer to a registered pass or pass pipeline
419f3f6d7bSStella Laurenzo    except ValueError as e:
42*5e83a5b4SStella Laurenzo      # CHECK: ValueError exception: invalid pass pipeline 'builtin.module(func.func(not-existing-pass{json=false}))'.
439f3f6d7bSStella Laurenzo      log("ValueError exception:", e)
449f3f6d7bSStella Laurenzo    else:
459f3f6d7bSStella Laurenzo      log("Exception not produced")
469f3f6d7bSStella Laurenzo
47*5e83a5b4SStella Laurenzo    # A registered pass should parse successfully.
488010d7e0SOkwan Kwon    pm = PassManager.parse("builtin.module(func.func(print-op-stats{json=false}))")
498010d7e0SOkwan Kwon    # CHECK: Roundtrip: builtin.module(func.func(print-op-stats{json=false}))
509f3f6d7bSStella Laurenzo    log("Roundtrip: ", pm)
519f3f6d7bSStella Laurenzorun(testParseSuccess)
529f3f6d7bSStella Laurenzo
539f3f6d7bSStella Laurenzo# Verify failure on unregistered pass.
549f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testParseFail
559f3f6d7bSStella Laurenzodef testParseFail():
569f3f6d7bSStella Laurenzo  with Context():
579f3f6d7bSStella Laurenzo    try:
589f3f6d7bSStella Laurenzo      pm = PassManager.parse("unknown-pass")
599f3f6d7bSStella Laurenzo    except ValueError as e:
609f3f6d7bSStella Laurenzo      # CHECK: ValueError exception: invalid pass pipeline 'unknown-pass'.
619f3f6d7bSStella Laurenzo      log("ValueError exception:", e)
629f3f6d7bSStella Laurenzo    else:
639f3f6d7bSStella Laurenzo      log("Exception not produced")
649f3f6d7bSStella Laurenzorun(testParseFail)
659f3f6d7bSStella Laurenzo
669f3f6d7bSStella Laurenzo
679f3f6d7bSStella Laurenzo# Verify failure on incorrect level of nesting.
689f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testInvalidNesting
699f3f6d7bSStella Laurenzodef testInvalidNesting():
709f3f6d7bSStella Laurenzo  with Context():
719f3f6d7bSStella Laurenzo    try:
7236550692SRiver Riddle      pm = PassManager.parse("func.func(normalize-memrefs)")
739f3f6d7bSStella Laurenzo    except ValueError as e:
7436550692SRiver Riddle      # CHECK: Can't add pass 'NormalizeMemRefs' restricted to 'builtin.module' on a PassManager intended to run on 'func.func', did you intend to nest?
7536550692SRiver Riddle      # CHECK: ValueError exception: invalid pass pipeline 'func.func(normalize-memrefs)'.
769f3f6d7bSStella Laurenzo      log("ValueError exception:", e)
779f3f6d7bSStella Laurenzo    else:
789f3f6d7bSStella Laurenzo      log("Exception not produced")
799f3f6d7bSStella Laurenzorun(testInvalidNesting)
809f3f6d7bSStella Laurenzo
819f3f6d7bSStella Laurenzo
829f3f6d7bSStella Laurenzo# Verify that a pass manager can execute on IR
839f3f6d7bSStella Laurenzo# CHECK-LABEL: TEST: testRun
849f3f6d7bSStella Laurenzodef testRunPipeline():
859f3f6d7bSStella Laurenzo  with Context():
868010d7e0SOkwan Kwon    pm = PassManager.parse("print-op-stats{json=false}")
870fd3a1ceSRiver Riddle    module = Module.parse(r"""func.func @successfulParse() { return }""")
889f3f6d7bSStella Laurenzo    pm.run(module)
899f3f6d7bSStella Laurenzo# CHECK: Operations encountered:
90f8479d9dSRiver Riddle# CHECK: builtin.module    , 1
9136550692SRiver Riddle# CHECK: func.func      , 1
9223aa5a74SRiver Riddle# CHECK: func.return        , 1
939f3f6d7bSStella Laurenzorun(testRunPipeline)
94