diff --git a/xdsl/utils/exceptions.py b/xdsl/utils/exceptions.py index d3c15d99fa..b4dcac24f3 100644 --- a/xdsl/utils/exceptions.py +++ b/xdsl/utils/exceptions.py @@ -39,6 +39,23 @@ class InvalidIRException(Exception): pass +class ShrinkException(Exception): + """ + Exception used for shrinking purposes. + + When using DRMacIver's [Shrink Ray](https://github.com/DRMacIver/shrinkray) library, + this exception can be used to reduce test cases. For example, to find a smaller + version of a case that has some behavior you are interested in, raise this exception + on the line of code you want to hit, and pass the `--shrink` argument to `xdsl-opt`. + + To shrink a test case that raises a ShrinkException when called like this: + `xdsl-opt input_file.mlir -p my,pass,pipeline`, it needs to be changed to: + `shrinkray "xdsl-opt -p my,pass,pipeline --shrink" input_file.mlir`. + """ + + pass + + class InterpretationError(Exception): """ An error that can be raised during interpretation, or Interpreter setup. diff --git a/xdsl/xdsl_opt_main.py b/xdsl/xdsl_opt_main.py index b92b8e9991..0fc480b51a 100644 --- a/xdsl/xdsl_opt_main.py +++ b/xdsl/xdsl_opt_main.py @@ -13,7 +13,7 @@ from xdsl.printer import Printer from xdsl.tools.command_line_tool import CommandLineTool from xdsl.transforms import get_all_passes -from xdsl.utils.exceptions import DiagnosticException +from xdsl.utils.exceptions import DiagnosticException, ShrinkException from xdsl.utils.parse_pipeline import parse_pipeline @@ -75,9 +75,18 @@ def run(self): output_stream.flush() finally: chunk.close() + except ShrinkException: + assert self.args.shrink + print("Success, can shrink") + # Exit with value 0 to let shrinkray know that it can shrink + exit(0) finally: if output_stream is not sys.stdout: output_stream.close() + if self.args.shrink: + print("Failure, can't shrink") + # Exit with non-0 value to let shrinkray know that it cannot shrink + exit(1) def register_all_arguments(self, arg_parser: argparse.ArgumentParser): """ @@ -171,6 +180,13 @@ def register_all_arguments(self, arg_parser: argparse.ArgumentParser): version=f"xdsl-opt built from xdsl version {version('xdsl')}\n", ) + arg_parser.add_argument( + "--shrink", + default=False, + action="store_true", + help="Return success on exit if ShrinkException was raised.", + ) + def register_pass( self, pass_name: str, pass_factory: Callable[[], type[ModulePass]] ):