Commit Graph

804 Commits

Author SHA1 Message Date
MLIR Team 5c5739d42b Change the dependence check in the loop fusion pass to use the MLIR instruction list ordering (instead of the dependence graph node id ordering). This breaks the overloading of dependence graph node ids as both edge endpoints and instruction list position.
PiperOrigin-RevId: 230849232
2019-03-29 15:35:53 -07:00
Uday Bondhugula f94b15c247 Update dma-generate: update for multiple load/store op's per memref
- introduce a way to compute union using symbolic rectangular bounding boxes
- handle multiple load/store op's to the same memref by taking a union of the regions
- command-line argument to provide capacity of the fast memory space
- minor change to replaceAllMemRefUsesWith to not generate affine_apply if the
  supplied index remap was identity

PiperOrigin-RevId: 230848185
2019-03-29 15:35:38 -07:00
River Riddle 4a7dfa7882 Add order bit to instructions to lazily track dominance queries. This improves the performance of dominance queries, which are used quite often within the compiler(especially within the verifier).
This reduced the execution time of a few internal tests from ~2 minutes to ~4 seconds.

PiperOrigin-RevId: 230819723
2019-03-29 15:35:23 -07:00
Uday Bondhugula 06d21d9f64 loop-fusion: debug info cleanup
PiperOrigin-RevId: 230817383
2019-03-29 15:35:08 -07:00
Chris Lattner 934b6d125f Introduce a new operation hook point for implementing simple local
canonicalizations of operations.  The ultimate important user of this is
going to be a funcBuilder->foldOrCreate<YourOp>(...) API, but for now it
is just a more convenient way to write certain classes of canonicalizations
(see the change in StandardOps.cpp).

NFC.

PiperOrigin-RevId: 230770021
2019-03-29 15:34:35 -07:00
River Riddle 451869f394 Add cloning functionality to Block and Function, this also adds support for remapping successor block operands of terminator operations. We define a new BlockAndValueMapping class to simplify mapping between cloned values.
PiperOrigin-RevId: 230768759
2019-03-29 15:34:20 -07:00
Uday Bondhugula 72e5c7f428 Minor updates + cleanup to dma-generate
- switch some debug info to emitError
- use a single constant op for zero index to make it easier to write/update
  test cases; avoid creating new constant op's for common zero index cases
- test case cleanup

This is in preparation for an upcoming major update to this pass.

PiperOrigin-RevId: 230728379
2019-03-29 15:34:06 -07:00
River Riddle f319bbbd28 Add a function pass to strip debug info from functions and instructions.
PiperOrigin-RevId: 230654315
2019-03-29 15:33:50 -07:00
River Riddle 98c729d6f1 Change trailing locations printing to also print unknown locations. This will allow for truly round tripping debug locations given that we assign locations while parsing IR.
PiperOrigin-RevId: 230627191
2019-03-29 15:33:35 -07:00
River Riddle 6859f33292 Migrate VectorOrTensorType/MemRefType shape api to use int64_t instead of int.
PiperOrigin-RevId: 230605756
2019-03-29 15:33:20 -07:00
Feng Liu b64998a6b3 Add a method to construct a CallSiteLoc which represents a stack of locations.
PiperOrigin-RevId: 230592860
2019-03-29 15:33:05 -07:00
River Riddle 1210e92d86 Add asmparser/printer support for locations to make them round-trippable. Location printing is currently behind a command line flag "mlir-print-debuginfo", we can rethink this when we have a pass for stripping debug info or when we have support for printer flags.
Example inline notation:

  trailing-location ::= 'loc' '(' location ')'

  // FileLineCol Location.
  %1 = "foo"() : () -> i1 loc("mysource.cc":10:8)

  // Name Location
  return loc("foo")

  // CallSite Location
  return loc(callsite("foo" at "mysource.cc":19:9))

  // Fused Location
  /// Without metadata
  func @inline_notation() loc(fused["foo", "mysource.cc":10:8])

  /// With metadata
  return loc(fused<"myPass">["foo", "foo2"])

  // Unknown location.
  return loc(unknown)

Locations are currently only printed with inline notation at the line of each instruction. Further work is needed to allow for reference notation, e.g:
     ...
     return loc 1
   }
   ...
   loc 1 = "source.cc":10:1

PiperOrigin-RevId: 230587621
2019-03-29 15:32:49 -07:00
Lei Zhang 5654450853 Unify terms regarding assembly form to use generic vs. custom
This CL just changes various docs and comments to use the term "generic" and
"custom" when mentioning assembly forms. To be consist, several methods are
also renamed:

* FunctionParser::parseVerboseOperation() -> parseGenericOperation()
* ModuleState::hasShorthandForm() -> hasCustomForm()
* OpAsmPrinter::printDefaultOp() -> printGenericOp()

PiperOrigin-RevId: 230568819
2019-03-29 15:32:35 -07:00
MLIR Team b28009b681 Fix single producer check in loop fusion pass.
PiperOrigin-RevId: 230565482
2019-03-29 15:32:20 -07:00
Uday Bondhugula 864d9e02a1 Update fusion cost model + some additional infrastructure and debug information for -loop-fusion
- update fusion cost model to fuse while tolerating a certain amount of redundant
  computation; add cl option -fusion-compute-tolerance
  evaluate memory footprint and intermediate memory reduction
- emit debug info from -loop-fusion showing what was fused and why
- introduce function to compute memory footprint for a loop nest
- getMemRefRegion readability update - NFC

PiperOrigin-RevId: 230541857
2019-03-29 15:32:06 -07:00
Nicolas Vasilache e4020c2d1a Add support for Return in EDSCs
This CL adds the Return op to EDSCs types and emitter.
This allows generating full function bodies that can be compiled all the way
down to LLVMIR and executed on CPU.

At this point, the MLIR lacks the testing infrastructure to exercise this.
End-to-end testing of full functions written in EDSCs is left for a future CL.

PiperOrigin-RevId: 230527530
2019-03-29 15:31:50 -07:00
Uday Bondhugula 92e9d9484c loop unroll update: unroll factor one for a single iteration loop
- unrolling a single iteration loop by a factor of one should promote its body
  into its parent; this makes it consistent with the behavior/expectation that
  unrolling a loop by a factor equal to its trip count makes the loop go away.

PiperOrigin-RevId: 230426499
2019-03-29 15:31:35 -07:00
Uday Bondhugula 1b735dfe27 Refactor -dma-generate walker - NFC
- ForInst::walkOps will also be used in an upcoming CL (cl/229438679); better to have
  this instead of deriving from the InstWalker

PiperOrigin-RevId: 230413820
2019-03-29 15:31:03 -07:00
Uday Bondhugula 7669204304 Improve / fix documentation for affine map composition utilities - NFC
- improve/fix doc comments for affine apply composition related methods.
- drop makeSingleValueComposedAffineApply - really redundant and out of line in
  a public API; it's just returning the first result of the composed affine
  apply op, and not making a single result affine map or an affine_apply op.

PiperOrigin-RevId: 230406169
2019-03-29 15:30:47 -07:00
Uday Bondhugula 94a03f864f Allocate private/local buffers for slices accurately during fusion
- the size of the private memref created for the slice should be based on
  the memref region accessed at the depth at which the slice is being
  materialized, i.e., symbolic in the outer IVs up until that depth, as opposed
  to the region accessed based on the entire domain.

- leads to a significant contraction of the temporary / intermediate memref
  whenever the memref isn't reduced to a single scalar (through store fwd'ing).

Other changes

- update to promoteIfSingleIteration - avoid introducing unnecessary identity
  map affine_apply from IV; makes it much easier to write and read test cases
  and pass output for all passes that use promoteIfSingleIteration; loop-fusion
  test cases become much simpler

- fix replaceAllMemrefUsesWith bug that was exposed by the above update -
  'domInstFilter' could be one of the ops erased due to a memref replacement in
  it.

- fix getConstantBoundOnDimSize bug: a division by the coefficient of the identifier was
  missing (the latter need not always be 1); add lbFloorDivisors output argument

- rename getBoundingConstantSizeAndShape -> getConstantBoundingSizeAndShape

PiperOrigin-RevId: 230405218
2019-03-29 15:30:31 -07:00
MLIR Team 71495d58a7 Handle escaping memrefs in loop fusion pass:
*) Do not remove loop nests which write to memrefs which escape the function.
*) Do not remove memrefs which escape the function (e.g. are used in the return instruction).

PiperOrigin-RevId: 230398630
2019-03-29 15:30:14 -07:00
Jacques Pienaar 34c6f8c6e4 Add default attr value & define tf.AvgPool op and use pattern for rewrite.
Add default values to attributes, to allow attribute being left unspecified.  The attr getter will always return an attribute so callers need not check for it, if the attribute is not set then the default will be returned (at present the default will be constructed upon query but this will be changed).

Add op definition for tf.AvgPool in ops.td, rewrite matcher using pattern using attribute matching & transforms. Adding some helper functions to make it simpler.

Handle attributes with dialect prefix and map them to getter without dialect prefix.

Note: VerifyAvgPoolOp could probably be autogenerated by know given the predicate specification on attributes, but deferring that to a follow up.
PiperOrigin-RevId: 230364857
2019-03-29 15:29:59 -07:00
Uday Bondhugula d2aaa175ca Fix FlatAffineConstraints::removeIdRange
- the number of symbols/local ids was being incorrectly updated; the code in
  cl/230112574 exposes this.

PiperOrigin-RevId: 230358327
2019-03-29 15:29:44 -07:00
Jacques Pienaar a280e3997e Start doc generation pass.
Start doc generation pass that generates simple markdown output. The output is formatted simply[1] in markdown, but this allows seeing what info we have, where we can refine the op description (e.g., the inputs is probably redundant), what info is missing (e.g., the attributes could probably have a description).

The formatting of the description is still left up to whatever was in the op definition (which luckily, due to the uniformity in the .td file, turned out well but relying on the indentation there is fragile). The mechanism to autogenerate these post changes has not been added yet either. The output file could be run through a markdown formatter too to remove extra spaces.

[1]. This is not proposal for final style :) There could also be a discussion around single doc vs multiple (per dialect, per op), whether we want a TOC, whether operands/attributes should be headings or just formatted differently ...

PiperOrigin-RevId: 230354538
2019-03-29 15:29:29 -07:00
Lei Zhang 57aade19b3 Add assertions to SplatElementsAttr and ConstantOp builders and fix failures
1) Fix FloatAttr type inconsistency in conversion from tf.FusedBatchNorm to TFLite ops

We used to compose the splat tensor out of the scalar epsilon attribute by using the
type of the variance operand. However, the epsilon attribute may have a different
bitwidth than the one in the variance operand. So it ends up we were creating
inconsistent types within the FloatAttr itself.

2) Fix SplatElementsAttr type inconsistency in AnnotateInputArrays

We need to create the zero-valued attribute according to the type provided as the
command-line arguments.

3) Concretize the result type of tf.Shape constant folding test case

Currently the resultant constant is created by the constant folding harness, using
the result type of the original op as the constant's result type. That can be
a different type than the constant's internal DenseElementsAttr.

PiperOrigin-RevId: 230244665
2019-03-29 15:28:59 -07:00
Uday Bondhugula c1880a857d AffineExpr pretty print - add missing handling to print expr * - 1 as -expr
- print multiplication by -1 as unary negate; expressions like s0 * -1, d0 * -1
  + d1 will now appear as -s0, -d0 + d1 resp.
- a minor cleanup while on printAffineExprInternal

PiperOrigin-RevId: 230222151
2019-03-29 15:28:44 -07:00
River Riddle 512d87cefc Add a constant folding hook to ExtractElementOp to fold extracting the element of a constant. This also adds a 'getValue' function to DenseElementsAttr and SparseElementsAttr to get the element at a constant index.
PiperOrigin-RevId: 230098938
2019-03-29 15:28:28 -07:00
Nicolas Vasilache 119af6712e Cleanup spurious printing bits in EDSCs
This CL also makes ScopedEDSCContexts to reset the Bindable numbering when
creating a new context.
This is useful to write minimal tests that don't use FileCheck pattern
captures for now.

PiperOrigin-RevId: 230079997
2019-03-29 15:28:13 -07:00
Nicolas Vasilache 9f3f39d61a Cleanup EDSCs
This CL performs a bunch of cleanups related to EDSCs that are generally
useful in the context of using them with a simple wrapping C API (not in this
CL) and with simple language bindings to Python and Swift.

PiperOrigin-RevId: 230066505
2019-03-29 15:27:58 -07:00
River Riddle 174f66bc8a Restructure FloatAttr::get(Type, double) to allow for loss of precision when converting the double value to the target type semantics. A comment is added to discourage the use of this method for non simple constants. The new handling also removes the direct use of the float constructor for APFloat to avoid runtime float cast asan errors.
PiperOrigin-RevId: 230014696
2019-03-29 15:27:44 -07:00
River Riddle b04c9a47ca Fix raw buffer size when creating a DenseElementsAttr from an array of attributes.
PiperOrigin-RevId: 229973134
2019-03-29 15:27:13 -07:00
Lei Zhang 1e484b5ef4 Mark (void)indexRemap to please compiler for unused variable check
PiperOrigin-RevId: 229957023
2019-03-29 15:26:59 -07:00
River Riddle a1c0da42ec Rewrite OpStats to use llvm formatting utilities.
Example Output:

Operations encountered:
-----------------------
      addf                  , 11
      constant              , 4
      return                , 19
      some_op               , 1
   tf.AvgPool               , 3
   tf.DepthwiseConv2dNative , 3
   tf.FusedBatchNorm        , 2
  tfl.add                   , 7
  tfl.average_pool_2d       , 1
  tfl.leaky_relu            , 1

PiperOrigin-RevId: 229937190
2019-03-29 15:26:29 -07:00
MLIR Team c4237ae990 LoopFusion: Creates private MemRefs which are used only by operations in the fused loop.
*) Enables reduction of private memref size based on MemRef region accessed by fused slice.
*) Enables maximal fusion by creating a private memref to break a fusion-preventing dependence.
*) Adds maximal fusion flag to enable fusing as much as possible (though it still fuses the minimum cost computation slice).

PiperOrigin-RevId: 229936698
2019-03-29 15:26:15 -07:00
Nicolas Vasilache 24e5a72dac Fix AffineApply corner case
This CL adds a test reported by andydavis@ and fixes the corner case that
appears when operands do not come from an AffineApply and no Dim composition
is needed.

In such cases, we would need to create an empty map which is disallowed.
The composition in such cases becomes trivial: there is no composition.

This CL also updates the name AffineNormalizer to AffineApplyNormalizer.

PiperOrigin-RevId: 229819234
2019-03-29 15:25:59 -07:00
River Riddle 0e81d7c420 [MLIR] Add functionality for constructing a DenseElementAttr from an array of attributes and rerwite DenseElementsAttr::writeBits/readBits to handle non uniform bitwidths. This fixes asan failures that happen when using non uniform bitwidths.
PiperOrigin-RevId: 229815107
2019-03-29 15:25:45 -07:00
Uday Bondhugula 40f7535571 Update stale / target-specific information in comments - NFC
PiperOrigin-RevId: 229800834
2019-03-29 15:25:29 -07:00
Jacques Pienaar d6f84fa5d9 Add AttrConstraint to enable generating verification for attribute values.
Change MinMaxAttr to match hasValidMinMaxAttribute behavior. Post rewriting the other users of that function it could be removed too. The currently generated error message is:

error: 'tfl.fake_quant' op attribute 'minmax' failed to satisfy constraint of MinMaxAttr
PiperOrigin-RevId: 229775631
2019-03-29 15:25:13 -07:00
Smit Hinsu 0eebe6ffd9 Update comment in the constant folding pass as constant folding is supported even when not all operands are constants
PiperOrigin-RevId: 229670189
2019-03-29 15:24:28 -07:00
Nicolas Vasilache 4573a8da9a Fix improperly indexed DimOp in LowerVectorTransfers.cpp
This CL fixes a misunderstanding in how to build DimOp which triggered
execution issues in the CPU path.

The problem is that, given a `memref<?x4x?x8x?xf32>`, the expressions to
construct the dynamic dimensions should be:
`dim %arg, 0 : memref<?x4x?x8x?xf32>`
`dim %arg, 2 : memref<?x4x?x8x?xf32>`
and
`dim %arg, 4 : memref<?x4x?x8x?xf32>`

Before this CL, we wold construct:
`dim %arg, 0 : memref<?x4x?x8x?xf32>`
`dim %arg, 1 : memref<?x4x?x8x?xf32>`
`dim %arg, 2 : memref<?x4x?x8x?xf32>`

and expect the other dimensions to be constants.
This assumption seems consistent at first glance with the syntax of alloc:

```
    %tensor = alloc(%M, %N, %O) : memref<?x4x?x8x?xf32>
```

But this was actuallyincorrect.

This CL also makes the relevant functions available to EDSCs and removes
duplication of the incorrect function.

PiperOrigin-RevId: 229622766
2019-03-29 15:24:13 -07:00
Uday Bondhugula c1ca23ef6e Some loop fusion code cleanup/simplification post cl/229575126
- enforce the assumptions better / in a simpler way

PiperOrigin-RevId: 229612424
2019-03-29 15:23:43 -07:00
Lei Zhang 3766332533 Change impl::printBinaryOp() to consider operand and result type
The operand and result types of binary ops are not necessarily the
same. For those binary ops, we cannot print in the short-form assembly.

Enhance impl:::printBinaryOp to consider operand and result types
to select which assembly form to use.

PiperOrigin-RevId: 229608142
2019-03-29 15:23:28 -07:00
River Riddle 5843e5a7c0 Add a canonicalization pattern to remove Dealloc operations if the memref is an AllocOp that is only used by Dealloc operations.
PiperOrigin-RevId: 229606558
2019-03-29 15:23:13 -07:00
Alex Zinenko 05b02bb98e TableGen: implement predicate tree and basic simplification
A recent change in TableGen definitions allowed arbitrary AND/OR predicate
compositions at the cost of removing known-true predicate simplification.
Introduce a more advanced simplification mechanism instead.

In particular, instead of folding predicate C++ expressions directly in
TableGen, keep them as is and build a predicate tree in TableGen C++ library.
The predicate expression-substitution mechanism, necessary to implement complex
predicates for nested classes such as `ContainerType`, is replaced by a
dedicated predicate.  This predicate appears in the predicate tree and can be
used for tree matching and separation.  More specifically, subtrees defined
below such predicate may be subject to different transformations than those
that appear above.  For example, a subtree known to be true above the
substitution predicate is not necessarily true below it.

Use the predicate tree structure to eliminate known-true and known-false
predicates before code emission, as well as to collapse AND and OR predicates
if their value can be deduced based on the value of one child.

PiperOrigin-RevId: 229605997
2019-03-29 15:22:58 -07:00
Jacques Pienaar 4b2b5f5267 Enable specifying the op for which the reference implementation should be printed.
Allows emitting reference implementation of multiple ops inside the test lowering pass.

PiperOrigin-RevId: 229603494
2019-03-29 15:22:43 -07:00
River Riddle ada685f352 Add canonicalization to remove AllocOps if there are no uses. AllocOp has side effects on the heap, but can still be deleted if it has zero uses.
PiperOrigin-RevId: 229596556
2019-03-29 15:22:28 -07:00
Jacques Pienaar a5827fc91d Add attribute matching and transform to pattern rewrites.
Start simple with single predicate match & transform rules for attributes.
* Its unclear whether modelling Attr predicates will be needed so start with allowing matching attributes with a single predicate.
*  The input and output attr type often differs and so add ability to specify a transform between the input and output format.

PiperOrigin-RevId: 229580879
2019-03-29 15:22:14 -07:00
MLIR Team 27d067e164 LoopFusion improvements:
*) Adds support for fusing into consumer loop nests with multiple loads from the same memref.
*) Adds support for reducing slice loop trip count by projecting out destination loop IVs greater than destination loop depth.
*) Removes dependence on src loop depth and simplifies cost model computation.

PiperOrigin-RevId: 229575126
2019-03-29 15:21:59 -07:00
Jacques Pienaar 9d4bb57189 Start a testing pass for EDSC lowering.
This is mostly plumbing to start allowing testing EDSC lowering. Prototype specifying reference implementation using verbose format without any generation/binding support. Add test pass that dumps the constructed EDSC (of which there can only be one). The idea is to enable iterating from multiple sides, this is wrong on many dimensions at the moment.

PiperOrigin-RevId: 229570535
2019-03-29 15:21:44 -07:00
Alex Zinenko bd161ae5bc TableGen: untie Attr from Type
In TableGen definitions, the "Type" class has been used for types of things
that can be stored in Attributes, but not necessarily present in the MLIR type
system.  As a consequence, records like "String" or "DerviedAttrBody" were of
class "Type", which can be confusing.  Furthermore, the "builderCall" field of
the "Type" class serves only for attribute construction.  Some TableGen "Type"
subclasses that correspond to MLIR kinds of types do not have a canonical way
of construction only from the data available in TableGen, e.g. MemRefType would
require the list of affine maps.  This leads to a conclusion that the entities
that describe types of objects appearing in Attributes should be independent of
"Type": they have some properties "Type"s don't and vice versa.

Do not parameterize Tablegen "Attr" class by an instance of "Type".  Instead,
provide a "constBuilderCall" field that can be used to build an attribute from
a constant value stored in TableGen instead of indirectly going through
Attribute.Type.builderCall.  Some attributes still don't have a
"constBuilderCall" because they used to depend on types without a
"builderCall".

Drop definitions of class "Type" that don't correspond to MLIR Types.  Provide
infrastructure to define type-dependent attributes and string-backed attributes
for convenience.

PiperOrigin-RevId: 229570087
2019-03-29 15:21:28 -07:00
Lei Zhang 590012772d Promote broadcast logic from TensorFlowLite to Dialect/ directory
We also need the broadcast logic in the TensorFlow dialect. Move it to a
Dialect/ directory for a broader scope. This Dialect/ directory is intended
for code not in core IR, but can potentially be shared by multiple dialects.

Apart from fixing TensorFlow op TableGen to use this trait, this CL only
contains mechanical code shuffling.

PiperOrigin-RevId: 229563911
2019-03-29 15:21:14 -07:00
Uday Bondhugula f99a44a7cd Address documentation/readability related comments from cl/227252907 on memref
store forwarding - NFC.

PiperOrigin-RevId: 229561933
2019-03-29 15:20:59 -07:00
River Riddle 18fe1ffcd7 Move the storage of uniqued TypeStorage objects into TypeUniquer and give each context a unique TypeUniquer instance.
PiperOrigin-RevId: 229460053
2019-03-29 15:19:56 -07:00
Uday Bondhugula 03e15e1b9f Minor code cleanup - NFC.
- readability changes

PiperOrigin-RevId: 229443430
2019-03-29 15:19:41 -07:00
Lei Zhang b7dbfd04eb Const fold splat tensors for TFLite AddOp, SubOp, MulOp
The constant folding rules assumes value attributes of operands are already
verified to be in good standing.

For each op in the above, the constant folding rules support both integer and
floating point cases. Broadcast behavior is also supported as per the semantics
of TFLite ops.

This CL does not handle overflow/underflow cases yet.

PiperOrigin-RevId: 229441221
2019-03-29 15:19:26 -07:00
River Riddle f9d2eb1c8c Change derived type storage objects to define an 'operator==(const KeyTy &)' instead of converting to the KeyTy. This allows for handling cases where the KeyTy does not provide an equality operator on itself.
PiperOrigin-RevId: 229423249
2019-03-29 15:19:11 -07:00
River Riddle f8341cfe06 Verify that the parsed predicate attribute of a cmpi operation is a string.
PiperOrigin-RevId: 229419703
2019-03-29 15:18:53 -07:00
Alex Zinenko 0e58de70e7 Initial version of the LLVM IR dialect
LLVM IR types are defined using MLIR's extendable type system.  The dialect
provides the only type kind, LLVMType, that wraps an llvm::Type*.  Since LLVM
IR types are pointer-unique, MLIR type systems relies on those pointers to
perform its own type unique'ing.  Type parsing and printing is delegated to
LLVM libraries.

Define MLIR operations for the LLVM IR instructions currently used by the
translation to the LLVM IR Target to simplify eventual transition.  Operations
classes are defined using TableGen.  LLVM IR instruction operands that are only
allowed to take constant values are accepted as attributes instead.  All
operations are using verbose form for printing and parsing.

PiperOrigin-RevId: 229400375
2019-03-29 15:18:37 -07:00
Alex Zinenko 44e9869f1a TableGen: extract TypeConstraints from Type
MLIR has support for type-polymorphic instructions, i.e. instructions that may
take arguments of different types.  For example, standard arithmetic operands
take scalars, vectors or tensors.  In order to express such instructions in
TableGen, we need to be able to verify that a type object satisfies certain
constraints, but we don't need to construct an instance of this type.  The
existing TableGen definition of Type requires both.  Extract out a
TypeConstraint TableGen class to define restrictions on types.  Define the Type
TableGen class as a subclass of TypeConstraint for consistency.  Accept records
of the TypeConstraint class instead of the Type class as values in the
Arguments class when defining operators.

Replace the predicate logic TableGen class based on conjunctive normal form
with the predicate logic classes allowing for abitrary combinations of
predicates using Boolean operators (AND/OR/NOT).  The combination is
implemented using simple string rewriting of C++ expressions and, therefore,
respects the short-circuit evaluation order.  No logic simplification is
performed at the TableGen level so all expressions must be valid C++.
Maintaining CNF using TableGen only would have been complicated when one needed
to introduce top-level disjunction.  It is also unclear if it could lead to a
significantly simpler emitted C++ code.  In the future, we may replace inplace
predicate string combination with a tree structure that can be simplified in
TableGen's C++ driver.

Combined, these changes allow one to express traits like ArgumentsAreFloatLike
directly in TableGen instead of relying on C++ trait classes.

PiperOrigin-RevId: 229398247
2019-03-29 15:18:23 -07:00
Uday Bondhugula 4598dafa30 Parsing DmaStartOp: check if source, destination, and tag are of memref type.
- fix along the lines of cl/229390720 by @riverriddle

PiperOrigin-RevId: 229395218
2019-03-29 15:18:07 -07:00
River Riddle d50dc4fd6d When parsing DmaWait, check that the tag is a MemRef type.
PiperOrigin-RevId: 229390720
2019-03-29 15:17:52 -07:00
Nicolas Vasilache 515ce1e68e Add edsc::Indexed helper struct to act as syntactic sugar
This CL adds edsc::Indexed.

This helper class exists purely for sugaring purposes and allows writing
expressions such as:

```mlir
   Indexed A(...), B(...), C(...);
   ForNest(ivs, zeros, shapeA, ones, {
     C[ivs] = A[ivs] + B[ivs]
   });
```

PiperOrigin-RevId: 229388644
2019-03-29 15:17:37 -07:00
River Riddle 25d5b895fd When parsing Select/Cmpi standard operations, emit an error if the type does not have a valid i1 shape instead of crashing.
PiperOrigin-RevId: 229384794
2019-03-29 15:17:22 -07:00
Nicolas Vasilache 424041ad58 Add EDSC sugar
This allows load, store and ForNest to be used with both Expr and Bindable.
This simplifies writing generic pieces of MLIR snippet.

For instance, a generic pointwise add can now be written:

```cpp
// Different Bindable ivs, one per loop in the loop nest.
auto ivs = makeBindables(shapeA.size());
Bindable zero, one;
// Same bindable, all equal to `zero`.
SmallVector<Bindable, 8> zeros(ivs.size(), zero);
// Same bindable, all equal to `one`.
SmallVector<Bindable, 8> ones(ivs.size(), one);
// clang-format off
Bindable A, B, C;
Stmt scalarA, scalarB, tmp;
Stmt block = edsc::Block({
  ForNest(ivs, zeros, shapeA, ones, {
    scalarA = load(A, ivs),
    scalarB = load(B, ivs),
    tmp = scalarA + scalarB,
    store(tmp, C, ivs)
  }),
});
// clang-format on
```

This CL also adds some extra support for pretty printing that will be used in
a future CL when we introduce standalone testing of EDSCs. At the momen twe
are lacking the basic infrastructure to write such tests.

PiperOrigin-RevId: 229375850
2019-03-29 15:16:53 -07:00
Uday Bondhugula 6e4f3e40c7 Fix outdated comments
PiperOrigin-RevId: 229300301
2019-03-29 15:16:08 -07:00
River Riddle 3bb35ad0dc Don't allocate a buffer for an empty ArrayRef in TypeStorageAllocator.
PiperOrigin-RevId: 229290802
2019-03-29 15:15:52 -07:00
River Riddle b9c791b96d Change derived type storage objects to be constructed with an instance of the
KeyTy. This will simplify the cases where a type can be constructed, and need to be verified, in multiple ways.

PiperOrigin-RevId: 229279000
2019-03-29 15:15:37 -07:00
River Riddle 8b0ad6f579 If an instruction contains blocks, IfInst/ForInst, make sure to drop references held by those blocks when dropping references for the instruction.
PiperOrigin-RevId: 229278667
2019-03-29 15:15:23 -07:00
River Riddle 6c1631b3f8 Check that at least one constraint is parsed when parsing an IntegerSet.
PiperOrigin-RevId: 229248638
2019-03-29 15:15:08 -07:00
Lei Zhang 61ec6c0992 Swap the type and attribute parameter in ConstantOp::build()
This is to keep consistent with other TableGen generated builders
so that we can also use this builder in TableGen rules.

PiperOrigin-RevId: 229244630
2019-03-29 15:14:52 -07:00
River Riddle ed26dd0421 Add a canonicalization pattern for conditional branch to fold constant branch conditions.
PiperOrigin-RevId: 229242007
2019-03-29 15:14:37 -07:00
River Riddle 06b0bd9651 Emit unsupported error when parsing a DenseElementAttr with an integer type of greater than 64 bits.
DenseElementAttr currently does not support value bitwidths of > 64. This can result in asan failures and crashes when trying to invoke DenseElementsAttr::writeBits/DenseElementsAttr::readBits.

PiperOrigin-RevId: 229241125
2019-03-29 15:14:23 -07:00
River Riddle e0594ce732 Add missing return post parse failure for the indices of a sparse attribute.
PiperOrigin-RevId: 229231462
2019-03-29 15:14:07 -07:00
MLIR Team 38c2fe3158 LoopFusion: automate selection of source loop nest slice depth and destination loop nest insertion depth based on a simple cost model (cost model can be extended/replaced at a later time).
*) LoopFusion: Adds fusion cost function which compares the cost of the fused loop nest, with the cost of the two unfused loop nests to determine if it is profitable to fuse the candidate loop nests. The fusion cost function is run for various combinations for src/dst loop depths attempting find the minimum cost setting for src/dst loop depths which does not increase the computational cost when the loop nests are fused. Combinations of src/dst loop depth are evaluated attempting to maximize loop depth (i.e. take a bigger computation slice from the source loop nest, and insert it deeper in the destination loop nest for better locality).
*) LoopFusion: Adds utility to compute op instance count for loop nests, sliced loop nests, and to compute the cost of a loop nest fused with another sliced loop nest.
*) LoopFusion: canonicalizes slice bound AffineMaps (and updates related tests).
*) Analysis::Utils: Splits getBackwardComputationSlice into two functions: one which calculates and returns the slice loop bounds for analysis by LoopFusion, and the other for insertion of the computation slice (ones fusion has calculated the min-cost src/dst loop depths).
*) Test: Adds multiple unit tests to test the new functionality.

PiperOrigin-RevId: 229219757
2019-03-29 15:13:53 -07:00
River Riddle d6b71b0d57 Add a Block::dropAllReferences to drop all references from held instructions and call it when clearing the block. This fixes a bug where ForInst/IfInst instructions may still have references to values while being destroyed.
PiperOrigin-RevId: 229207798
2019-03-29 15:13:39 -07:00
River Riddle a674ae8bbd Return an empty IntegerSet if the '(' is not parsed.
PiperOrigin-RevId: 229198934
2019-03-29 15:13:25 -07:00
River Riddle 791049fb34 Add a FloatAttr::getChecked, and invoke it during Attribute parsing.
PiperOrigin-RevId: 229167099
2019-03-29 15:13:10 -07:00
Nicolas Vasilache 1b171e9357 Add EDSC support for operator*
PiperOrigin-RevId: 229097351
2019-03-29 15:12:55 -07:00
Nicolas Vasilache d734c50c5f [MLIR] Clip all access dimensions during LowerVectorTransfers
This CL adds a short term remedy to an issue that was found during execution
tests.

Lowering of vector transfer ops uses the permutation map to determine which
ForInst have been super-vectorized. During materialization to HW vector sizes
however, some of those dimensions may be fully unrolled and do not appear in
the permutation map.
Such dimensions were then not clipped and may have accessed out of bounds.

This CL conservatively clips all dimensions to ensure no out of bounds access.
The longer term solution is still up for debate but will probably require
either passing more information between Materialization and lowering, or just
merging the 2 passes.

PiperOrigin-RevId: 228980787
2019-03-29 15:12:26 -07:00
Nicolas Vasilache b941dc8238 [MLIR] Make MLIREmitter emit composed single-result AffineMap by construction
Arguably the dependence of EDSCs on Analysis is not great but on the other
hand this is a strict improvement in the emitted IR and since EDSCs are an
alternative to builders it makes sense that they have as much access to
Analysis as Transforms.

PiperOrigin-RevId: 228967624
2019-03-29 15:12:11 -07:00
Nicolas Vasilache 362557e11c Simplify compositions of AffineApply
This CL is the 6th and last on the path to simplifying AffineMap composition.
This removes `AffineValueMap::forwardSubstitutions` and replaces it by simple
calls to `fullyComposeAffineMapAndOperands`.

PiperOrigin-RevId: 228962580
2019-03-29 15:11:56 -07:00
River Riddle ba9a544615 Simplify Attribute constructor definitions.
PiperOrigin-RevId: 228926113
2019-03-29 15:11:41 -07:00
River Riddle 3fe8eb3f22 Add check for '[' when parsing a tensor literal list.
PiperOrigin-RevId: 228913908
2019-03-29 15:11:11 -07:00
River Riddle 6985dc62b5 Make sure that type construction arguments are forwarded.
PiperOrigin-RevId: 228910216
2019-03-29 15:10:55 -07:00
Jacques Pienaar 58423ad1c1 Follow up from previous change to avoid setting tokStart 2x.
PiperOrigin-RevId: 228903980
2019-03-29 15:10:40 -07:00
Jacques Pienaar 71ec869011 Fix omitted return post failed parse
PiperOrigin-RevId: 228903905
2019-03-29 15:10:25 -07:00
Jacques Pienaar 4fd6db3e29 Skip over whitespace using loop. NFC.
Else we can stack overflow on a long sequence of whitespace.

PiperOrigin-RevId: 228893517
2019-03-29 15:10:10 -07:00
Lei Zhang 311af4abf3 Const fold splat vectors/tensors in standard add, sub, and mul ops
The const folding logic is structurally similar, so use a template
to abstract the common part.

Moved mul(x, 0) to a legalization pattern to be consistent with
mul(x, 1).

Also promoted getZeroAttr() to be a method on Builder since it is
expected to be frequently used.

PiperOrigin-RevId: 228891989
2019-03-29 15:09:55 -07:00
Jacques Pienaar 78da6704b7 Verify string type token before attempting to get string value.
Add repro that would have resulted in crash previously.

PiperOrigin-RevId: 228890749
2019-03-29 15:09:40 -07:00
Jacques Pienaar 4c0faef943 Avoid redundant predicate checking in type matching.
Expand type matcher template generator to consider a set of predicates that are known to
hold. This avoids inserting redundant checking for trivially true predicates
(for example predicate that hold according to the op definition). This only targets predicates that trivially holds and does not attempt any logic equivalence proof.

PiperOrigin-RevId: 228880468
2019-03-29 15:09:25 -07:00
Lei Zhang ac5a50e1e4 Extract openInputFile() into Support/FileUtilities
Multiple binaries have the needs to open input files. Use this function
to de-duplicate the code.

Also changed openOutputFile() to return errors using std::string since
it is a library call and accessing I/O in library call is not friendly.

PiperOrigin-RevId: 228878221
2019-03-29 15:09:11 -07:00
River Riddle e8d0e1f72a Provide dialect hooks for defining named aliases for AffineMap/IntegerSet/Type.
The AsmPrinter will then query registered dialects for aliases of symbols used within the module and use them in place.

PiperOrigin-RevId: 228831678
2019-03-29 15:08:55 -07:00
Nicolas Vasilache cfa5831960 Uniformize composition of AffineApplyOp by construction
This CL is the 5th on the path to simplifying AffineMap composition.
This removes the distinction between normalized single-result AffineMap and
more general composed multi-result map.

One nice byproduct of making the implementation driven by single-result is
that the multi-result extension is a trivial change: the implementation is
still single-result and we just use:

```
unsigned idx = getIndexOf(...);
map.getResult(idx);
```

This CL also fixes an AffineNormalizer implementation issue related to symbols.
Namely it stops performing substitutions on symbols in AffineNormalizer and
instead concatenates them all to be consistent with the call to
`AffineMap::compose(AffineMap)`. This latter call to `compose` cannot perform
simplifications of symbols coming from different maps based on positions only:
i.e. dims are applied and renumbered but symbols must be concatenated.

The only way to determine whether symbols from different AffineApply are the
same is to look at the concrete values. The canonicalizeMapAndOperands is thus
extended with behavior to support replacing operands that appear multiple
times.

Lastly, this CL demonstrates that the implementation is correct by rewriting
ComposeAffineMaps using only `makeComposedAffineApply`. The implementation
uses a matcher because AffineApplyOp are introduced as composed operations on
the fly instead of iteratively forwardSubstituting. For this purpose, a walker
would revisit freshly introduced AffineApplyOp. Regardless, ComposeAffineMaps
is scheduled to disappear, this CL replaces the implementation based on
iterative `forwardSubstitute` by a composed-by-construction
`makeComposedAffineApply`.
Remaining calls to `forwardSubstitute` will be removed in the next CL.

PiperOrigin-RevId: 228830443
2019-03-29 15:08:40 -07:00
Uday Bondhugula 2370c601ba Add safeguard against FM explosion
- FM has a worst case exponential complexity. For our purposes, this worst case
  is rarely expected, but could still appear due to improperly constructed
  constraints (a logical/memory error in other methods for eg.) or artificially
  created arbitrarily complex integer sets (adversarial / fuzz tests).

  Add a check to detect such an explosion in the number of constraints and
  conservatively return false from isEmpty() (instead of running out of memory
  or running for too long).

- Add an artifical virus test case.

PiperOrigin-RevId: 228753496
2019-03-29 15:07:55 -07:00
Alex Zinenko 9003490287 Implement branch-free single-division lowering of affine division/remainder
This implements the lowering of `floordiv`, `ceildiv` and `mod` operators from
affine expressions to the arithmetic primitive operations.  Integer division
rules in affine expressions explicitly require rounding towards either negative
or positive infinity unlike machine implementations that round towards zero.
In the general case, implementing `floordiv` and `ceildiv` using machine signed
division requires computing both the quotient and the remainder.  When the
divisor is positive, this can be simplified by adjusting the dividend and the
quotient by one and switching signs.

In the current use cases, we are unlikely to encounter affine expressions with
negative divisors (affine divisions appear in loop transformations such as
tiling that guarantee that divisors are positive by construction).  Therefore,
it is reasonable to use branch-free single-division implementation.  In case of
affine maps, divisors can only be literals so we can check the sign and
implement the case for negative divisors when the need arises.

The affine lowering pass can still fail when applied to semi-affine maps
(division or modulo by a symbol).

PiperOrigin-RevId: 228668181
2019-03-29 15:07:40 -07:00
River Riddle 56b99b4045 Add a few utilities for terminator management:
* Get a specific successor operand.
* Iterator support for non successor operands.
* Fix bug when removing the last operand from the operand list of an Instruction.
* Get the argument number for a BlockArgument.

PiperOrigin-RevId: 228660898
2019-03-29 15:07:25 -07:00
Uday Bondhugula 742c37abc9 Fix DMA overlap pass buffer mapping
- the double buffer should be indexed (iv floordiv step) % 2 and NOT (iv % 2);
  step wasn't being accounted for.

- fix test cases, enable failing test cases

PiperOrigin-RevId: 228635726
2019-03-29 15:07:10 -07:00
Lei Zhang 9b034f0bfd Add tblgen::Attribute to wrap around TableGen Attr defs
This CL added a tblgen::Attribute class to wrap around raw TableGen
Record getValue*() calls on Attr defs, which will provide a nicer
API for handling TableGen Record.

PiperOrigin-RevId: 228581107
2019-03-29 15:06:41 -07:00
Alex Zinenko 6ce30becd7 Support verbose parsing and printing of terminator operations
Originally, terminators were special kinds of operation and could not be
extended by dialects.  Only builtin terminators were supported and they had
custom parsers and printers.  Currently, "terminator" is a property of an
operation, making it possible for dialects to define custom terminators.
However, verbose forms of operation syntax were not designed to support
terminators that may have a list of successors (each successor contains a block
name and an optional operand list).  Calling printDefaultOp on a terminator
drops all successor information.  Dialects are thus required to provide custom
parsers and printers for their terminators.

Introduce the syntax for the list of successors in the verbose from of the
operation.  Add support for printing and parsing verbose operations with
successors.

Note that this does not yet add support for unregistered terminators since
"terminator" is a property stored in AsbtractOperation and therefore is only
available for registered operations that have an instance of AbstractOperation.

Add tests for verbose parsing.  It is currently impossible to test round-trip
for verbose terminators because none of the known dialects use verbose syntax
for printing terminators by default, however the printer was exercised on the
LLVM IR dialect prototype.

PiperOrigin-RevId: 228566453
2019-03-29 15:06:26 -07:00
Uday Bondhugula 303c09299f Fix affine expr flattener bug + improve simplification in a particular scenario
- fix visitDivExpr: constraints constructed for localVarCst used the original
  divisor instead of the simplified divisor; fix this. Add a simple test case
  in memref-bound-check that reproduces this bug - although this was encountered in the
  context of slicing for fusion.

- improve mod expr flattening: when flattening mod expressions,
  cancel out the GCD of the numerator and denominator so that we can get a
  simpler flattened form along with a simpler floordiv local var for it

PiperOrigin-RevId: 228539928
2019-03-29 15:06:11 -07:00
Nicolas Vasilache 1f78d63f05 [MLIR] Make SuperVectorization use normalized AffineApplyOp
Supervectorization does not plan on handling multi-result AffineMaps and
non-canonical chains of > 1 AffineApplyOp.
This CL uses the simpler single-result unbounded AffineApplyOp in the
MaterializeVectors pass.

PiperOrigin-RevId: 228469085
2019-03-29 15:05:55 -07:00
Lei Zhang 3e5ee82b81 Put Operator and PredCNF into the tblgen namespace
PiperOrigin-RevId: 228429130
2019-03-29 15:05:38 -07:00
Lei Zhang b2cc2c344e Add tblgen::Type to wrap around TableGen Type defs
This CL added a tblgen::Type class to wrap around raw TableGen
Record getValue*() calls on Type defs, which will provide a
nicer API for handling TableGen Record.

The PredCNF class is also updated to work together with
tblgen::Type.
PiperOrigin-RevId: 228429090
2019-03-29 15:05:23 -07:00
Chris Lattner 2b902f1288 Delete FuncBuilder::createChecked. It is perhaps still a good idea, but has no
clients.  Let's re-add it in the future if there is ever a reason to.  NFC.

Unrelatedly, add a use of a variable to unbreak the non-assert build.

PiperOrigin-RevId: 228284026
2019-03-29 15:05:08 -07:00
Nicolas Vasilache 997415fa77 Extract BuiltinOps::canonicalizeMapAndOperands
This CL is the 4th on the path to simplifying AffineMap composition.
This CL extract canonicalizeMapAndOperands so it can be reused by other
functions; in particular, this will be used in
`makeNormalizedAffineApply`.

PiperOrigin-RevId: 228277890
2019-03-29 15:04:52 -07:00
Nicolas Vasilache 00aac70159 Move makeNormalizedAffineApply
This CL is the 3rd on the path to simplifying AffineMap composition.
This CL just moves `makeNormalizedAffineApply` from VectorAnalysis to
AffineAnalysis where it more naturally belongs.

PiperOrigin-RevId: 228277182
2019-03-29 15:04:38 -07:00
Nicolas Vasilache c6f798a976 Introduce AffineMap::compose(AffineMap)
This CL is the 2nd on the path to simplifying AffineMap composition.
This CL uses the now accepted `AffineExpr::compose(AffineMap)` to
implement `AffineMap::compose(AffineMap)`.

Implications of keeping the simplification function in
Analysis are documented where relevant.

PiperOrigin-RevId: 228276646
2019-03-29 15:04:20 -07:00
River Riddle 8eccc429b7 Add parser support for named type aliases.
Alias identifiers can be used in the place of the types that they alias, and are defined as:

    type-alias-def ::= '!' alias-name '=' 'type' type
    type-alias ::= '!' alias-name

Example:

    !avx.m128 = type vector<4 x f32>
    ...

    "foo"(%x) : vector<4 x f32> -> ()

    // becomes:

    "foo"(%x) : !avx.m128 -> ()

PiperOrigin-RevId: 228271372
2019-03-29 15:04:05 -07:00
Uday Bondhugula e94ba6815a Fix 0-d memref corner case for getMemRefRegion()
- fix crash on test/Transforms/canonicalize.mlir with
  -memref-bound-check

PiperOrigin-RevId: 228268486
2019-03-29 15:03:50 -07:00
Nicolas Vasilache c449e46ceb Introduce AffineExpr::compose(AffineMap)
This CL is the 1st on the path to simplifying AffineMap composition.
This CL uses the now accepted AffineExpr.replaceDimsAndSymbols to
implement `AffineExpr::compose(AffineMap)`.

Arguably, `simplifyAffineExpr` should be part of IR and not Analysis but
this CL does not yet pull the trigger on that.

PiperOrigin-RevId: 228265845
2019-03-29 15:03:36 -07:00
Uday Bondhugula 21baf86a2f Extend loop-fusion's slicing utility + other fixes / updates
- refactor toAffineFromEq and the code surrounding it; refactor code into
  FlatAffineConstraints::getSliceBounds
- add FlatAffineConstraints methods to detect identifiers as mod's and div's of other
  identifiers
- add FlatAffineConstraints::getConstantLower/UpperBound
- Address b/122118218 (don't assert on invalid fusion depths cmdline flags -
  instead, don't do anything; change cmdline flags
  src-loop-depth -> fusion-src-loop-depth
- AffineExpr/Map print method update: don't fail on null instances (since we have
  a wrapper around a pointer, it's avoidable); rationale: dump/print methods should
  never fail if possible.
- Update memref-dataflow-opt to add an optimization to avoid a unnecessary call to
  IsRangeOneToOne when it's trivially going to be true.
- Add additional test cases to exercise the new support
- update a few existing test cases since the maps are now generated uniformly with
  all destination loop operands appearing for the backward slice
- Fix projectOut - fix wrong range for getBestElimCandidate.
- Fix for getConstantBoundOnDimSize() - didn't show up in any test cases since
  we didn't have any non-hyperrectangular ones.

PiperOrigin-RevId: 228265152
2019-03-29 15:03:20 -07:00
Uday Bondhugula b934d75b8f Convert expr - c * (expr floordiv c) to expr mod c in AffineExpr
- Detect 'mod' to replace the combination of floordiv, mul, and subtract when
  possible at construction time; when 'c' is a power of two, this reduces the number of
  operations; also more compact and readable. Update simplifyAdd for this.

  On a side note:
  - with the affine expr flattening we have, a mod expression like d0 mod c
    would be flattened into d0 - c * q,  c * q <= d0 <= c*q + c - 1, with 'q'
    being added as the local variable (q = d0 floordiv c); as a result, a mod
    was turned into a floordiv whenever the expression was reconstructed back,
    i.e., as  d0 - c * (d0 floordiv c); as a result of this change, we recover
    the mod back.

- rename SimplifyAffineExpr -> SimplifyAffineStructures (pass had been renamed but
  the file hadn't been).

PiperOrigin-RevId: 228258120
2019-03-29 15:02:56 -07:00
Uday Bondhugula 56b3640b94 Misc readability and doc / code comment related improvements - NFC
- when SSAValue/MLValue existed, code at several places was forced to create additional
  aggregate temporaries of SmallVector<SSAValue/MLValue> to handle the conversion; get
  rid of such redundant code

- use filling ctors instead of explicit loops

- for smallvectors, change insert(list.end(), ...) -> append(...

- improve comments at various places

- turn getMemRefAccess into MemRefAccess ctor and drop duplicated
  getMemRefAccess. In the next CL, provide getAccess() accessors for load,
  store, DMA op's to return a MemRefAccess.

PiperOrigin-RevId: 228243638
2019-03-29 15:02:41 -07:00
Lei Zhang f8bbe5deca Various tiny refinements over TableGen Operator class
Use "native" vs "derived" to differentiate attributes on ops: native ones
are specified when creating the op as a part of defining the op, while
derived ones are computed from properties of the op.

PiperOrigin-RevId: 228186962
2019-03-29 15:01:56 -07:00
River Riddle 3b2c5600d9 Add support for types belonging to unknown dialects. This allows for types to be round tripped even if the dialect that defines them is not linked in. These types will be represented by a new "UnknownType" that uniques them based upon the dialect namespace and raw string type data.
PiperOrigin-RevId: 228184629
2019-03-29 15:01:11 -07:00
Jacques Pienaar aae85ddce1 Match attributes in input pattern.
Bind attributes similar to operands. Use to rewrite leakyreulo and const rewrite pattern. The attribute type/attributes are not currently checked so should only be used where the attributes match due to the construction of the op.

To support current attribute namespacing, convert __ in attribute name to "$" for matching purposes ('$' is not valid character in variable in TableGen).

Some simplification to make it simpler to specify indented ostream and avoid so many spaces. The goal is not to have perfectly formatted code generated but good enough so that its still easy to read for a user.

PiperOrigin-RevId: 228183639
2019-03-29 15:00:55 -07:00
Alex Zinenko 92a899f629 Drop all uses of the ForInst induction variable before deleting ForInst
The `for` instruction defines the loop induction variable it uses.  In the
well-formed IR, the induction variable can only be used by the body of the
`for` loop.  Existing implementation was explicitly cleaning the body of the
for loop to remove all uses of the induction variable before removing its
definition.  However, in ill-formed IR that may appear in some stages of
parsing, there may be (invalid) users of the loop induction variable outside
the loop body.  In case of unsuccessful parsing, destructor of the
ForInst-defined Value would assert because there are remaining though invalid
users of this Value.  Explicitly drop all uses of the loop induction Value when
destroying a ForInst.  It is no longer necessary to explicitly clean the body
of the loop, destructor of the block will take care of this.

PiperOrigin-RevId: 228168880
2019-03-29 15:00:26 -07:00
Alex Zinenko 3b7b0040ce FunctionParser::~FunctionParser: avoid iterator invalidation
When destroying a FunctionParser in case of parsing failure, we clean up all
uses of undefined forward-declared references.  This has been implemented as
iteration over the list of uses.  However, deleting one use from the list
invalidates the iterator (`IROperand::drop` sets `nextUse` to `nullptr` while
the iterator reads `nextUse` to advance; therefore only the first use was
deleted from the list).  Get a new iterator before calling drop to avoid
invalidation.

PiperOrigin-RevId: 228168849
2019-03-29 15:00:10 -07:00
Uday Bondhugula 94c2d969ce Rename getAffineBinaryExpr -> getAffineBinaryOpExpr, getBinaryAffineOpExpr ->
getAffineBinaryOpExpr for consistency (NFC)

- this is consistent with the name of the class and getAffineDimExpr/ConstantExpr, etc.

PiperOrigin-RevId: 228164959
2019-03-29 14:59:52 -07:00
Nicolas Vasilache 7c0bbe0939 Iterate on vector rather than DenseMap during AffineMap normalization
This CL removes a flakyness associated to a spurious iteration on DenseMap
iterators when normalizing AffineMap.

PiperOrigin-RevId: 228160074
2019-03-29 14:59:37 -07:00
Alex Zinenko c47ed53211 Add simple constant folding hook for CmpIOp
Integer comparisons can be constant folded if both of their arguments are known
constants, which we can compare in the compiler.  This requires implementing
all comparison predicates, but thanks to consistency between LLVM and MLIR
comparison predicates, we have a one-to-one correspondence between predicates
and llvm::APInt comparison functions.  Constant folding of comparsions with
maximum/minimum values of the integer type are left for future work.

This will be used to test the lowering of mod/floordiv/ceildiv in affine
expressions at compile time.

PiperOrigin-RevId: 228077580
2019-03-29 14:59:22 -07:00
Alex Zinenko caa7e70627 LLVM IR lowering: support integer division and remainder operations
These operations trivially map to LLVM IR counterparts for operands of scalar
and (one-dimensional) vector type.  Multi-dimensional vector and tensor type
operands would fail type conversion before the operation conversion takes
place.  Add tests for scalar and vector cases.  Also add a test for vector
`select` instruction for consistency with other tests.

PiperOrigin-RevId: 228077564
2019-03-29 14:59:07 -07:00
Alex Zinenko bc04556cf8 Introduce integer division and remainder operations
This adds signed/unsigned integer division and remainder operations to the
StandardOps dialect.  Two versions are required because MLIR integers are
signless, but the meaning of the leading bit is important in division and
affects the results.  LLVM IR made a similar choice.  Define the operations in
the tablegen file and add simple constant folding hooks in the C++
implementation.  Handle signed division overflow and division by zero errors in
constant folding.  Canonicalization is left for future work.

These operations are necessary to lower affine_apply's down to LLVM IR.

PiperOrigin-RevId: 228077549
2019-03-29 14:58:52 -07:00
Nicolas Vasilache 28cf580555 Cleanup spurious DenseMap include
PiperOrigin-RevId: 228059305
2019-03-29 14:58:38 -07:00
Jacques Pienaar 8f24943826 Verify type of operands match those specifed in op registry.
Expand type to include matcher predicates. Use CNF form to allow specifying combinations of constraints for type. The matching call for the type is used to verify the construction of the operation as well as in rewrite pattern generation.

The matching initially includes redundant checks (e.g., even if the operand of the op is guaranteed to satisfy some requirement, it is still checked during matcher generation for now). As well as some of the traits specified now check what the generated code already checks. Some of the traits can be removed in future as the verify method will include the relevant checks based on the op definition already.

More work is needed for variadic operands.

CNF form is used so that in the follow up redundant checks in the rewrite patterns could be omitted (e.g., when matching a F32Tensor, one does not need to verify that op X's operand 0 is a Tensor if that is guaranteed by op X's definition). The alternative was to have single matcher function specified, but this would not allow for reasoning about what attributes already hold (at the level of PredAtoms).

Use this new operand type restrictions to rewrite BiasAdd with floating point operands as declarative pattern.

PiperOrigin-RevId: 227991412
2019-03-29 14:58:23 -07:00
Nicolas Vasilache 62dabbfd09 Fix opt build failure
PiperOrigin-RevId: 227938032
2019-03-29 14:57:36 -07:00
Uday Bondhugula 8496f2c30b Complete TODOs / cleanup for loop-fusion utility
- this is CL 1/2 that does a clean up and gets rid of one limitation in an
  underlying method - as a result, fusion works for more cases.
- fix bugs/incomplete impl. in toAffineMapFromEq
- fusing across rank changing reshapes for example now just works

  For eg. given a rank 1 memref to rank 2 memref reshape (64 -> 8 x 8) like this,
  -loop-fusion -memref-dataflow-opt now completely fuses and inlines/store-forward
  to get rid of the temporary:

INPUT

  // Rank 1 -> Rank 2 reshape
  for %i0 = 0 to 64 {
     %v = load %A[%i0]
     store %v, %B[%i0 floordiv 8, i0 mod 8]
  }

  for %i1 = 0 to 8
    for %i2 = 0 to 8
      %w = load %B[%i1, i2]
      "foo"(%w) : (f32) -> ()

OUTPUT

$ mlir-opt -loop-fusion -memref-dataflow-opt fuse_reshape.mlir

#map0 = (d0, d1) -> (d0 * 8 + d1)
mlfunc @fuse_reshape(%arg0: memref<64xf32>) {
  for %i0 = 0 to 8 {
    for %i1 = 0 to 8 {
      %0 = affine_apply #map0(%i0, %i1)
      %1 = load %arg0[%0] : memref<64xf32>
      "foo"(%1) : (f32) -> ()
    }
  }
}

AFAIK, there is no polyhedral tool / compiler that can perform such fusion -
because it's not really standard loop fusion, but possible through a
generalized slicing-based approach such as ours.

PiperOrigin-RevId: 227918338
2019-03-29 14:57:22 -07:00
Smit Hinsu d3339ea2b8 Handle parsing failure for splat elements attribute
Currently, it emits the error but does not terminate parsing.

TESTED with unit test

PiperOrigin-RevId: 227886274
2019-03-29 14:56:52 -07:00
Nicolas Vasilache 618c6a74c6 [MLIR] Introduce normalized single-result unbounded AffineApplyOp
Supervectorization does not plan on handling multi-result AffineMaps and
non-canonical chains of > 1 AffineApplyOp.
This CL introduces a simpler abstraction and composition of single-result
unbounded AffineApplyOp by using the existing unbound AffineMap composition.

This CL adds a simple API call and relevant tests:

```c++
OpPointer<AffineApplyOp> makeNormalizedAffineApply(
  FuncBuilder *b, Location loc, AffineMap map, ArrayRef<Value*> operands);
```

which creates a single-result unbounded AffineApplyOp.
The operands of AffineApplyOp are not themselves results of AffineApplyOp by
consrtuction.

This represent the simplest possible interface to complement the composition
of (mathematical) AffineMap, for the cases when we are interested in applying
it to Value*.

In this CL the composed AffineMap is not compressed (i.e. there exist operands
that are not part of the result). A followup commit will compress to normal
form.

The single-result unbounded AffineApplyOp abstraction will be used in a
followup CL to support the MaterializeVectors pass.

PiperOrigin-RevId: 227879021
2019-03-29 14:56:37 -07:00
River Riddle d2cd083f79 Introduce CRTP TypeBase class to simplify type construction and validation.
This impl class currently provides the following:
* auto definition of the 'ImplType = StorageClass'
* get/getChecked wrappers around TypeUniquer
* 'verifyConstructionInvariants' hook
   - This hook verifies that the arguments passed into get/getChecked are valid
     to construct a type instance with.

With this, all non-generic type uniquing has been moved out of MLIRContext.cpp

PiperOrigin-RevId: 227871108
2019-03-29 14:56:22 -07:00
Chris Lattner 7983bbc251 Introduce a simple canonicalization of affine_apply that drops unused dims and
symbols.

Included with this is some other infra:
 - Testcases for other canonicalizations that I will implement next.
 - Some helpers in AffineMap/Expr for doing simple walks without defining whole
   visitor classes.
 - A 'replaceDimsAndSymbols' facility that I'll be using to simplify maps and
   exprs, e.g. to fold one constant into a mapping and to drop/renumber unused dims.
 - Allow index (and everything else) to work in memref's, as we previously
   discussed, to make the testcase easier to write.
 - A "getAffineBinaryExpr" helper to produce a binop when you know the kind as
   an enum.

This line of work will eventually subsume the ComposeAffineApply pass, but it is no where close to that yet :-)

PiperOrigin-RevId: 227852951
2019-03-29 14:56:07 -07:00
Alex Zinenko 8281151c2a TableGen standard arithmetic ops
Use tablegen to generate definitions of the standard binary arithmetic
operations.  These operations share a lot of boilerplate that is better off
generated by a tool.

Using tablegen for standard binary arithmetic operations requires the following
modifications.
1. Add a bit field `hasConstantFolder` to the base Op tablegen class; generate
the `constantFold` method signature if the bit is set.  Differentiate between
single-result and zero/multi-result functions that use different signatures.
The implementation of the method remains in C++, similarly to canonicalization
patterns, since it may be large and non-trivial.
2. Define the `AnyType` record of class `Type` since `BinaryOp` currently
provided in op_base.td is supposed to operate on tensors and other tablegen
users may rely on this behavior.

Note that this drops the inline documentation on the operation classes that was
copy-pasted around anyway.  Since we don't generate g3doc from tablegen yet,
keep LangRef.md as it is.  Eventually, the user documentation can move to the
tablegen definition file as well.

PiperOrigin-RevId: 227820815
2019-03-29 14:55:37 -07:00
Jacques Pienaar dde5bf234d Use Operator class in OpDefinitionsGen. Cleanup NFC.
PiperOrigin-RevId: 227764826
2019-03-29 14:55:22 -07:00
Nicolas Vasilache 0ebc0ba72e [MLIR] More graceful failure in MaterializeVectors
Even though it is unexpected except in pathological cases, a nullptr clone may
be returned. This CL handles the nullptr return gracefuly.

PiperOrigin-RevId: 227764615
2019-03-29 14:55:05 -07:00
Nicolas Vasilache 5b87a5ef4b [MLIR] Drop strict super-vector requirement in MaterializeVector
The strict requirement (i.e. at least 2 HW vectors in a super-vector) was a
premature optimization to avoid interfering with other vector code potentially
introduced via other means.

This CL avoids this premature optimization and the spurious errors it causes
when super-vector size == HW vector size (which is a possible corner case).

This may be revisited in the future.

PiperOrigin-RevId: 227763966
2019-03-29 14:54:49 -07:00
Nicolas Vasilache 17f96ea3dd [MLIR] Fix uninitialized value found with msan
The omission of an early exit created opportunities for unitialized memory
reads. This CL fixes the issue.

PiperOrigin-RevId: 227761814
2019-03-29 14:54:36 -07:00
Nicolas Vasilache 947e5f4a68 [MLIR] Handle corner case in MaterializeVectors
This corner was found when stress testing with a functional end-to-end CPU
path. In the case where the hardware vector size is 1x...x1 the `keep` vector
is empty and would result a crash.

While there is no reason to expect a 1x...x1 HW vector in practice, this case
can just gracefully degrade to scalar, which is what this CL allows.

PiperOrigin-RevId: 227761097
2019-03-29 14:54:22 -07:00
River Riddle 54948a4380 Split the standard types from builtin types and move them into separate source files(StandardTypes.cpp/h). After this cl only FunctionType and IndexType are builtin types, but IndexType will likely become a standard type when the ml/cfgfunc merger is done. Mechanical NFC.
PiperOrigin-RevId: 227750918
2019-03-29 14:54:07 -07:00
Jacques Pienaar c396c044e6 Match the op via isa instead of string compare.
* Match using isa
  - This limits the rewrite pattern to ops defined in op registry but that is probably better end state (esp. for additional verification).

PiperOrigin-RevId: 227598946
2019-03-29 14:53:37 -07:00
River Riddle 8abc06f3d5 Implement initial support for dialect specific types.
Dialect specific types are registered similarly to operations, i.e. registerType<...> within the dialect. Unlike operations, there is no notion of a "verbose" type, that is *all* types must be registered to a dialect. Casting support(isa/dyn_cast/etc.) is implemented by reserving a range of type kinds in the top level Type class as opposed to string comparison like operations.

To support derived types a few hooks need to be implemented:

In the concrete type class:
    - static char typeID;
      * A unique identifier for the type used during registration.

In the Dialect:
    - typeParseHook and typePrintHook must be implemented to provide parser support.

The syntax for dialect extended types is as follows:
 dialect-type:  '!' dialect-namespace '<' '"' type-specific-data '"' '>'

The 'type-specific-data' is information used to identify different types within the dialect, e.g:
 - !tf<"variant"> // Tensor Flow Variant Type
 - !tf<"string">  // Tensor Flow String Type

TensorFlow/TensorFlowControl types are now implemented as dialect specific types as a proof
 of concept.

PiperOrigin-RevId: 227580052
2019-03-29 14:53:07 -07:00
Alex Zinenko 0c4ee54198 Merge LowerAffineApplyPass into LowerIfAndForPass, rename to LowerAffinePass
This change is mechanical and merges the LowerAffineApplyPass and
LowerIfAndForPass into a single LowerAffinePass.  It makes a step towards
defining an "affine dialect" that would contain all polyhedral-related
constructs.  The motivation for merging these two passes is based on retiring
MLFunctions and, eventually, transforming If and For statements into regular
operations.  After that happens, LowerAffinePass becomes yet another
legalization.

PiperOrigin-RevId: 227566113
2019-03-29 14:52:52 -07:00
Alex Zinenko fa710c17f4 LowerForAndIf: expand affine_apply's inplace
Existing implementation was created before ML/CFG unification refactoring and
did not concern itself with further lowering to separate concerns.  As a
result, it emitted `affine_apply` instructions to implement `for` loop bounds
and `if` conditions and required a follow-up function pass to lower those
`affine_apply` to arithmetic primitives.  In the unified function world,
LowerForAndIf is mostly a lowering pass with low complexity.  As we move
towards a dialect for affine operations (including `for` and `if`), it makes
sense to lower `for` and `if` conditions directly to arithmetic primitives
instead of relying on `affine_apply`.

Expose `expandAffineExpr` function in LoweringUtils.  Use this function
together with `expandAffineMaps` to emit primitives that implement loop and
branch conditions directly.

Also remove tests that become unnecessary after transforming LowerForAndIf into
a function pass.

PiperOrigin-RevId: 227563608
2019-03-29 14:52:22 -07:00
Alex Zinenko d64db86f20 Refactor LowerAffineApply
In LoweringUtils, extract out `expandAffineMap`.  This function takes an affine
map and a list of values the map should be applied to and emits a sequence of
arithmetic instructions that implement the affine map.  It is independent of
the AffineApplyOp and can be used in places where we need to insert an
evaluation of an affine map without relying on a (temporary) `affine_apply`
instruction.  This prepares for a merge between LowerAffineApply and
LowerForAndIf passes.

Move the `expandAffineApply` function to the LowerAffineApply pass since it is
the only place that must be aware of the `affine_apply` instructions.

PiperOrigin-RevId: 227563439
2019-03-29 14:52:07 -07:00
Chris Lattner 8ebd64b32f Update the g3docs to reflect the merging of CFG and ML functions.
PiperOrigin-RevId: 227562943
2019-03-29 14:51:52 -07:00
Chris Lattner bbf362b784 Eliminate extfunc/cfgfunc/mlfunc as a concept, and just use 'func' instead.
The entire compiler now looks at structural properties of the function (e.g.
does it have one block, does it contain an if/for stmt, etc) so the only thing
holding up this difference is round tripping through the parser/printer syntax.
Removing this shrinks the compile by ~140LOC.

This is step 31/n towards merging instructions and statements.  The last step
is updating the docs, which I will do as a separate patch in order to split it
from this mostly mechanical patch.

PiperOrigin-RevId: 227540453
2019-03-29 14:51:37 -07:00
River Riddle ae3f8a79ae Rename OperationPrefix to Namespace in Dialect. This is important as dialects will soon be able to define more than just operations.
Moving forward dialect namespaces cannot contain '.' characters.

This cl also standardizes that operation names must begin with the dialect namespace followed by a '.'.

PiperOrigin-RevId: 227532193
2019-03-29 14:51:22 -07:00
Alex Zinenko 0565067495 LLVM IR Lowering: support "select"
This commit adds support for the "select" operation that lowers directly into
its LLVM IR counterpart.  A simple test is included.

PiperOrigin-RevId: 227527893
2019-03-29 14:51:08 -07:00
Chris Lattner 50a356d118 Simplify FunctionPass to only have a runOnFunction hook, instead of having a
runOnCFG/MLFunction override locations.  Passes that care can handle this
filtering if they choose.  Also, eliminate one needless difference between
CFG/ML functions in the parser.

This is step 30/n towards merging instructions and statements.

PiperOrigin-RevId: 227515912
2019-03-29 14:50:53 -07:00
Nicolas Vasilache 73f5c9c380 [MLIR] Sketch a simple set of EDSCs to declaratively write MLIR
This CL introduces a simple set of Embedded Domain-Specific Components (EDSCs)
in MLIR components:
1. a `Type` system of shell classes that closely matches the MLIR type system. These
types are subdivided into `Bindable` leaf expressions and non-bindable `Expr`
expressions;
2. an `MLIREmitter` class whose purpose is to:
  a. maintain a map of `Bindable` leaf expressions to concrete SSAValue*;
  b. provide helper functionality to specify bindings of `Bindable` classes to
     SSAValue* while verifying comformable types;
  c. traverse the `Expr` and emit the MLIR.

This is used on a concrete example to implement MemRef load/store with clipping in the
LowerVectorTransfer pass. More specifically, the following pseudo-C++ code:
```c++
MLFuncBuilder *b = ...;
Location location = ...;
Bindable zero, one, expr, size;
// EDSL expression
auto access = select(expr < zero, zero, select(expr < size, expr, size - one));
auto ssaValue = MLIREmitter(b)
    .bind(zero, ...)
    .bind(one, ...)
    .bind(expr, ...)
    .bind(size, ...)
    .emit(location, access);
```
is used to emit all the MLIR for a clipped MemRef access.

This simple EDSL can easily be extended to more powerful patterns and should
serve as the counterpart to pattern matchers (and could potentially be unified
once we get enough experience).

In the future, most of this code should be TableGen'd but for now it has
concrete valuable uses: make MLIR programmable in a declarative fashion.

This CL also adds Stmt, proper supporting free functions and rewrites
VectorTransferLowering fully using EDSCs.

The code for creating the EDSCs emitting a VectorTransferReadOp as loops
with clipped loads is:

```c++
  Stmt block = Block({
    tmpAlloc = alloc(tmpMemRefType),
    vectorView = vector_type_cast(tmpAlloc, vectorMemRefType),
    ForNest(ivs, lbs, ubs, steps, {
      scalarValue = load(scalarMemRef, accessInfo.clippedScalarAccessExprs),
      store(scalarValue, tmpAlloc, accessInfo.tmpAccessExprs),
    }),
    vectorValue = load(vectorView, zero),
    tmpDealloc = dealloc(tmpAlloc.getLHS())});
  emitter.emitStmt(block);
```

where `accessInfo.clippedScalarAccessExprs)` is created with:

```c++
select(i + ii < zero, zero, select(i + ii < N, i + ii, N - one));
```

The generated MLIR resembles:

```mlir
    %1 = dim %0, 0 : memref<?x?x?x?xf32>
    %2 = dim %0, 1 : memref<?x?x?x?xf32>
    %3 = dim %0, 2 : memref<?x?x?x?xf32>
    %4 = dim %0, 3 : memref<?x?x?x?xf32>
    %5 = alloc() : memref<5x4x3xf32>
    %6 = vector_type_cast %5 : memref<5x4x3xf32>, memref<1xvector<5x4x3xf32>>
    for %i4 = 0 to 3 {
      for %i5 = 0 to 4 {
        for %i6 = 0 to 5 {
          %7 = affine_apply #map0(%i0, %i4)
          %8 = cmpi "slt", %7, %c0 : index
          %9 = affine_apply #map0(%i0, %i4)
          %10 = cmpi "slt", %9, %1 : index
          %11 = affine_apply #map0(%i0, %i4)
          %12 = affine_apply #map1(%1, %c1)
          %13 = select %10, %11, %12 : index
          %14 = select %8, %c0, %13 : index
          %15 = affine_apply #map0(%i3, %i6)
          %16 = cmpi "slt", %15, %c0 : index
          %17 = affine_apply #map0(%i3, %i6)
          %18 = cmpi "slt", %17, %4 : index
          %19 = affine_apply #map0(%i3, %i6)
          %20 = affine_apply #map1(%4, %c1)
          %21 = select %18, %19, %20 : index
          %22 = select %16, %c0, %21 : index
          %23 = load %0[%14, %i1, %i2, %22] : memref<?x?x?x?xf32>
          store %23, %5[%i6, %i5, %i4] : memref<5x4x3xf32>
        }
      }
    }
    %24 = load %6[%c0] : memref<1xvector<5x4x3xf32>>
    dealloc %5 : memref<5x4x3xf32>
```

In particular notice that only 3 out of the 4-d accesses are clipped: this
corresponds indeed to the number of dimensions in the super-vector.

This CL also addresses the cleanups resulting from the review of the prevous
CL and performs some refactoring to simplify the abstraction.

PiperOrigin-RevId: 227367414
2019-03-29 14:50:23 -07:00
Chris Lattner a250643ec8 Merge together the CFG/ML function paths in the CSE pass. I did a first pass
on this to merge together the classes, but there may be other simplification
possible.  I'll leave that to riverriddle@ as future work.

This is step 29/n towards merging instructions and statements.

PiperOrigin-RevId: 227328680
2019-03-29 14:50:08 -07:00
Chris Lattner 7974889f54 Update and generalize various passes to work on both CFG and ML functions,
simplifying them in minor ways.  The only significant cleanup here
is the constant folding pass.  All the other changes are simple and easy,
but this is still enough to shrink the compiler by 45LOC.

The one pass left to merge is the CSE pass, which will be move involved, so I'm
splitting it out to its own patch (which I'll tackle right after this).

This is step 28/n towards merging instructions and statements.

PiperOrigin-RevId: 227328115
2019-03-29 14:49:52 -07:00
Chris Lattner 3c8fc797de Simplify the remapFunctionAttrs logic, merging CFG/ML function handling.
Remove an unnecessary restriction in forward substitution.  Slightly
simplify LLVM IR lowering, which previously would crash if given an ML
function, it should now produce a clean error if given a function with an
if/for instruction in it, just like it does any other unsupported op.

This is step 27/n towards merging instructions and statements.

PiperOrigin-RevId: 227324542
2019-03-29 14:49:35 -07:00
Chris Lattner 4bd9f93606 Simplify GreedyPatternRewriteDriver now that functions are merged into one
representation, shrinking by 70LOC.  The PatternRewriter class can probably
also be simplified as well, but one step at a time.

This is step 26/n towards merging instructions and statements.  NFC.

PiperOrigin-RevId: 227324218
2019-03-29 14:49:20 -07:00
Uday Bondhugula 18fbc3e170 Drop unusued HyperRectangularSet.h/.cpp, given the new design being worked on.
- drop these ununsed/incomplete sketches given the new design
  @albertcohen is working on, and given that FlatAffineConstraints is now
  stable and fast enough for all the analyses/transforms that depend on it.

PiperOrigin-RevId: 227322739
2019-03-29 14:49:03 -07:00
Uday Bondhugula f12182157e Introduce PostDominanceInfo, fix properlyDominates() for Instructions
- introduce PostDominanceInfo in the right/complete way and use that for post
  dominance check in store-load forwarding
- replace all uses of Analysis/Utils::dominates/properlyDominates with
  DominanceInfo::dominates/properlyDominates
- drop all redundant copies of dominance methods in Analysis/Utils/
- in pipeline-data-transfer, replace dominates call with a much less expensive
  check; similarly, substitute dominates() in checkMemRefAccessDependence with
  a simpler check suitable for that context
- fix a bug in properlyDominates
- improve doc for 'for' instruction 'body'

PiperOrigin-RevId: 227320507
2019-03-29 14:48:44 -07:00
Uday Bondhugula cea9f28a2c Fix dominates() for block's.
- dominates() for blocks was assuming that there was only a single block at the
  top level whenever there was a hierarchy of blocks (as in the case of 'for'/'if'
  instructions).
- fix the comments as well

PiperOrigin-RevId: 227319738
2019-03-29 14:48:28 -07:00
Chris Lattner ae618428f6 Greatly simplify the ConvertToCFG pass, converting it from a module pass to a
function pass, and eliminating the need to copy over code and do
interprocedural updates.  While here, also improve it to make fewer empty
blocks, and rename it to "LowerIfAndFor" since that is what it does.  This is
a net reduction of ~170 lines of code.

As drive-bys, change the splitBlock method to *not* insert an unconditional
branch, since that behavior is annoying for all clients.  Also improve the
AsmPrinter to not crash when a block is referenced that isn't linked into a
function.

PiperOrigin-RevId: 227308856
2019-03-29 14:48:13 -07:00
Uday Bondhugula 545f3ce430 Fix ASAN failure in memref-dataflow-opt
- memrefsToErase had duplicates inserted into it; switch to SmallPtrSet.

PiperOrigin-RevId: 227299306
2019-03-29 14:47:58 -07:00
Feng Liu dfee0a6e9b Make PrintOpStatsPass a module pass
PrintOpStatsPass is maintaining state (op stats ) across functions and doing
per-module work - it should be a module pass.

PiperOrigin-RevId: 227294151
2019-03-29 14:47:43 -07:00
Uday Bondhugula b9fe6be6d4 Introduce memref store to load forwarding - a simple memref dataflow analysis
- the load/store forwarding relies on memref dependence routines as well as
  SSA/dominance to identify the memref store instance uniquely supplying a value
  to a memref load, and replaces the result of that load with the value being
  stored. The memref is also deleted when possible if only stores remain.

- add methods for post dominance for MLFunction blocks.

- remove duplicated getLoopDepth/getNestingDepth - move getNestingDepth,
  getMemRefAccess, getNumCommonSurroundingLoops into Analysis/Utils (were
  earlier static)

- add a helper method in FlatAffineConstraints - isRangeOneToOne.

PiperOrigin-RevId: 227252907
2019-03-29 14:47:28 -07:00
Uday Bondhugula 6e3462d251 Fix b/122139732; update FlatAffineConstraints::isEmpty() to eliminate IDs in a
better order.

- update isEmpty() to eliminate IDs in a better order. Speed improvement for
  complex cases (for eg. high-d reshape's involving mod's/div's).
- minor efficiency update to projectOut (was earlier making an extra albeit
  benign call to gaussianEliminateIds) (NFC).
- move getBestIdToEliminate further up in the file (NFC).
- add the failing test case.
- add debug info to checkMemRefAccessDependence.

PiperOrigin-RevId: 227244634
2019-03-29 14:47:13 -07:00
Chris Lattner dffc589ad2 Extend InstVisitor and Walker to handle arbitrary CFG functions, expand the
Function::walk functionality into f->walkInsts/Ops which allows visiting all
instructions, not just ops.  Eliminate Function::getBody() and
Function::getReturn() helpers which crash in CFG functions, and were only kept
around as a bridge.

This is step 25/n towards merging instructions and statements.

PiperOrigin-RevId: 227243966
2019-03-29 14:46:58 -07:00
Chris Lattner 8ef2552df7 Have the asmprinter take advantage of the new capabilities of the asmparser, by
printing the entry block in a CFG function's argument line.  Since I'm touching
all of the testcases anyway, change the argument list from printing as
"%arg : type" to "%arg: type" which is more consistent with bb arguments.

In addition to being more consistent, this is a much nicer look for cfg functions.

PiperOrigin-RevId: 227240069
2019-03-29 14:46:29 -07:00
Chris Lattner aaa1d77e96 Clean up and improve the parser handling of basic block labels, now that we
have a designator.  This improves diagnostics and merges handling between CFG
and ML functions more.  This also eliminates hard coded parser knowledge of
terminator keywords, allowing dialects to define their own terminators.

PiperOrigin-RevId: 227239398
2019-03-29 14:46:13 -07:00
Chris Lattner 37579ae8c4 Introduce ^ as a basic block sigil, eliminating an ambiguity on the MLIR
syntax.

PiperOrigin-RevId: 227234174
2019-03-29 14:45:59 -07:00
Chris Lattner 56e2a6cc3b Merge the verifier logic for all functions into a unified framework, this
requires enhancing DominanceInfo to handle the structure of an ML function,
which is required anyway.  Along the way, this also fixes a const correctness
problem with Instruction::getBlock().

This is step 24/n towards merging instructions and statements.

PiperOrigin-RevId: 227228900
2019-03-29 14:45:43 -07:00
Chris Lattner 4a96a11d6d Enhance parsing of CFG and Ext functions to optionally allow named arguments in
the function signature, giving them common functionality to ml functions.  This
is a strictly additive patch that adds new capability without changing behavior
in a significant way (other than a few diagnostic cleanups).  A subsequent
patch will change the printer to use this behavior, which will require updating
a ton of testcases.  :)

This exposes the fact that we need to make a grammar change for block
arguments, as is tracked by b/122119779

This is step 23/n towards merging instructions and statements, and one of the
first steps towards eliminating the "cfg vs ml" distinction at a syntax and
semantic level.

PiperOrigin-RevId: 227228342
2019-03-29 14:45:28 -07:00
Chris Lattner 5b9c3f7cdb Tidy up references to "basic blocks" that should refer to blocks now. NFC.
PiperOrigin-RevId: 227196077
2019-03-29 14:44:59 -07:00
Chris Lattner be9ee4a98e Merge parser logic for CFG and ML functions, shrinking the code
by ~80 lines.  This causes a slight change to diagnostics, but
is otherwise behavior preserving.

This is step 22/n towards merging instructions and statements, MFC.

PiperOrigin-RevId: 227187857
2019-03-29 14:44:44 -07:00
Chris Lattner 456ad6a8e0 Standardize naming of statements -> instructions, revisting the code base to be
consistent and moving the using declarations over.  Hopefully this is the last
truly massive patch in this refactoring.

This is step 21/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227178245
2019-03-29 14:44:30 -07:00
Uday Bondhugula b1d9cc4d1e Extend/complete dependence tester to utilize local var info.
- extend/complete dependence tester to utilize local var info while adding
  access function equality constraints; one more step closer to get slicing
  based fusion working in the general case of affine_apply's involving mod's/div's.
- update test case to reflect more accurate dependence information; remove
  inaccurate comment on test case mod_deps.
- fix a minor "bug" in equality addition in addMemRefAccessConstraints (doesn't
  affect correctness, but the fixed version is more intuitive).
- some more surrounding code clean up
- move simplifyAffineExpr out of anonymous AffineExprFlattener class - the
  latter has state, and the former should reside outside.

PiperOrigin-RevId: 227175600
2019-03-29 14:44:14 -07:00
Chris Lattner 315a466aed Rename BasicBlock and StmtBlock to Block, and make a pass cleaning it up. I did not make an effort to rename all of the 'bb' names in the codebase, since they are still correct and any specific missed once can be fixed up on demand.
The last major renaming is Statement -> Instruction, which is why Statement and
Stmt still appears in various places.

This is step 19/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227163082
2019-03-29 14:43:58 -07:00
Jacques Pienaar 2a463c36b1 Add convenience wrapper for operator in tblgen
Add convenience wrapper to make it easier to iterate over attributes and operands of operator defined in TableGen file. Use this class in RewriterGen (not used in the op generator yet, will do shortly). Change the RewriterGen to pass the bound arguments explicitly, this is in preparation for multi-op matching.

PiperOrigin-RevId: 227156748
2019-03-29 14:43:43 -07:00
Chris Lattner 69f9f6e21c Merge ext/cfg/ml function printing logic in the AsmPrinter (shrinking it
by about 100 LOC), without changing any existing behavior.

This is step 20/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227155000
2019-03-29 14:43:29 -07:00
Chris Lattner 69d9e990fa Eliminate the using decls for MLFunction and CFGFunction standardizing on
Function.

This is step 18/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227139399
2019-03-29 14:43:13 -07:00
Chris Lattner d798f9bad5 Rename BBArgument -> BlockArgument, Op::getOperation -> Op::getInst(),
StmtResult -> InstResult, StmtOperand -> InstOperand, and remove the old names.

This is step 17/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227121537
2019-03-29 14:42:40 -07:00
Chris Lattner 5187cfcf03 Merge Operation into OperationInst and standardize nomenclature around
OperationInst.  This is a big mechanical patch.

This is step 16/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227093712
2019-03-29 14:42:23 -07:00
Chris Lattner 471c976413 Rework inherentance hierarchy: Operation now derives from Statement, and
OperationInst derives from it.  This allows eliminating some forwarding
functions, other complex code handling multiple paths, and the 'isStatement'
bit tracked by Operation.

This is the last patch I think I can make before the big mechanical change
merging Operation into OperationInst, coming next.

This is step 15/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227077411
2019-03-29 14:41:49 -07:00
Feng Liu 9b20a4ccdf add a method to get FloatAttr value as double
Sometimes we have to get the raw value of the FloatAttr to invoke APIs from
non-MLIR libraries (i.e. in the tpu_ops.inc and convert_tensor.cc files). Using
`FloatAttr::getValue().convertToFloat()` and
`FloatAttr::getValue().convertToDouble()` is not safe because interally they
checke the semantics of the APFloat in the attribute, and the semantics is not
always specified (the default value is f64 then convertToFloat will fail) or
inferred incorrectly (for example, using 1.0 instead of 1.f for IEEEFloat).
Calling these convert methods without knowing the semantics can usually crash
the compiler.

This new method converts the value of a FloatAttr to double even if it loses
precision. Currently this method can be used to read in f32 data from arrays.

PiperOrigin-RevId: 227076616
2019-03-29 14:41:34 -07:00
Chris Lattner 1b430f1d32 Delicately re-layer Operation, Statement, and OperationStmt, reworking
#includes so Statements.h includes Operation.h but nothing else does.  This is
in preparation to eliminate the Operation class and the complexity it brings
with it.  I split this patch off because it is just moving stuff around, the
next patch will be more complex.

This is step 14/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227071777
2019-03-29 14:41:05 -07:00
Chris Lattner 4fbcd1ac52 Minor renamings: Trim the "Stmt" prefix off
StmtSuccessorIterator/StmtSuccessorIterator, and rename and move the
CFGFunctionViewGraph pass to ViewFunctionGraph.

This is step 13/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227069438
2019-03-29 14:40:51 -07:00
Uday Bondhugula 294687ef59 Fix affine expr flattener bug introduced by cl/225452174.
- inconsistent local var constraint size when repeatedly using the same
  flattener for all expressions in a map.

PiperOrigin-RevId: 227067836
2019-03-29 14:40:37 -07:00
Chris Lattner 4c05f8cac6 Merge CFGFuncBuilder/MLFuncBuilder/FuncBuilder together into a single new
FuncBuilder class.  Also rename SSAValue.cpp to Value.cpp

This is step 12/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227067644
2019-03-29 14:40:22 -07:00
Chris Lattner 3f190312f8 Merge SSAValue, CFGValue, and MLValue together into a single Value class, which
is the new base of the SSA value hierarchy.  This CL also standardizes all the
nomenclature and comments to use 'Value' where appropriate.  This also eliminates a large number of cast<MLValue>(x)'s, which is very soothing.

This is step 11/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227064624
2019-03-29 14:40:06 -07:00
Chris Lattner 776b035646 Eliminate the Instruction, BasicBlock, CFGFunction, MLFunction, and ExtFunction classes, using the Statement/StmtBlock hierarchy and Function instead.
This *only* changes the internal data structures, it does not affect the user visible syntax or structure of MLIR code.  Function gets new "isCFG()" sorts of predicates as a transitional measure.

This patch is gross in a number of ways, largely in an effort to reduce the amount of mechanical churn in one go.  It introduces a bunch of using decls to keep the old names alive for now, and a bunch of stuff needs to be renamed.

This is step 10/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227044402
2019-03-29 14:39:49 -07:00
Alex Zinenko a63f440601 LoopAnalysis: isContiguousAccess fail gracefully
Existing implementation of isContiguousAccess asserts that one of the
function arguments is within certain range, depending on another parameter.
However, the value of this argument may come from outside, in particular in the
loop vectorization pass it may come from command line arguments.  This leads
to 'mlir-opt' crashing on an assertion depending on flags.  Handle the error
gracefully by reporting error returning a negative result instead.  This
negative result prevents any further transformation by the vectorizer so the IR
remains valid.

PiperOrigin-RevId: 227029496
2019-03-29 14:39:34 -07:00
Jacques Pienaar 057984d05d Move print op stats pass to analysis.
Move PrintOpStatsPass out of tools and to other passes (moved to Analysis as it
doesn't modify the program but it is different than the other analysis passes
as it is only consumer at present is the user).

PiperOrigin-RevId: 227018996
2019-03-29 14:39:19 -07:00
Chris Lattner abf72a8bb1 Rename findFunction from the ML side of the house to be named getFunction(),
making it more similar to the CFG side of things.  It is true that in a deeply
nested case that this is not a guaranteed O(1) time operation, and that 'get'
could lead compiler hackers to think this is cheap, but we need to merge these
and we can look into solutions for this in the future if it becomes a problem
in practice.

This is step 9/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 226983931
2019-03-29 14:38:49 -07:00
Mehdi Amini 4e5337601e Inline Instruction's operands as TrailingObjects
For performance/memory saving purpose, having the Instruction holding a
std::vector for the operands isn't a really good tradeoff.  The only reason for
this was to support adding/removing easily BasicBlock arguments to Terminator.
Since this isn't the most common operation, we instead force a pre-allocated
list of operands on Instructions at creation time.
PiperOrigin-RevId: 226981227
2019-03-29 14:38:34 -07:00
Chris Lattner 036f87b15f Rename CFGFunctionGraphTraits.h -> FunctionGraphTraits.h and add
graph specializations for doing CFG traversals of ML Functions, making the two
sorts of functions have the same capabilities.

This is step 8/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 226968502
2019-03-29 14:38:19 -07:00
Chris Lattner 3bd8ff6699 Eliminate the MLFuncArgument class representing arguments to MLFunctions: use the
BlockArgument arguments of the entry block instead.  This makes MLFunctions and
CFGFunctions work more similarly.

This is step 7/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 226966975
2019-03-29 14:38:04 -07:00
Chris Lattner 5ff0001dc7 Introduce a new StmtBlockList type to hold a list of StmtBlocks. Use it in
MLFunction, IfStmt, ForStmt even though they currently only contain exactly one
block in that list.

This is step 6/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 226960278
2019-03-29 14:37:49 -07:00
Feng Liu 63068da4d9 Support NameLoc and CallSiteLoc for mlir::Location
The NameLoc can be used to represent a variable, node or method. The
CallSiteLoc has two fields, one represents the concrete location and another
one represents the caller's location. Multiple CallSiteLocs can be chained as
a call stack.

For example, the following call stack
```
AAA
at file1:1
at file2:135
at file3:34
```

can be formed by call0:

```
auto name = NameLoc::get("AAA");
auto file1 = FileLineColLoc::get("file1", 1);
auto file2 = FileLineColLoc::get("file2", 135);
auto file3 = FileLineColLoc::get("file3", 34);
auto call2 = CallSiteLoc::get(file2, file3);
auto call1 = CallSiteLoc::get(file1, call2);
auto call0 = CallSiteLoc::get(name, call1);
```

PiperOrigin-RevId: 226941797
2019-03-29 14:37:34 -07:00
Alex Zinenko eb0f9f37af SuperVectorization: fix 'isa' assertion
Supervectorization uses null pointers to SSA values as a means of communicating
the failure to vectorize.  In operation vectorization, all operations producing
the values of operation arguments must be vectorized for the given operation to
be vectorized.  The existing check verified if any of the value "def"
statements was vectorized instead, sometimes leading to assertions inside `isa`
called on a null pointer.  Fix this to check that all "def" statements were
vectorized.

PiperOrigin-RevId: 226941552
2019-03-29 14:37:20 -07:00
Alex Zinenko 9403f80dd3 LLVM IR lowering: support SubIOp and SubFOp
The binary subtraction operations were not supported by the lowering because
they were not essential for the testing flow.  Add support for these
operations.

PiperOrigin-RevId: 226941463
2019-03-29 14:37:05 -07:00
Jacques Pienaar 58d50a6325 Rename convenience methods to make type explicit.
PiperOrigin-RevId: 226939383
2019-03-29 14:36:50 -07:00
Chris Lattner d613f5ab65 Refactor MLFunction to contain a StmtBlock for its body instead of inheriting
from it.  This is necessary progress to squaring away the parent relationship
that a StmtBlock has with its enclosing if/for/fn, and makes room for functions
to have more than one block in the future.  This also removes IfClause and ForStmtBody.

This is step 5/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 226936541
2019-03-29 14:36:35 -07:00
Chris Lattner 9a4060d3f5 Eliminate the ability to add operands to an instruction, used in a narrow case
for SSA values in terminators, but easily worked around.  At the same time,
move the StmtOperand list in a OperationStmt to the end of its trailing
objects list so we can *reduce* the number of operands, without affecting
offsets to the other stuff in the allocation.

This is important because we want OperationStmts to be consequtive, including
their operands - we don't want to use an std::vector of operands like
Instructions have.

This is patch 4/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 226865727
2019-03-29 14:36:20 -07:00
Chris Lattner eadaa1101c Implement StmtBlocks support for arguments and pred/succ iteration. This isn't
tested yet, but will when stuff starts switching over to it.  This is part 3/n of merging CFGFunctions and MLFunctions.

PiperOrigin-RevId: 226794787
2019-03-29 14:36:05 -07:00
Chris Lattner 87ce4cc501 Per review on the previous CL, drop MLFuncBuilder::createOperation, changing
clients to use OperationState instead.  This makes MLFuncBuilder more similiar
to CFGFuncBuilder.  This whole area will get tidied up more when cfg and ml
worlds get unified.  This patch is just gardening, NFC.

PiperOrigin-RevId: 226701959
2019-03-29 14:35:49 -07:00