platform/upstream/llvm.git
5 years ago[TableGen] Use tblgen::DagLeaf to model DAG arguments
Lei Zhang [Fri, 1 Feb 2019 23:40:22 +0000 (15:40 -0800)]
[TableGen] Use tblgen::DagLeaf to model DAG arguments

This CL added a tblgen::DagLeaf wrapper class with several helper methods for handling
DAG arguments. It helps to refactor the rewriter generation logic to be more higher
level.

This CL also added a tblgen::ConstantAttr wrapper class for constant attributes.

PiperOrigin-RevId: 232050683

5 years agoUpdate link
Jacques Pienaar [Fri, 1 Feb 2019 23:31:24 +0000 (15:31 -0800)]
Update link

PiperOrigin-RevId: 232049075

5 years agoFix Block::getNumSuccessors()
Uday Bondhugula [Fri, 1 Feb 2019 21:18:20 +0000 (13:18 -0800)]
Fix Block::getNumSuccessors()

- getTerminator() on a block can return nullptr; moreover, blocks that are improperly
  constructed/transformed by utilities/passes may not have terminators even for the
  top-level blocks

PiperOrigin-RevId: 232025963

5 years agoFix use of llvm::Module::getOrInsertFunction after the upstream opaque pointer type...
River Riddle [Fri, 1 Feb 2019 19:04:48 +0000 (11:04 -0800)]
Fix use of llvm::Module::getOrInsertFunction after the upstream opaque pointer type changes.

PiperOrigin-RevId: 232002583

5 years agoCleanup EDSCs and start a functional auto-generated library of custom Ops
Nicolas Vasilache [Fri, 1 Feb 2019 17:16:31 +0000 (09:16 -0800)]
Cleanup EDSCs and start a functional auto-generated library of custom Ops

This CL applies the following simplifications to EDSCs:
1. Rename Block to StmtList because an MLIR Block is a different, not yet
supported, notion;
2. Rework Bindable to drop specific storage and just use it as a simple wrapper
around Expr. The only value of Bindable is to force a static cast when used by
the user to bind into the emitter. For all intended purposes, Bindable is just
a lightweight check that an Expr is Unbound. This simplifies usage and reduces
the API footprint. After playing with it for some time, it wasn't worth the API
cognition overhead;
3. Replace makeExprs and makeBindables by makeNewExprs and copyExprs which is
more explicit and less easy to misuse;
4. Add generally useful functionality to MLIREmitter:
  a. expose zero and one for the ubiquitous common lower bounds and step;
  b. add support to create already bound Exprs for all function arguments as
  well as shapes and views for Exprs bound to memrefs.
5. Delete Stmt::operator= and replace by a `Stmt::set` method which is more
explicit.
6. Make Stmt::operator Expr() explicit.
7. Indexed.indices assertions are removed to pave the way for expressing slices
and views as well as to work with 0-D memrefs.

The CL plugs those simplifications with TableGen and allows emitting a full MLIR function for
pointwise add.

This "x.add" op is both type and rank-agnostic (by allowing ArrayRef of Expr
passed to For loops) and opens the door to spinning up a composable library of
existing and custom ops that should automate a lot of the tedious work in
TF/XLA -> MLIR.

Testing needs to be significantly improved but can be done in a separate CL.

PiperOrigin-RevId: 231982325

5 years agoDefine an detail::OperandStorage class to handle managing instruction operands. This...
River Riddle [Fri, 1 Feb 2019 05:25:17 +0000 (21:25 -0800)]
Define an detail::OperandStorage class to handle managing instruction operands. This class stores operands in a similar way to SmallVector except for two key differences. The first is the inline storage, which is a trailing objects array. The second is that being able to dynamically resize the operand list is optional. This means that we can enable the cases where operations need to change the number of operands after construction without losing the spatial locality benefits of the common case (operation instructions / non-control flow instructions with a lifetime fixed number of operands).

PiperOrigin-RevId: 231910497

5 years agoAdd fallback to native code op builder specification for patterns.
Jacques Pienaar [Fri, 1 Feb 2019 01:57:06 +0000 (17:57 -0800)]
Add fallback to native code op builder specification for patterns.

This allow for arbitrarily complex builder patterns which is meant to cover initial cases while the modelling is improved and long tail cases/cases for which expanding the DSL would result in worst overall system.

NFC just sorting the emit replace methods alphabetical in the class and file body.

PiperOrigin-RevId: 231890352

5 years agoEnable using constant attribute as matchers.
Jacques Pienaar [Thu, 31 Jan 2019 16:33:47 +0000 (08:33 -0800)]
Enable using constant attribute as matchers.

Straight roll-forward of cl/231322019 that got accidentally reverted in the move.

PiperOrigin-RevId: 231791464

5 years agoPost commit fixes
Nicolas Vasilache [Thu, 31 Jan 2019 16:05:11 +0000 (08:05 -0800)]
Post commit fixes

This CL introduces a hotfix post refactoring of NestedMatchers:
- fix uninitialized read to skip
- avoid bumpptr allocating with 0 elements

Interestingly the latter issue only surfaced in fastbuild mode with no-san and
manifested itself by a SIGILL. All other combinations that were tried failed to
reproduce the issue (dbg, opt, fastbuild with asan)

PiperOrigin-RevId: 231787642

5 years agoAddress Performance issue in NestedMatcher
Nicolas Vasilache [Thu, 31 Jan 2019 15:16:29 +0000 (07:16 -0800)]
Address Performance issue in NestedMatcher

A performance issue was reported due to the usage of NestedMatcher in
ComposeAffineMaps. The main culprit was the ubiquitous copies that were
occuring when appending even a single element in `matchOne`.

This CL generally simplifies the implementation and removes one level of indirection by getting rid of
auxiliary storage as well as simplifying the API.
The users of the API are updated accordingly.

The implementation was tested on a heavily unrolled example with
ComposeAffineMaps and is now close in performance with an implementation based
on stateless InstWalker.

As a reminder, the whole ComposeAffineMaps pass is slated to disappear but the bug report was very useful as a stress test for NestedMatchers.

Lastly, the following cleanups reported by @aminim were addressed:
1. make NestedPatternContext scoped within runFunction rather than at the Pass level. This was caused by a previous misunderstanding of Pass lifetime;
2. use defensive assertions in the constructor of NestedPatternContext to make it clear a unique such locally scoped context is allowed to exist.

PiperOrigin-RevId: 231781279

5 years agoAddress cleanups from previous CL
Nicolas Vasilache [Thu, 31 Jan 2019 06:03:30 +0000 (22:03 -0800)]
Address cleanups from previous CL

This CL addresses some cleanups that were leftover after an incorrect rebase:
1. use StringSwitch
2. use // NOLINTNEXTLINE
3. remove a dead line of code

PiperOrigin-RevId: 231726640

5 years agoFix ASAN issue: snapshot edge list before loop which can modify this list.
MLIR Team [Thu, 31 Jan 2019 00:01:46 +0000 (16:01 -0800)]
Fix ASAN issue: snapshot edge list before loop which can modify this list.

PiperOrigin-RevId: 231686040

5 years agoLoopFusion: insert the source loop nest slice at a depth in the destination loop...
MLIR Team [Wed, 30 Jan 2019 23:53:41 +0000 (15:53 -0800)]
LoopFusion: insert the source loop nest slice at a depth in the destination loop nest which preserves dependences (above any loop carried or other dependences). This is accomplished by updating the maximum destination loop depth based on dependence checks between source loop nest loads and stores which access the memref on which the source loop nest has a store op. In addition, prevent fusing in source loop nests which write to memrefs which escape or are live out.

PiperOrigin-RevId: 231684492

5 years agoUpdate tests using affine maps to not rely on specific map numbers in the output...
River Riddle [Wed, 30 Jan 2019 19:33:32 +0000 (11:33 -0800)]
Update tests using affine maps to not rely on specific map numbers in the output IR. This is necessary to remove the dependency on ForInst not numbering the AffineMap bounds it has custom formatting for.

PiperOrigin-RevId: 231634812

5 years ago3000x speed improvement on compose-affine-maps by dropping NestedMatcher for
Uday Bondhugula [Wed, 30 Jan 2019 18:43:27 +0000 (10:43 -0800)]
3000x speed improvement on compose-affine-maps by dropping NestedMatcher for
a trivial inst walker :-) (reduces pass time from several minutes non-terminating to 120ms) - (fixes b/123541184)

- use a simple 7-line inst walker to collect affine_apply op's instead of the nested
  matcher; -compose-affine-maps pass runs in 120ms now instead of 5 minutes + (non-
  terminating / out of memory) - on a realistic test case that is 20,000 lines 12-d
  loop nest

- this CL is also pushing for simple existing/standard patterns unless there
  is a real efficiency issue (OTOH, fixing nested matcher to address this issue requires
  cl/231400521)

- the improvement is from swapping out the nested walker as opposed to from a bug
  or anything else that this CL changes

- update stale comment

PiperOrigin-RevId: 231623619

5 years agoStandardize the spelling of debug info to "debuginfo" in opt flags.
River Riddle [Wed, 30 Jan 2019 17:37:47 +0000 (09:37 -0800)]
Standardize the spelling of debug info to "debuginfo" in opt flags.

PiperOrigin-RevId: 231610337

5 years ago[tablegen] Use tblgen:: classes for NamedAttribute and Operand fields
Lei Zhang [Wed, 30 Jan 2019 14:05:27 +0000 (06:05 -0800)]
[tablegen] Use tblgen:: classes for NamedAttribute and Operand fields

This is another step towards hiding raw TableGen API calls.

PiperOrigin-RevId: 231580827

5 years ago[doc] Use table to list all attributes
Lei Zhang [Wed, 30 Jan 2019 14:02:57 +0000 (06:02 -0800)]
[doc] Use table to list all attributes

For each attribute, list its MLIR type and description.

PiperOrigin-RevId: 231580353

5 years ago[doc] Generate more readable description for attributes
Lei Zhang [Wed, 30 Jan 2019 13:59:58 +0000 (05:59 -0800)]
[doc] Generate more readable description for attributes

This CL added "description" field to AttrConstraint and Attr, like what we
have for type classes.

PiperOrigin-RevId: 231579853

5 years ago[doc] Generate more readable description for operands
Lei Zhang [Wed, 30 Jan 2019 13:57:39 +0000 (05:57 -0800)]
[doc] Generate more readable description for operands

This CL mandated TypeConstraint and Type to provide descriptions and fixed
various subclasses and definitions to provide so. The purpose is to enforce
good documentation; using empty string as the default just invites oversight.

PiperOrigin-RevId: 231579629

5 years agoFold CallIndirectOp to CallOp when the callee operand is a known constant function.
River Riddle [Wed, 30 Jan 2019 02:08:28 +0000 (18:08 -0800)]
Fold CallIndirectOp to CallOp when the callee operand is a known constant function.

PiperOrigin-RevId: 231511697

5 years agoUse formatv for the error instead of string stream.
Jacques Pienaar [Wed, 30 Jan 2019 01:39:52 +0000 (17:39 -0800)]
Use formatv for the error instead of string stream.

PiperOrigin-RevId: 231507680

5 years agoInclude op results in generate TensorFlow/TFLite op docs
Lei Zhang [Tue, 29 Jan 2019 18:28:56 +0000 (10:28 -0800)]
Include op results in generate TensorFlow/TFLite op docs

* Emitted result lists for ops.
* Changed to allow empty summary and description for ops.
* Avoided indenting description to allow proper MarkDown rendering of
  formatting markers inside description content.
* Used fixed width font for operand/attribute names.
* Massaged TensorFlow op docs and generated dialect op doc.

PiperOrigin-RevId: 231427574

5 years agoFix getFullMemRefAsRegion() and FlatAffineConstraints::reset
Uday Bondhugula [Tue, 29 Jan 2019 18:24:30 +0000 (10:24 -0800)]
Fix getFullMemRefAsRegion() and FlatAffineConstraints::reset

PiperOrigin-RevId: 231426734

5 years agoTableGen: Use DAG for op results
Lei Zhang [Tue, 29 Jan 2019 18:03:17 +0000 (10:03 -0800)]
TableGen: Use DAG for op results

Similar to op operands and attributes, use DAG to specify operation's results.
This will allow us to provide names and matchers for outputs.

Also Defined `outs` as a marker to indicate the start of op result list.

PiperOrigin-RevId: 231422455

5 years agoSupport fusing loop nests which require insertion into a new instruction Block positi...
MLIR Team [Tue, 29 Jan 2019 17:36:41 +0000 (09:36 -0800)]
Support fusing loop nests which require insertion into a new instruction Block position while preserving dependences, opening up additional fusion opportunities.
- Adds SSA Value edges to the data dependence graph used in the loop fusion pass.

PiperOrigin-RevId: 231417649

5 years agoPrefix Operator getter methods with "get" to be consistent
Lei Zhang [Tue, 29 Jan 2019 17:27:04 +0000 (09:27 -0800)]
Prefix Operator getter methods with "get" to be consistent

PiperOrigin-RevId: 231416230

5 years agoRecommit: Define a AffineOps dialect as well as an AffineIfOp operation. Replace...
River Riddle [Tue, 29 Jan 2019 05:23:53 +0000 (21:23 -0800)]
Recommit: Define a AffineOps dialect as well as an AffineIfOp operation. Replace all instances of IfInst with AffineIfOp and delete IfInst.

PiperOrigin-RevId: 231342063

5 years agoIntroduce python bindings for MLIR EDSCs
Nicolas Vasilache [Tue, 29 Jan 2019 04:29:46 +0000 (20:29 -0800)]
Introduce python bindings for MLIR EDSCs

This CL also introduces a set of python bindings using pybind11. The bindings
are exercised using a `test_py2andpy3.py` test suite that works for both
python 2 and 3.

`test_py3.py` on the other hand uses the more idiomatic,
python 3 only "PEP 3132 -- Extended Iterable Unpacking" to implement a rank
and type-agnostic copy with transposition.

Because python assignment is by reference, we cannot easily make the
assignment operator use the same type of sugaring as in C++; i.e. the
following:

```cpp
Stmt block = edsc::Block({
  For(ivs, zeros, shapeA, ones, {
    C[ivs] = IA[ivs] + IB[ivs]
})});
```

has no equivalent in the native Python EDSCs at this time.

However, the sugaring can be built as a simple DSL in python and is left as
future work.

PiperOrigin-RevId: 231337667

5 years agoMove google-mlir to google_mlir
Nicolas Vasilache [Tue, 29 Jan 2019 02:51:53 +0000 (18:51 -0800)]
Move google-mlir to google_mlir

Python modules cannot be defined under a directory that has a `-` character in its name inside of Google code.
Rename to `google_mlir` which circumvents this limitation.

PiperOrigin-RevId: 231329321

5 years ago Automated rollback of changelist 231318632.
Nicolas Vasilache [Tue, 29 Jan 2019 02:28:43 +0000 (18:28 -0800)]
Automated rollback of changelist 231318632.

PiperOrigin-RevId: 231327161

5 years agoEnable using constant attribute as matchers.
Jacques Pienaar [Tue, 29 Jan 2019 01:46:27 +0000 (17:46 -0800)]
Enable using constant attribute as matchers.

Update to allow constant attribute values to be used to match or as result in rewrite rule. Define variable ctx in the matcher to allow matchers to refer to the context of the operation being matched.

PiperOrigin-RevId: 231322019

5 years agoDefine a AffineOps dialect as well as an AffineIfOp operation. Replace all instances...
River Riddle [Tue, 29 Jan 2019 01:20:44 +0000 (17:20 -0800)]
Define a AffineOps dialect as well as an AffineIfOp operation. Replace all instances of IfInst with AffineIfOp and delete IfInst.

PiperOrigin-RevId: 231318632

5 years agoAdd a C API for EDSCs in other languages + python
Nicolas Vasilache [Mon, 28 Jan 2019 22:32:00 +0000 (14:32 -0800)]
Add a C API for EDSCs in other languages + python

This CL adds support for calling EDSCs from other languages than C++.
Following the LLVM convention this CL:
1. declares simple opaque types and a C API in mlir-c/Core.h;
2. defines the implementation directly in lib/EDSC/Types.cpp and
lib/EDSC/MLIREmitter.cpp.

Unlike LLVM however the nomenclature for these types and API functions is not
well-defined, naming suggestions are most welcome.

To avoid the need for conversion functions, Types.h and MLIREmitter.h include
mlir-c/Core.h and provide constructors and conversion operators between the
mlir::edsc type and the corresponding C type.

In this first commit, mlir-c/Core.h only contains the types for the C API
to allow EDSCs to work from Python. This includes both a minimal set of core
MLIR
types (mlir_context_t, mlir_type_t, mlir_func_t) as well as the EDSC types
(edsc_mlir_emitter_t, edsc_expr_t, edsc_stmt_t, edsc_indexed_t). This can be
restructured in the future as concrete needs arise.

For now, the API only supports:
1. scalar types;
2. memrefs of scalar types with static or symbolic shapes;
3. functions with input and output of these types.

The C API is not complete wrt ownership semantics. This is in large part due
to the fact that python bindings are written with Pybind11 which allows very
idiomatic C++ bindings. An effort is made to write a large chunk of these
bindings using the C API but some C++isms are used where the design benefits
from this simplication. A fully isolated C API will make more sense once we
also integrate with another language like Swift and have enough use cases to
drive the design.

Lastly, this CL also fixes a bug in mlir::ExecutionEngine were the order of
declaration of llvmContext and the JIT result in an improper order of
destructors (which used to crash before the fix).

PiperOrigin-RevId: 231290250

5 years agoAdd tblgen::Pattern to model Patterns defined in TableGen
Lei Zhang [Mon, 28 Jan 2019 22:04:40 +0000 (14:04 -0800)]
Add tblgen::Pattern to model Patterns defined in TableGen

Similar to other tblgen:: abstractions, tblgen::Pattern hides the native TableGen
API and provides a nicer API that is more coherent with the TableGen definitions.

PiperOrigin-RevId: 231285143

5 years agoDefine mAttr in terms of AttrConstraint.
Jacques Pienaar [Mon, 28 Jan 2019 15:13:40 +0000 (07:13 -0800)]
Define mAttr in terms of AttrConstraint.

* Matching an attribute and specifying a attribute constraint is the same thing executionally, so represent it such.
* Extract AttrConstraint helper to match TypeConstraint and use that where mAttr was previously used in RewriterGen.

PiperOrigin-RevId: 231213580

5 years agoReplace too obscure usage of functional::map by declare + reserve + loop.
Nicolas Vasilache [Mon, 28 Jan 2019 14:55:48 +0000 (06:55 -0800)]
Replace too obscure usage of functional::map by declare + reserve + loop.

Cleanup a usage of functional::map that is deemed too obscure in
`reindexAffineIndices`. Also fix a stale comment in `reindexAffineIndices`.

PiperOrigin-RevId: 231211184

5 years agoAdd value member to constant attribute specification base.
Jacques Pienaar [Mon, 28 Jan 2019 13:50:13 +0000 (05:50 -0800)]
Add value member to constant attribute specification base.

String specification of the default value is the common case so just make it so.

PiperOrigin-RevId: 231204081

5 years agoChange AffineApplyOp to produce a single result, simplifying the code that
Chris Lattner [Sun, 27 Jan 2019 17:33:19 +0000 (09:33 -0800)]
Change AffineApplyOp to produce a single result, simplifying the code that
works with it, and updating the g3docs.

PiperOrigin-RevId: 231120927

5 years agoChange the ForInst induction variable to be a block argument of the body instead...
River Riddle [Sat, 26 Jan 2019 20:40:12 +0000 (12:40 -0800)]
Change the ForInst induction variable to be a block argument of the body instead of the ForInst itself. This is a necessary step in converting ForInst into an operation.

PiperOrigin-RevId: 231064139

5 years agoDrop AffineMap::Null and IntegerSet::Null
Nicolas Vasilache [Sat, 26 Jan 2019 18:41:17 +0000 (10:41 -0800)]
Drop AffineMap::Null and IntegerSet::Null

Addresses b/122486036

This CL addresses some leftover crumbs in AffineMap and IntegerSet by removing
the Null method and cleaning up the constructors.

As the ::Null uses were tracked down, opportunities appeared to untangle some
of the Parsing logic and make it explicit where AffineMap/IntegerSet have
ambiguous syntax. Previously, ambiguous cases were hidden behind the implicit
pointer values of AffineMap* and IntegerSet* that were passed as function
parameters. Depending the values of those pointers one of 3 behaviors could
occur.

This parsing logic convolution is one of the rare cases where I would advocate
for code duplication. The more proper fix would be to make the syntax
unambiguous or to allow some lookahead.

PiperOrigin-RevId: 231058512

5 years agoCleanup resource management and rename recursive matchers
Nicolas Vasilache [Sat, 26 Jan 2019 14:59:23 +0000 (06:59 -0800)]
Cleanup resource management and rename recursive matchers

This CL follows up on a memory leak issue related to SmallVector growth that
escapes the BumpPtrAllocator.
The fix is to properly use ArrayRef and placement new to define away the
issue.

The following renaming is also applied:
1. MLFunctionMatcher -> NestedPattern
2. MLFunctionMatches -> NestedMatch

As a consequence all allocations are now guaranteed to live on the BumpPtrAllocator.

PiperOrigin-RevId: 231047766

5 years agoWrap cl::opt flags within passes in a category with the pass name. This improves...
River Riddle [Sat, 26 Jan 2019 06:14:04 +0000 (22:14 -0800)]
Wrap cl::opt flags within passes in a category with the pass name. This improves the help output of tools like mlir-opt.

Example:

dma-generate options:

  -dma-fast-mem-capacity                 - Set fast memory space  ...
  -dma-fast-mem-space=<uint>             - Set fast memory space  ...

loop-fusion options:

  -fusion-compute-tolerance=<number>     - Fractional increase in  ...
  -fusion-maximal                        - Enables maximal loop fusion

loop-tile options:

  -tile-size=<uint>                      - Use this tile size for  ...

loop-unroll options:

  -unroll-factor=<uint>                  - Use this unroll factor  ...
  -unroll-full                           - Fully unroll loops
  -unroll-full-threshold=<uint>          - Unroll all loops with  ...
  -unroll-num-reps=<uint>                - Unroll innermost loops  ...

loop-unroll-jam options:

  -unroll-jam-factor=<uint>              - Use this unroll jam factor ...

PiperOrigin-RevId: 231019363

5 years agoFinish removing multi-result affine maps from the testsuite, and disable them.
Chris Lattner [Sat, 26 Jan 2019 04:44:40 +0000 (20:44 -0800)]
Finish removing multi-result affine maps from the testsuite, and disable them.

PiperOrigin-RevId: 231014261

5 years agoAdd an option to improve the readibility of the printed MLIR debuginfo
Feng Liu [Sat, 26 Jan 2019 04:37:33 +0000 (20:37 -0800)]
Add an option to improve the readibility of the printed MLIR debuginfo

Use `-mlir-pretty-debuginfo` if the user wants line breaks between different callsite lines.
The print results before and after this CL are shown in the tests.

PiperOrigin-RevId: 231013812

5 years agoDrop unused result from affine map in test case - NFC
Uday Bondhugula [Sat, 26 Jan 2019 03:03:49 +0000 (19:03 -0800)]
Drop unused result from affine map in test case - NFC

PiperOrigin-RevId: 231008044

5 years agoMore updates of tests to move towards single result affine maps.
Chris Lattner [Sat, 26 Jan 2019 00:36:15 +0000 (16:36 -0800)]
More updates of tests to move towards single result affine maps.

PiperOrigin-RevId: 230991929

5 years agoUpdate replaceAllMemRefUsesWith to generate single result affine_apply's for
Uday Bondhugula [Sat, 26 Jan 2019 00:00:50 +0000 (16:00 -0800)]
Update replaceAllMemRefUsesWith to generate single result affine_apply's for
index remapping
- generate a sequence of single result affine_apply's for the index remapping
  (instead of one multi result affine_apply)
- update dma-generate and loop-fusion test cases; while on this, change test cases
  to use single result affine apply ops
- some fusion comment fix/cleanup

PiperOrigin-RevId: 230985830

5 years agoAdd a simple arity-agnostic invocation of JIT-compiled functions.
Nicolas Vasilache [Fri, 25 Jan 2019 22:57:30 +0000 (14:57 -0800)]
Add a simple arity-agnostic invocation of JIT-compiled functions.

This is useful to call generic function with unspecified number of arguments
e.g. when interfacing with ML frameworks.

PiperOrigin-RevId: 230974736

5 years agoUpdate createAffineComputationSlice to generate single result affine maps
Uday Bondhugula [Fri, 25 Jan 2019 22:06:32 +0000 (14:06 -0800)]
Update createAffineComputationSlice to generate single result affine maps

- Update createAffineComputationSlice to generate a sequence of single result
  affine apply ops instead of one multi-result affine apply
- update pipeline-data-transfer test case; while on this, also update the test
  case to use only single result affine maps, and make it more robust to
  change.

PiperOrigin-RevId: 230965478

5 years agoAllow operations to hold a blocklist and add support for parsing/printing a block...
River Riddle [Fri, 25 Jan 2019 20:48:25 +0000 (12:48 -0800)]
Allow operations to hold a blocklist and add support for parsing/printing a block list for verbose printing.

PiperOrigin-RevId: 230951462

5 years agoGeneric dialect conversion pass exercised by LLVM IR lowering
Alex Zinenko [Fri, 25 Jan 2019 20:46:53 +0000 (12:46 -0800)]
Generic dialect conversion pass exercised by LLVM IR lowering

This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.

It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.

The latter two things required, given the existing API, to create new functions
in the same module.  Eventually, this should converge with the rest of
PatternRewriter.  However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.

This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function.  Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks.  The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks.  The patterns are defined as
separate classes that can be table-generated in the future.

The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion.  It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen.  The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows.  Future
patches will add missing support before switching the translator in a single
patch.

PiperOrigin-RevId: 230951202

5 years agoUse a unique_ptr instead of manual deletion for PIMPL idiom (NFC)
Mehdi Amini [Fri, 25 Jan 2019 18:51:51 +0000 (10:51 -0800)]
Use a unique_ptr instead of manual deletion for PIMPL idiom (NFC)

PiperOrigin-RevId: 230930254

5 years agoPull TableGen op argument definitions into their own files
Lei Zhang [Fri, 25 Jan 2019 18:13:35 +0000 (10:13 -0800)]
Pull TableGen op argument definitions into their own files

PiperOrigin-RevId: 230923050

5 years agoSupport op removal patterns in TableGen
Lei Zhang [Fri, 25 Jan 2019 18:09:15 +0000 (10:09 -0800)]
Support op removal patterns in TableGen

This CL adds a new marker, replaceWithValue, to indicate that no new result
op is generated by applying a pattern. Instead, the matched DAG is replaced
by an existing SSA value.

Converted the tf.Identity converter to use the pattern.

PiperOrigin-RevId: 230922323

5 years agoFix return value logic / error reporting in -dma-generate
Uday Bondhugula [Fri, 25 Jan 2019 16:24:17 +0000 (08:24 -0800)]
Fix return value logic / error reporting in -dma-generate

PiperOrigin-RevId: 230906158

5 years agoSimple CPU runner
Alex Zinenko [Fri, 25 Jan 2019 11:16:06 +0000 (03:16 -0800)]
Simple CPU runner

This implements a simple CPU runner based on LLVM Orc JIT.  The base
functionality is provided by the ExecutionEngine class that compiles and links
the module, and provides an interface for obtaining function pointers to the
JIT-compiled MLIR functions and for invoking those functions directly.  Since
function pointers need to be casted to the correct pointer type, the
ExecutionEngine wraps LLVM IR functions obtained from MLIR into a helper
function with the common signature `void (void **)` where the single argument
is interpreted as a list of pointers to the actual arguments passed to the
function, eventually followed by a pointer to the result of the function.
Additionally, the ExecutionEngine is set up to resolve library functions to
those available in the current process, enabling support for, e.g., simple C
library calls.

For integration purposes, this also provides a simplistic runtime for memref
descriptors as expected by the LLVM IR code produced by MLIR translation.  In
particular, memrefs are transformed into LLVM structs (can be mapped to C
structs) with a pointer to the data, followed by dynamic sizes.  This
implementation only supports statically-shaped memrefs of type float, but can
be extened if necessary.

Provide a binary for the runner and a test that exercises it.

PiperOrigin-RevId: 230876363

5 years agoChange the dependence check in the loop fusion pass to use the MLIR instruction list...
MLIR Team [Fri, 25 Jan 2019 06:27:40 +0000 (22:27 -0800)]
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

5 years agoUpdate dma-generate: update for multiple load/store op's per memref
Uday Bondhugula [Fri, 25 Jan 2019 06:10:53 +0000 (22:10 -0800)]
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

5 years agoAdd order bit to instructions to lazily track dominance queries. This improves the...
River Riddle [Fri, 25 Jan 2019 01:16:30 +0000 (17:16 -0800)]
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

5 years agoloop-fusion: debug info cleanup
Uday Bondhugula [Fri, 25 Jan 2019 01:01:49 +0000 (17:01 -0800)]
loop-fusion: debug info cleanup

PiperOrigin-RevId: 230817383

5 years agoIncremental progress to move the testsuite towards single-result affine_apply
Chris Lattner [Thu, 24 Jan 2019 21:04:50 +0000 (13:04 -0800)]
Incremental progress to move the testsuite towards single-result affine_apply
instructions.

PiperOrigin-RevId: 230775607

5 years agoIntroduce a new operation hook point for implementing simple local
Chris Lattner [Thu, 24 Jan 2019 20:34:00 +0000 (12:34 -0800)]
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

5 years agoAdd cloning functionality to Block and Function, this also adds support for remapping...
River Riddle [Thu, 24 Jan 2019 20:25:30 +0000 (12:25 -0800)]
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

5 years agoMinor updates + cleanup to dma-generate
Uday Bondhugula [Thu, 24 Jan 2019 16:43:17 +0000 (08:43 -0800)]
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

5 years agoAdd a function pass to strip debug info from functions and instructions.
River Riddle [Thu, 24 Jan 2019 04:48:23 +0000 (20:48 -0800)]
Add a function pass to strip debug info from functions and instructions.

PiperOrigin-RevId: 230654315

5 years agoChange trailing locations printing to also print unknown locations. This will allow...
River Riddle [Thu, 24 Jan 2019 00:37:45 +0000 (16:37 -0800)]
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

5 years agoMigrate VectorOrTensorType/MemRefType shape api to use int64_t instead of int.
River Riddle [Wed, 23 Jan 2019 22:39:45 +0000 (14:39 -0800)]
Migrate VectorOrTensorType/MemRefType shape api to use int64_t instead of int.

PiperOrigin-RevId: 230605756

5 years agoAdd a method to construct a CallSiteLoc which represents a stack of locations.
Feng Liu [Wed, 23 Jan 2019 21:37:35 +0000 (13:37 -0800)]
Add a method to construct a CallSiteLoc which represents a stack of locations.

PiperOrigin-RevId: 230592860

5 years agoAdd asmparser/printer support for locations to make them round-trippable. Location...
River Riddle [Wed, 23 Jan 2019 21:11:23 +0000 (13:11 -0800)]
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

5 years agoUnify terms regarding assembly form to use generic vs. custom
Lei Zhang [Wed, 23 Jan 2019 19:26:56 +0000 (11:26 -0800)]
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

5 years agoFix single producer check in loop fusion pass.
MLIR Team [Wed, 23 Jan 2019 19:11:43 +0000 (11:11 -0800)]
Fix single producer check in loop fusion pass.

PiperOrigin-RevId: 230565482

5 years agoUpdate fusion cost model + some additional infrastructure and debug information for...
Uday Bondhugula [Wed, 23 Jan 2019 17:16:24 +0000 (09:16 -0800)]
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

5 years agoAdd support for Return in EDSCs
Nicolas Vasilache [Wed, 23 Jan 2019 15:39:49 +0000 (07:39 -0800)]
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

5 years agoloop unroll update: unroll factor one for a single iteration loop
Uday Bondhugula [Tue, 22 Jan 2019 23:48:07 +0000 (15:48 -0800)]
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

5 years agoFixing op description white space during doc emission.
Jacques Pienaar [Tue, 22 Jan 2019 23:46:14 +0000 (15:46 -0800)]
Fixing op description white space during doc emission.

Strip additional whitespacing before and only add required additional indentation back.

PiperOrigin-RevId: 230426127

5 years agoRefactor -dma-generate walker - NFC
Uday Bondhugula [Tue, 22 Jan 2019 22:42:20 +0000 (14:42 -0800)]
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

5 years agoImprove / fix documentation for affine map composition utilities - NFC
Uday Bondhugula [Tue, 22 Jan 2019 22:03:23 +0000 (14:03 -0800)]
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

5 years agoAllocate private/local buffers for slices accurately during fusion
Uday Bondhugula [Tue, 22 Jan 2019 21:58:52 +0000 (13:58 -0800)]
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

5 years agoHandle escaping memrefs in loop fusion pass:
MLIR Team [Tue, 22 Jan 2019 21:23:37 +0000 (13:23 -0800)]
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

5 years agoAdd default attr value & define tf.AvgPool op and use pattern for rewrite.
Jacques Pienaar [Tue, 22 Jan 2019 18:26:09 +0000 (10:26 -0800)]
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

5 years agoFix FlatAffineConstraints::removeIdRange
Uday Bondhugula [Tue, 22 Jan 2019 17:52:56 +0000 (09:52 -0800)]
Fix FlatAffineConstraints::removeIdRange

- the number of symbols/local ids was being incorrectly updated; the code in
  cl/230112574 exposes this.

PiperOrigin-RevId: 230358327

5 years agoStart doc generation pass.
Jacques Pienaar [Tue, 22 Jan 2019 17:31:04 +0000 (09:31 -0800)]
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

5 years agoMake MLIREmitter::bindConstant variadic
Nicolas Vasilache [Tue, 22 Jan 2019 13:00:01 +0000 (05:00 -0800)]
Make MLIREmitter::bindConstant variadic

This is needed to allow binding to more constant types.
Tests that exercise this behavior will come in a followup CL.
In the meantime this does not breaks things.

PiperOrigin-RevId: 230320621

5 years agoAdd assertions to SplatElementsAttr and ConstantOp builders and fix failures
Lei Zhang [Mon, 21 Jan 2019 19:24:16 +0000 (11:24 -0800)]
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

5 years agoAffineExpr pretty print - add missing handling to print expr * - 1 as -expr
Uday Bondhugula [Mon, 21 Jan 2019 14:59:58 +0000 (06:59 -0800)]
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

5 years agoAdd a constant folding hook to ExtractElementOp to fold extracting the element of...
River Riddle [Sun, 20 Jan 2019 04:54:09 +0000 (20:54 -0800)]
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

5 years agoCleanup spurious printing bits in EDSCs
Nicolas Vasilache [Sat, 19 Jan 2019 21:20:28 +0000 (13:20 -0800)]
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

5 years agoCleanup EDSCs
Nicolas Vasilache [Sat, 19 Jan 2019 15:26:03 +0000 (07:26 -0800)]
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

5 years agoRestructure FloatAttr::get(Type, double) to allow for loss of precision when converti...
River Riddle [Sat, 19 Jan 2019 00:31:58 +0000 (16:31 -0800)]
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

5 years agoFix test cases that were accessing out of bounds to start with (b/123072438)
Uday Bondhugula [Fri, 18 Jan 2019 20:55:46 +0000 (12:55 -0800)]
Fix test cases that were accessing out of bounds to start with (b/123072438)

- detected with memref-bound-check

- fixes b/123072438; while on this, fix another test case which was reported
  out of bounds

PiperOrigin-RevId: 229978187

5 years agoFix raw buffer size when creating a DenseElementsAttr from an array of attributes.
River Riddle [Fri, 18 Jan 2019 20:23:47 +0000 (12:23 -0800)]
Fix raw buffer size when creating a DenseElementsAttr from an array of attributes.

PiperOrigin-RevId: 229973134

5 years agoMark (void)indexRemap to please compiler for unused variable check
Lei Zhang [Fri, 18 Jan 2019 18:56:12 +0000 (10:56 -0800)]
Mark (void)indexRemap to please compiler for unused variable check

PiperOrigin-RevId: 229957023

5 years agoWhen constructing or hashing a key type in TypeUniquer first check if the derived...
River Riddle [Fri, 18 Jan 2019 17:16:09 +0000 (09:16 -0800)]
When constructing or hashing a key type in TypeUniquer first check if the derived storage type provides a 'getKey' or 'hashKey'.

PiperOrigin-RevId: 229939463

5 years agoRewrite OpStats to use llvm formatting utilities.
River Riddle [Fri, 18 Jan 2019 17:00:34 +0000 (09:00 -0800)]
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

5 years agoLoopFusion: Creates private MemRefs which are used only by operations in the fused...
MLIR Team [Fri, 18 Jan 2019 16:56:27 +0000 (08:56 -0800)]
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

5 years agoFix AffineApply corner case
Nicolas Vasilache [Thu, 17 Jan 2019 22:33:09 +0000 (14:33 -0800)]
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

5 years ago[MLIR] Add functionality for constructing a DenseElementAttr from an array of attribu...
River Riddle [Thu, 17 Jan 2019 22:11:05 +0000 (14:11 -0800)]
[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

5 years agoUpdate stale / target-specific information in comments - NFC
Uday Bondhugula [Thu, 17 Jan 2019 20:51:48 +0000 (12:51 -0800)]
Update stale / target-specific information in comments - NFC

PiperOrigin-RevId: 229800834

5 years agoAdd AttrConstraint to enable generating verification for attribute values.
Jacques Pienaar [Thu, 17 Jan 2019 18:36:51 +0000 (10:36 -0800)]
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