Commit Graph

1215 Commits

Author SHA1 Message Date
MLIR Team 11b099c012 Adds offset argument to specified range of ids know to be aligned when calling mergeAndAlignIds (used by FlatAffineConstraints).
Supports use case where FlatAffineConstraints::composeMap adds dim identifiers with no SSA values (because the identifiers are the result of an AffineValueMap which is not materialized in the IR and thus has no SSA Value results).

PiperOrigin-RevId: 237145506
2019-03-29 17:03:47 -07:00
MLIR Team 1678fd1584 Fix opt build.
PiperOrigin-RevId: 237141751
2019-03-29 17:03:32 -07:00
Uday Bondhugula b8b15c7700 Add FlatAffineConstraints::containsId to avoid using findId when position isn't
needed + other cleanup
- clean up unionBoundingBox (hoist SmallVector allocations out of loop).

PiperOrigin-RevId: 237141668
2019-03-29 17:03:17 -07:00
Nicolas Vasilache 9e425a06f7 Fix an incorrect comment in builder-api-test.
Also address post commit cleanups that were missed.

PiperOrigin-RevId: 237122077
2019-03-29 17:03:00 -07:00
Nicolas Vasilache 7c0b9e8b62 Add helper classes to declarative builders to help write end-to-end custom ops.
This CL adds the same helper classes that exist in the AST form of EDSCs to support a basic indexing notation and emit the proper load and store operations and capture MemRefViews as function arguments.

This CL also adds a wrapper class LoopNestBuilder to allow generic rank-agnostic loops over indices.

PiperOrigin-RevId: 237113755
2019-03-29 17:02:41 -07:00
Lei Zhang 4fc9b51727 [TableGen] Emit verification code for op results
They can be verified using the same logic as operands.

PiperOrigin-RevId: 237101461
2019-03-29 17:02:26 -07:00
River Riddle d43f630de8 NFC: Remove 'Result' from the analysis manager api to better reflect the implementation. There is no distinction between analysis computation and result.
PiperOrigin-RevId: 237093101
2019-03-29 17:02:12 -07:00
Dimitrios Vytiniotis 32943f5783 More graceful failure when verifying llvm.noalias.
PiperOrigin-RevId: 237081778
2019-03-29 17:01:56 -07:00
River Riddle 1d87b62afe Add support for preserving specific analyses in the analysis manager. Passes can now preserve specific analyses via 'markAnalysesPreserved'.
Example:

markAnalysesPreserved<DominanceInfo>();
markAnalysesPreserved<DominanceInfo, PostDominanceInfo>();

PiperOrigin-RevId: 237081454
2019-03-29 17:01:41 -07:00
Nicolas Vasilache b2fe39977e Hotfix for unused variable in opt mode
PiperOrigin-RevId: 237073601
2019-03-29 17:01:26 -07:00
Dimitrios Vytiniotis 480cc2b063 Using llvm.noalias attribute when generating LLVMIR.
PiperOrigin-RevId: 237063104
2019-03-29 17:01:11 -07:00
Nicolas Vasilache 421276e0d5 [EDSC] Hotfix: Avoid implicit OpPointer -> OpType* conversion
An implicit OpPointer -> OpType* conversion results in AddressSanitizer triggering a stack-use-after-scope error (which may be a false positive).
Avoid using such patterns to make life good again.

PiperOrigin-RevId: 237053863
2019-03-29 17:00:56 -07:00
Alex Zinenko 76759395f2 Python bindinds: support functions with attributes and argument attributes
Currently, Python bindings provide support for declarting and defining MLIR
functions given a list of argument and result types.  Extend the support for
both function declaration and function definition to handle optional function
attributes and function argument attributes.  Function attributes are exposed
as keyword arguments on function declaration and definition calls.  Function
argument attributes are exposed through a special object that combines the
argument type and its list of attributes.  Such objects can be passed instead
of bare types into the type declaration and definition calls.  They can be
constructed from bare types and reused in different declarations.

Note that, from the beginning, Python bindings did not pass through C bindings
to declare and define functions.  This commit keeps the direct interaction
between Python and C++.

PiperOrigin-RevId: 237047561
2019-03-29 17:00:41 -07:00
Nicolas Vasilache ee4a80bbd6 Add an eager API version for BR and COND_BR
When building unstructured control-flow there is a need to construct mlir::Block* before being able to fill them. This invites goto-style programming.

This CL introduces an alternative eager API for BR and COND_BR in which blocks are created eagerly and captured on the fly.

This allows reducing the number of calls to `BlockBuilder` from 4 to 2 in the `builder_blocks_eager` test and from 3 to 2 in the `builder_cond_branch_eager` test.

PiperOrigin-RevId: 237046114
2019-03-29 17:00:26 -07:00
Nicolas Vasilache 38f1d2d77e Add support for Branches in edsc::Builder
This CL adds support for BranchHandle and BranchBuilder that require a slightly different
abstraction since an mlir::Block is not an mlir::Value.

This CL also adds support for the BR and COND_BR instructions and the relevant tests.

PiperOrigin-RevId: 237034312
2019-03-29 17:00:09 -07:00
Nicolas Vasilache af6c3f7a63 Start a new implementation for edsc::Builder
This CL reworks the design of EDSCs from first principles.
It introduces a ValueHandle which can hold either:
1. an eagerly typed, delayed Value*
2. a precomputed Value*

A ValueHandle can be manipulated with intrinsic operations a nested within a NestedBuilder. These NestedBuilder are a more idiomatic nested builder abstraction that should feel intuitive to program in C++.

Notably, this abstraction does not require an AST to stage the construction of MLIR snippets from C++. Instead, the abstraction makes use of orderings between definition and declaration of ValueHandles and provides a NestedBuilder and a LoopBuilder helper classes to handle those orderings.

All instruction creations are meant to use the templated ValueHandle::create<> which directly calls mlir::Builder.create<>.

For now the EDSC AST and the builders live side-by-side until the C API is ported.

PiperOrigin-RevId: 237030945
2019-03-29 16:59:50 -07:00
Alex Zinenko 95949a0d09 TableGen: allow mixing attributes and operands in the Arguments DAG of Op definition
The existing implementation of the Op definition generator assumes and relies
on the fact that native Op Attributes appear after its value-based operands in
the Arguments list.  Furthermore, the same order is used in the generated
`build` function for the operation.  This is not desirable for some operations
with mandatory attributes that would want the attribute to appear upfront for
better consistency with their textual representation, for example `cmpi` would
prefer the `predicate` attribute to be foremost in the argument list.

Introduce support for using attributes and operands in the Arguments DAG in no
particular order.  This is achieved by maintaining a list of Arguments that
point to either the value or the attribute and are used to generate the `build`
method.

PiperOrigin-RevId: 237002921
2019-03-29 16:59:35 -07:00
MLIR Team c1ff9e866e Use FlatAffineConstraints::unionBoundingBox to perform slice bounds union for loop fusion pass (WIP).
Adds utility to convert slice bounds to a FlatAffineConstraints representation.
Adds utility to FlatAffineConstraints to promote loop IV symbol identifiers to dim identifiers.

PiperOrigin-RevId: 236973261
2019-03-29 16:59:21 -07:00
Uday Bondhugula 5836fae8a0 DMA generation CL flag update
- allow mem capacity to be overridden by command-line flag
- change default fast mem space to 2

PiperOrigin-RevId: 236951598
2019-03-29 16:59:05 -07:00
Uday Bondhugula 7e288e7c19 Add missing run command to fusion test cases - follow up to cl/236882988
PiperOrigin-RevId: 236947383
2019-03-29 16:58:50 -07:00
Uday Bondhugula 02af8c22df Change Pass:getFunction() to return pointer instead of ref - NFC
- change this for consistency - everything else similar takes/returns a
  Function pointer - the FuncBuilder ctor,
  Block/Value/Instruction::getFunction(), etc.
- saves a whole bunch of &s everywhere

PiperOrigin-RevId: 236928761
2019-03-29 16:58:35 -07:00
River Riddle 73e0297d36 Change the TensorFlow attribute prefix from "tf$" to "tf." to match the specification of dialect attributes. This also fixes tblgen generation of dialect attributes that used the sugared name "tf$attr" as c++ identifiers.
PiperOrigin-RevId: 236924392
2019-03-29 16:58:20 -07:00
River Riddle 7b0b344c5e Add a unittests directory for MLIR and start adding tests for OperandStorage from InstructionSupport.h.
PiperOrigin-RevId: 236911640
2019-03-29 16:58:05 -07:00
River Riddle 89d42f15a7 NFC: Move OperandStorage into a new header file for instruction support utilities, InstructionSupport.h.
PiperOrigin-RevId: 236892857
2019-03-29 16:57:50 -07:00
Uday Bondhugula b34f8d3c83 Fix and improve detectAsMod
- fix for the mod detection
- simplify/avoid the mod at construction (if the dividend is already known to be less
  than the divisor), since the information is available at hand there

PiperOrigin-RevId: 236882988
2019-03-29 16:57:36 -07:00
Nicolas Vasilache 069c818f40 Fix lower/upper bound mismatch in stripmineSink
Also beef up the corresponding test case.

PiperOrigin-RevId: 236878818
2019-03-29 16:57:21 -07:00
River Riddle 2dfefdafea Fix dialect attribute hooks so that they accept a NamedAttribute instead of an Attribute.
PiperOrigin-RevId: 236869321
2019-03-29 16:57:05 -07:00
Alex Zinenko dd75675080 TableGen: fix builder generation for optional attributes
The recently introduced support for generating MLIR Operations with optional
attributes did not handle the formatted string emission properly, in particular
it did not escape `{` and `}` in calls to `formatv` leading to assertions
during TableGen op definition generation.  Fix this by splitting out the
unncessary braces from the format string.  Additionally, fix the emission of
the builder argument comment to correctly indicate which attributes are indeed
optional and which are not.

PiperOrigin-RevId: 236832230
2019-03-29 16:56:50 -07:00
Uday Bondhugula a77734e185 Make sure that fusion test cases don't have out of bounds accesses
- fix out of bounds test case
- -memref-bound-check on the test/Transforms/loop-fusion.mlir no longer reports any
  errors, before or after -loop-fusion is run

PiperOrigin-RevId: 236757658
2019-03-29 16:56:35 -07:00
MLIR Team 39a1ddeb1c Adds loop attribute as a temporary work around to prevent slice fusion of loop nests containing instructions with side effects (the proper solution will be do use memref read/write regions in the future).
PiperOrigin-RevId: 236733739
2019-03-29 16:56:20 -07:00
Uday Bondhugula 12b9dece8d Bug fix for getConstantBoundOnDimSize
- this was detected when memref-bound-check was run on the output of the
  loop-fusion pass
- the addition (to represent ceildiv as a floordiv) had to be performed only
  for the constant term of the constraint
- update test cases
- memref-bound-check no longer returns an error on the output of this test case

PiperOrigin-RevId: 236731137
2019-03-29 16:56:06 -07:00
Dimitrios Vytiniotis a60ba7d908 Supporting conversion of argument attributes along their types.
This fixes a bug: previously, during conversion function argument
attributes were neither beings passed through nor converted. This fix
extends DialectConversion to allow for simultaneous conversion of the
function type and the argument attributes.

This was important when lowering MLIR to LLVM where attribute
information (e.g. noalias) needs to be preserved in MLIR(LLVMDialect).

Longer run it seems reasonable that we want to convert both the
function attribute and its type and the argument attributes, but that
requires a small refactoring in Function.h to aggregate these three
fields in an inner struct, which will require some discussion.

PiperOrigin-RevId: 236709409
2019-03-29 16:55:51 -07:00
River Riddle 50efe0fc85 Add a 'verifyPasses' flag to the PassManager that specifies if the IR should be verified after each pass. This also adds a "verify-each" flag to mlir-opt to optionally disable running the verifier after each pass.
PiperOrigin-RevId: 236703760
2019-03-29 16:55:35 -07:00
MLIR Team d42ef78a75 Handle MemRefRegion::compute return value in loop fusion pass (NFC).
PiperOrigin-RevId: 236685849
2019-03-29 16:55:20 -07:00
River Riddle a495f960e0 Introduce the notion of dialect attributes and dependent attributes. A dialect attribute derives its context from a specific dialect, whereas a dependent attribute derives context from what it is attached to. Following this, we now enforce that functions and function arguments may only contain dialect specific attributes. These are generic entities and cannot provide any specific context for a dependent attribute.
Dialect attributes are defined as:

        dialect-namespace `.` attr-name `:` attribute-value

Dialects can override any of the following hooks to verify the validity of a given attribute:
  * verifyFunctionAttribute
  * verifyFunctionArgAttribute
  * verifyInstructionAttribute

PiperOrigin-RevId: 236507970
2019-03-29 16:55:05 -07:00
River Riddle 485746f524 Implement the initial AnalysisManagement infrastructure, with the introduction of the FunctionAnalysisManager and ModuleAnalysisManager classes. These classes provide analysis computation, caching, and invalidation for a specific IR unit. The invalidation is currently limited to either all or none, i.e. you cannot yet preserve specific analyses.
An analysis can be any class, but it must provide the following:
* A constructor for a given IR unit.

struct MyAnalysis {
  // Compute this analysis with the provided module.
  MyAnalysis(Module *module);
};

Analyses can be accessed from a Pass by calling either the 'getAnalysisResult<AnalysisT>' or 'getCachedAnalysisResult<AnalysisT>' methods. A FunctionPass may query for a cached analysis on the parent module with 'getCachedModuleAnalysisResult'. Similary, a ModulePass may query an analysis, it doesn't need to be cached, on a child function with 'getFunctionAnalysisResult'.

By default, when running a pass all cached analyses are set to be invalidated. If no transformation was performed, a pass can use the method 'markAllAnalysesPreserved' to preserve all analysis results. As noted above, preserving specific analyses is not yet supported.

PiperOrigin-RevId: 236505642
2019-03-29 16:54:50 -07:00
Mehdi Amini c1b02a17be Add an assertion on the builder to ensure that a block is set before creating an operation
This is more friendly for the user than a raw segfault

PiperOrigin-RevId: 236504102
2019-03-29 16:54:35 -07:00
River Riddle eeeef090ef Set the namespace of the StandardOps dialect to "std", but add a special case to the parser to allow parsing standard operations without the "std" prefix. This will now allow for the standard dialect to be looked up dynamically by name.
PiperOrigin-RevId: 236493865
2019-03-29 16:54:20 -07:00
Uday Bondhugula eee85361bb Remove hidden flag from fusion CL options
PiperOrigin-RevId: 236409185
2019-03-29 16:54:05 -07:00
Uday Bondhugula 62e3e2c57c Update addSliceBounds to deal with loops with floor's/mod's.
- This change only impacts the cost model for fusion, given the way
  addSliceBounds was being used. It so happens that the output in spite of this
  CL's fix is the same; however, the assertions added no longer fail. (an
  invalid/inconsistent memref region was being used earlier).

PiperOrigin-RevId: 236405030
2019-03-29 16:53:50 -07:00
River Riddle f37651c708 NFC. Move all of the remaining operations left in BuiltinOps to StandardOps. The only thing left in BuiltinOps are the core MLIR types. The standard types can't be moved because they are referenced within the IR directory, e.g. in things like Builder.
PiperOrigin-RevId: 236403665
2019-03-29 16:53:35 -07:00
Lei Zhang 85d9b6c8f7 Use consistent names for dialect op source files
This CL changes dialect op source files (.h, .cpp, .td) to follow the following
convention:

  <full-dialect-name>/<dialect-namespace>Ops.{h|cpp|td}

Builtin and standard dialects are specially treated, though. Both of them do
not have dialect namespace; the former is still named as BuiltinOps.* and the
latter is named as Ops.*.

Purely mechanical. NFC.

PiperOrigin-RevId: 236371358
2019-03-29 16:53:19 -07:00
Uday Bondhugula 8254aabd4a A simple pass to detect and mark all parallel loops
- detect all parallel loops based on dep information and mark them with a
  "parallel" attribute
- add mlir::isLoopParallel(OpPointer<AffineForOp> ...), and refactor an existing method
  to use that (reuse some code from @andydavis (cl/236007073) for this)
- a simple/meaningful way to test memref dep test as well

Ex:

$ mlir-opt -detect-parallel test/Transforms/parallelism-detection.mlir
#map1 = ()[s0] -> (s0)
func @foo(%arg0: index) {
  %0 = alloc() : memref<1024x1024xvector<64xf32>>
  %1 = alloc() : memref<1024x1024xvector<64xf32>>
  %2 = alloc() : memref<1024x1024xvector<64xf32>>
  for %i0 = 0 to %arg0 {
    for %i1 = 0 to %arg0 {
      for %i2 = 0 to %arg0 {
        %3 = load %0[%i0, %i2] : memref<1024x1024xvector<64xf32>>
        %4 = load %1[%i2, %i1] : memref<1024x1024xvector<64xf32>>
        %5 = load %2[%i0, %i1] : memref<1024x1024xvector<64xf32>>
        %6 = mulf %3, %4 : vector<64xf32>
        %7 = addf %5, %6 : vector<64xf32>
        store %7, %2[%i0, %i1] : memref<1024x1024xvector<64xf32>>
      } {parallel: false}
    } {parallel: true}
  } {parallel: true}
  return
}

PiperOrigin-RevId: 236367368
2019-03-29 16:53:03 -07:00
MLIR Team d038e34735 Loop fusion for input reuse.
*) Breaks fusion pass into multiple sub passes over nodes in data dependence graph:
- first pass fuses single-use producers into their unique consumer.
- second pass enables fusing for input-reuse by fusing sibling nodes which read from the same memref, but which do not share dependence edges.
- third pass fuses remaining producers into their consumers (Note that the sibling fusion pass may have transformed a producer with multiple uses into a single-use producer).
*) Fusion for input reuse is enabled by computing a sibling node slice using the load/load accesses to the same memref, and fusion safety is guaranteed by checking that the sibling node memref write region (to a different memref) is preserved.
*) Enables output vector and output matrix computations from KFAC patches-second-moment operation to fuse into a single loop nest and reuse input from the image patches operation.
*) Adds a generic loop utilitiy for finding all sequential loops in a loop nest.
*) Adds and updates unit tests.

PiperOrigin-RevId: 236350987
2019-03-29 16:52:35 -07:00
River Riddle 269c872ee8 Add support for parsing and printing affine.if and affine.for attributes. The attribute dictionaries are printed after the final block list for both operations:
for %i = 0 to 10 {
     ...
  } {some_attr: true}

  if () : () () {
    ...
  } {some_attr: true}

  if () : () () {
    ...
  } else {
    ...
  } {some_attr: true}

PiperOrigin-RevId: 236346983
2019-03-29 16:52:19 -07:00
Uday Bondhugula 932e4fb29f Analysis support for floordiv/mod's in loop bounds/
- handle floordiv/mod's in loop bounds for all analysis purposes
- allows fusion slicing to be more powerful
- add simple test cases based on -memref-bound-check
- fusion based test cases in follow up CLs

PiperOrigin-RevId: 236328551
2019-03-29 16:52:04 -07:00
Uday Bondhugula 6ef5fc582e Method to align/merge dimensional/symbolic identifiers between two FlatAffineConstraints
- add a method to merge and align the spaces (identifiers) of two
  FlatAffineConstraints (both get dimension-wise and symbol-wise unique
  columns)
- this completes several TODOs, gets rid of previous assumptions/restrictions
  in composeMap, unionBoundingBox, and reuses common code
- remove previous workarounds / duplicated funcitonality in
  FlatAffineConstraints::composeMap and unionBoundingBox, use mergeAlignIds
  from both

PiperOrigin-RevId: 236320581
2019-03-29 16:51:47 -07:00
Alex Zinenko 4bd5d28391 EDSC bindings: expose generic Op construction interface
EDSC Expressions can now be used to build arbitrary MLIR operations identified
by their canonical name, i.e. the name obtained from
`OpClass::getOperationName()` for registered operations.  Expose this
functionality to the C API and Python bindings.  This exposes builder-level
interface to Python and avoids the need for experimental Python code to
implement EDSC free function calls for constructing each op type.

This modification required exposing mlir::Attribute to the C API and Python
bindings, which only supports integer attributes for now.

This is step 4/n to making EDSCs more generalizable.

PiperOrigin-RevId: 236306776
2019-03-29 16:51:32 -07:00
Uday Bondhugula 229bd9ba21 Use Instruction::isBeforeInBlock instead of a linear scan
- use Instruction::isBeforeInBlock instead of a linear scan in
  AffineAnalysis.cpp

PiperOrigin-RevId: 236235824
2019-03-29 16:51:16 -07:00
River Riddle ddc6788cc7 Provide a Builder::getNamedAttr and (Instruction|Function)::setAttr(StringRef, Attribute) to simplify attribute manipulation.
PiperOrigin-RevId: 236222504
2019-03-29 16:50:59 -07:00