Skip to content

Latest commit

 

History

History
120 lines (86 loc) · 3.94 KB

README-mlir.md

File metadata and controls

120 lines (86 loc) · 3.94 KB

Knossos MLIR libraries

This tree aims to implement two libraries: a Knossos file reader that emits MLIR, and an API providing introspection into an MLIR graph for heuristics search.

MLIR back-end

The MLIR back-end parsers Knossos IR and emits MLIR using as much as possible of the MLIR core/affine/linalg dialects.

This back-end prints out an MLIR graph (text, binary) when requested, or it feeds into the introspection API library for further processing.

The library should also be able to import MLIR graphs, for round-trip testing and interacting with other MLIR tools.

Partial implementation. See TODO below.

MLIR Heuristics Introspection Engine

Provides a stable way to query MLIR graphs for the purpose of heuristics searches. We may need a Knossos-specific dialect.

If we do, we'll need to be able to annotate generic MLIR graph with Knossos dialect, as well as read Knossos IR into MLIR into that dialect.

Not implemented yet.

Knossos MLIR Dialect

This is a stub for the Knossos MLIR dialect along with a tool to operate on that dialect.

We may in the future decide to use the Rise dialect. But the decision should be orthogonal with the decision to use the Elevate rewrite description on either dialect.

Building Ksc-MLIR

This setup assumes that you have built a specific checkout of LLVM and MLIR in $BUILD_DIR. See instructions below.

To build and launch the tests, run

# Prepare
$ cd <<path/to/knossos-ksc>>
$ cp user.cmake.template user.cmake
EDIT user.cmake to add path to LLVM
$ mkdir -p build && cd build

# Build
$ cmake -G Ninja ..
$ ninja ksc-mlir

# Test
$ ninja check-ksc

# Use
$ ./bin/ksc-mlir TEST -vvv # Runs the unit tests
$ ./bin/ksc-mlir AST foo.ks # Spits out AST
$ ./bin/ksc-mlir MLIR foo.ks # Spits out MLIR
$ ./bin/ksc-mlir LLVM foo.ks # Spits out LLVM IR
$ lli foo.ll ; echo $? # Run llvm and echo exit code

Tested with:

  • Compilers: Clang 6 and 9, GCC 7.4 and 9.2
  • Linkers: GNU and LLD
  • OS: Ubuntu 18 and 19

Should work with any compiler, linker and OS LLVM works with.

Building LLVM/MLIR

See https://mlir.llvm.org/getting_started for more, but this is a useful summary. Note that you need to checkout the right commit as below.

# Prepare
$ apt install clang ninja-build cmake lld
$ git clone git@github.com:llvm/llvm-project.git

# Make sure you got the right commit
# Be sure to update this line when that changes
$ KNOSSOS=<<path to knossos>>
$ cd llvm-project
$ git checkout -b ksc `cat $KNOSSOS/etc/llvm-branch.txt`

$ mkdir -p build && cd build

# Build
$ . $KNOSSOS/mlir/run-cmake-in-llvm.sh
$ ninja check-mlir

Implementation Details

The Lexer/Tokeniser creates two different kinds of tokens: values and non-values. This is consistent with existing continuation compilers.

The expected sequence of value and non-value tokens and the token's value will determine which kind of AST node we're parsing.

The Parser reads the Token tree and creates the AST, which is then used by the MLIR back end to generate a module. The module can be optimised and LLVM IR generated from it.

In the future, the heuristics engine will use the MLIR module to optimise the graph, and there will be the option of either running the result in a JIT or lowering to specific hardware.

Back-end TODO:

  • Add support for local variables (context) & finish Knossos IR support.
  • Run through multiple Ksc examples, add FileCheck validation.

Engine TODO:

  • Cost Model: liveness analysis, target-specific hooks, PGO, etc.
  • Navigation: find users/ops, dominance analysis, control flow, patterns, etc.
  • Rewrite dialect: known transformations representation, heuristics costs.
  • Heuristics: query/add/change heuristics values based on cost and predictions.
  • Traversal: allows sub-trees to be selected, pruned, cloned, modified, etc.
  • Lowering: either to a JIT execution engine or to specific hardware languages.