Skip to content
Please note that GitHub no longer supports Internet Explorer.

We recommend upgrading to the latest Microsoft Edge, Google Chrome, or Firefox.

Learn more
Permalink
Browse files

Import MLIR into the LLVM tree

  • Loading branch information
joker-eph committed Dec 24, 2019
2 parents 6f635f9 + 5b4a01d commit 0f0d0ed1c78f1a80139a1f2133fad5284691a121
Showing 1,026 changed files with 226,337 additions and 0 deletions.
@@ -0,0 +1,2 @@
BasedOnStyle: LLVM
AlwaysBreakTemplateDeclarations: Yes
@@ -0,0 +1,108 @@
# MLIR project.
set(MLIR_MAIN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include ) # --src-root
set(MLIR_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include ) # --includedir
set(MLIR_TABLEGEN_EXE mlir-tblgen)

set(MLIR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(MLIR_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})

function(mlir_tablegen ofn)
tablegen(MLIR ${ARGV} "-I${MLIR_MAIN_SRC_DIR}" "-I${MLIR_INCLUDE_DIR}")
set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
PARENT_SCOPE)
endfunction()

function(add_mlir_dialect dialect dialect_doc_filename)
set(LLVM_TARGET_DEFINITIONS ${dialect}.td)
mlir_tablegen(${dialect}.h.inc -gen-op-decls)
mlir_tablegen(${dialect}.cpp.inc -gen-op-defs)
add_public_tablegen_target(MLIR${dialect}IncGen)

# Generate Dialect Documentation
set(LLVM_TARGET_DEFINITIONS ${dialect_doc_filename}.td)
tablegen(MLIR ${dialect_doc_filename}.md -gen-op-doc "-I${MLIR_MAIN_SRC_DIR}" "-I${MLIR_INCLUDE_DIR}")
set(GEN_DOC_FILE ${MLIR_BINARY_DIR}/docs/Dialects/${dialect_doc_filename}.md)
add_custom_command(
OUTPUT ${GEN_DOC_FILE}
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/${dialect_doc_filename}.md
${GEN_DOC_FILE}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${dialect_doc_filename}.md)
add_custom_target(${dialect_doc_filename}DocGen DEPENDS ${GEN_DOC_FILE})
add_dependencies(mlir-doc ${dialect_doc_filename}DocGen)
endfunction()

add_custom_target(mlir-doc)

# TODO: This is to handle the current static registration, but should be
# factored out a bit.
function(whole_archive_link target)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
set(link_flags "-L${CMAKE_BINARY_DIR}/lib ")
FOREACH(LIB ${ARGN})
string(CONCAT link_flags ${link_flags} "-Wl,-force_load ${CMAKE_BINARY_DIR}/lib/lib${LIB}.a ")
ENDFOREACH(LIB)
elseif(MSVC)
FOREACH(LIB ${ARGN})
string(CONCAT link_flags ${link_flags} "/WHOLEARCHIVE:${LIB} ")
ENDFOREACH(LIB)
else()
set(link_flags "-L${CMAKE_BINARY_DIR}/lib -Wl,--whole-archive,")
FOREACH(LIB ${ARGN})
string(CONCAT link_flags ${link_flags} "-l${LIB},")
ENDFOREACH(LIB)
string(CONCAT link_flags ${link_flags} "--no-whole-archive")
endif()
set_target_properties(${target} PROPERTIES LINK_FLAGS ${link_flags})
endfunction(whole_archive_link)

# Build the CUDA conversions and run according tests if the NVPTX backend
# is available
if ("NVPTX" IN_LIST LLVM_TARGETS_TO_BUILD)
set(MLIR_CUDA_CONVERSIONS_ENABLED 1)
else()
set(MLIR_CUDA_CONVERSIONS_ENABLED 0)
endif()

set(MLIR_CUDA_RUNNER_ENABLED 0 CACHE BOOL "Enable building the mlir CUDA runner")

include_directories( "include")
include_directories( ${MLIR_INCLUDE_DIR})

add_subdirectory(include/mlir)
add_subdirectory(lib)
add_subdirectory(tools)
add_subdirectory(unittests)
add_subdirectory(test)

if( LLVM_INCLUDE_EXAMPLES )
add_subdirectory(examples)
endif()

if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
install(DIRECTORY include/mlir include/mlir-c
DESTINATION include
COMPONENT mlir-headers
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.inc"
PATTERN "LICENSE.TXT"
)

install(DIRECTORY ${MLIR_INCLUDE_DIR}/mlir ${MLIR_INCLUDE_DIR}/mlir-c
DESTINATION include
COMPONENT mlir-headers
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.gen"
PATTERN "*.inc"
PATTERN "CMakeFiles" EXCLUDE
PATTERN "config.h" EXCLUDE
)

if (NOT LLVM_ENABLE_IDE)
add_llvm_install_targets(install-mlir-headers
DEPENDS mlir-headers
COMPONENT mlir-headers)
endif()
endif()
@@ -0,0 +1,3 @@
# Multi-Level Intermediate Representation

See [https://mlir.llvm.org/](https://mlir.llvm.org/]) for more information.
@@ -0,0 +1,64 @@
# Operation Canonicalization in MLIR

Canonicalization is an important part of compiler IR design: it makes it easier
to implement reliable compiler transformations and to reason about what is
better or worse in the code, and it forces interesting discussions about the
goals of a particular level of IR. Dan Gohman wrote
[an article](https://sunfishcode.github.io/blog/2018/10/22/Canonicalization.html)
exploring these issues; it is worth reading if you're not familiar with these
concepts.

Most compilers have canonicalization passes, and sometimes they have many
different ones (e.g. instcombine, dag combine, etc in LLVM). Because MLIR is a
multi-level IR, we can provide a single canonicalization infrastructure and
reuse it across many different IRs that it represents. This document describes
the general approach, global canonicalizations performed, and provides sections
to capture IR-specific rules for reference.

## General Design

MLIR has a single canonicalization pass, which iteratively applies
canonicalization transformations in a greedy way until the IR converges. These
transformations are defined by the operations themselves, which allows each
dialect to define its own set of operations and canonicalizations together.

Some important things to think about w.r.t. canonicalization patterns:

* Repeated applications of patterns should converge. Unstable or cyclic
rewrites will cause infinite loops in the canonicalizer.

* It is generally better to canonicalize towards operations that have fewer
uses of a value when the operands are duplicated, because some patterns only
match when a value has a single user. For example, it is generally good to
canonicalize "x + x" into "x * 2", because this reduces the number of uses
of x by one.

* It is always good to eliminate operations entirely when possible, e.g. by
folding known identities (like "x + 0 = x").

## Globally Applied Rules

These transformations are applied to all levels of IR:

* Elimination of operations that have no side effects and have no uses.

* Constant folding - e.g. "(addi 1, 2)" to "3". Constant folding hooks are
specified by operations.

* Move constant operands to commutative binary operators to the right side -
e.g. "(addi 4, x)" to "(addi x, 4)".

## Builtin Ops Canonicalizations

These transformations are applied to builtin ops:

* `constant` ops are uniqued and hoisted into the entry block of the first
parent region that is isolated from above, e.g. the entry block of a
function.
* (TODO) Merge `affine.apply` operations that directly feed each other.

## Standard Ops Canonicalizations

* Shape folding of `alloc` operations to turn dynamic dimensions into static
ones.
* Folding `memref_cast` operations into users where possible.

0 comments on commit 0f0d0ed

Please sign in to comment.
You can’t perform that action at this time.