Skip to content

Latest commit

 

History

History
121 lines (89 loc) · 5.1 KB

File metadata and controls

121 lines (89 loc) · 5.1 KB

muxc

muxc is a compiler pass pipeline testing tool, similar to opt and veczc. It takes in a pipeline of passes in textual form, creates a pipeline and runs those passes on a LLVM IR module.

It can either work per target or use the default set of utility passes. Target-specific execution requires the use of --device/--device-idx. Targets can support additional pass parsing and debug names as explained in Supporting muxc passes in targets.

The tool assumes that all targets provide a compiler interface which creates a derived class from compiler::BaseModule when creating the Module from the Target interface.

The LLVM IR module may passed directly to the tool or may be compiled from OpenCL C using compiler::BaseModule's APIs; this requires a target to work.

Executing muxc

Its most common usage requires the following arguments:

  • <input_filename>. Default is '-' (stdin).
  • --passes <pipeline_text> - pass pipeline. Optional. Default is "".
  • -o <output_filename>. Default is '-' (stdout).
  • --device <device_name> or --device-idx <device_idx> - target-specific device to run on. Optional.

The input can be an LLVM IR module or an OpenCL C kernel (see below). The file type is automatically worked out by the filename extension, but LLVM IR is assumed. The input file type can be specifically controlled by passing -x ir for IR or -x cl for OpenCL C.

The --passes <pipeline_text> option allows passes separated by a comma (,). These passes include standard LLVM passes, such as instcombine. Parameters for such passes are included inside <> and generally have default values. For example, link-builtins or link-builtins<early>.

Additionally, several standard LLVM command line arguments for tools such opt can be used.

The --device option is only required if target-specific testing is needed, either to set the LLVM target triple or to register pass information. This is also required in order for the tool to accept OpenCL C inputs.

Examples of running on LLVM IR modules:

> # Run instcombine on a textual LLVM module.
> muxc --passes instcombine test.ll
> # Run instcombine,simplifycfg on a bitcode LLVM module,
> # saving the result to a new textual file.
> muxc --passes instcombine,simplifycfg test.bc -o output.ll
> # Run instcombine,simplifycfg on a bitcode LLVM module,
> # saving the result to a new bitcode file.
> muxc --passes instcombine,simplifycfg test.bc --filetype obj -o output.bc

> # Pipe a program from stdin and run no passes on it (pass-through)
> echo 'define i32 @foo() { ret i32 0 }' | muxc

> # Run a refsi-specific compiler pass
> muxc --device "RefSi G1 RV64" --passes ir-to-builtins < test.ll

> # Run a compiler pass with options on the first known device
> muxc --device-idx 0 --passes link-builtins < test.ll
> muxc --device-idx 0 --passes "link-builtins<early>" < test.ll

> # Run instcombine, logging its debug output to stderr (requires a debug
> # build of LLVM).
> muxc --passes instcombine --debug test.ll

Examples of compiling OpenCL C (requires a known device):

> # Compile an OpenCL C kernel to IR, printing it to stdout.
> muxc --device-idx 0 kernel.cl

> # Compile an OpenCL C kernel to IR, providing compiler options
> muxc --device-idx 0 -cl-options '-cl-fast-relaxed-math' kernel.cl

> # Compile an OpenCL C kernel from stdin to IR
> echo 'kernel void foo() { }' | muxc --device-idx 0 -x cl

> # Compile an OpenCL C kernel to IR and run instcombine on it
> muxc --device-idx 0 --passes instcombine kernel.cl

Other useful options include:

  • --list-devices - list all known devices.
  • --print-passes - print available passes that can be specified in --passes=foo.

All of the passes available to opt are available as well as those shown using --print-passes.

A full list of options can be found by passing --help to muxc.

Supporting muxc passes in targets

ComputeMux targets provide an interface to muxc through the PassMachinery class. Specifically, the interface needed is based off the virtual function in BaseModule, createPassMachinery(). The default for this in BaseModule creates a BaseModulePassMachinery. This implements the parse and debug name support for the majority of utility passes that the oneAPI Construction Kit provides. This method should always be overridden even if a BaseModulePassMachinery is used so that a TargetMachine appropriate to the target can be attached to the PassMachinery during creation.

In order to extend for target specific passes, the virtual function createPassMachinery() should create a PassMachinery derived from BaseModulePassMachinery. The PassMachinery created should have the methods registerPassCallbacks and addClassToPassName overridden to support parsing and debug names for the target passes. Note that these methods should still call the BaseModulePassMachinery methods in order to ensure that the util passes are available.