Commit Graph

235 Commits

Author SHA1 Message Date
Mehdi Amini c224bc71af Remove DialectHooks and introduce a Dialect Interfaces instead
These hooks were introduced before the Interfaces mechanism was available.

DialectExtractElementHook is unused and entirely removed. The
DialectConstantFoldHook is used a fallback in the
operation fold() method, and is replaced by a DialectInterface.
The DialectConstantDecodeHook is used for interpreting OpaqueAttribute
and should be revamped, but is replaced with an interface in 1:1 fashion
for now.

Differential Revision: https://reviews.llvm.org/D85595
2020-08-13 00:38:55 +00:00
Rahul Joshi e2b716105b [MLIR] Add argument related API to Region
- Arguments of the first block of a region are considered region arguments.
- Add API on Region class to deal with these arguments directly instead of
  using the front() block.
- Changed several instances of existing code that can use this API
- Fixes https://bugs.llvm.org/show_bug.cgi?id=46535

Differential Revision: https://reviews.llvm.org/D83599
2020-07-14 09:28:29 -07:00
River Riddle 9db53a1827 [mlir][NFC] Remove usernames and google bug numbers from TODO comments.
These were largely leftover from when MLIR was a google project, and don't really follow LLVM guidelines.
2020-07-07 01:40:52 -07:00
Rahul Joshi 52af9c59e3 [MLIR] Add a NoRegionArguments trait
- This trait will verify that all regions attached to an Op have no arguments
- Fixes https://bugs.llvm.org/show_bug.cgi?id=46521 : Add trait NoRegionArguments

Differential Revision: https://reviews.llvm.org/D83016
2020-07-06 09:05:38 -07:00
Lucy Fox 7b226fde67 [MLIR] Add an Op util which returns its name with the dialect stripped.
Differential Revision: https://reviews.llvm.org/D81435
2020-06-16 16:47:24 -07:00
Alex Zinenko 3ccf4a5bd1 [mlir] ensureRegionTerminator: take OpBuilder
The SingleBlockImplicitTerminator op trait provides a function
`ensureRegionTerminator` that injects an appropriate terminator into the block
if necessary, which is used during operation constructing and parsing.
Currently, this function directly modifies the IR using low-level APIs on
Operation and Block. If this function is called from a conversion pattern,
these manipulations are not reflected in the ConversionPatternRewriter and thus
cannot be undone or, worse, lead to tricky memory errors and malformed IR.
Change `ensureRegionTerminator` to take an instance of `OpBuilder` instead of
`Builder`, and use it to construct the block and the terminator when required.
Maintain overloads taking an instance of `Builder` and creating a simple
`OpBuilder` to use in parsers, which don't have an `OpBuilder` and cannot
interact with the dialect conversion mechanism. This change was one of the
reasons to make `<OpTy>::build` accept an `OpBuilder`.

Differential Revision: https://reviews.llvm.org/D80138
2020-05-20 16:14:46 +02:00
Geoffrey Martin-Noble 2280cb880d Add Operation::moveAfter
This revision introduces an Operation::moveAfter mirroring
Operation::moveBefore to move an operation after another
existing operation or an iterator in a specified block.

Resolves https://bugs.llvm.org/show_bug.cgi?id=45799

Differential Revision: https://reviews.llvm.org/D79640
2020-05-08 22:34:21 +00:00
Jacques Pienaar 5eae715a31 [mlir] Add NamedAttrList
This is a wrapper around vector of NamedAttributes that keeps track of whether sorted and does some minimal effort to remain sorted (doing more, e.g., appending attributes in sorted order, could be done in follow up). It contains whether sorted and if a DictionaryAttr is queried, it caches the returned DictionaryAttr along with whether sorted.

Change MutableDictionaryAttr to always return a non-null Attribute even when empty (reserve null cases for errors). To this end change the getter to take a context as input so that the empty DictionaryAttr could be queried. Also create one instance of the empty dictionary attribute that could be reused without needing to lock context etc.

Update infer type op interface to use DictionaryAttr and use NamedAttrList to avoid incurring multiple conversion costs.

Fix bug in sorting helper function.

Differential Revision: https://reviews.llvm.org/D79463
2020-05-07 12:33:36 -07:00
River Riddle 108abd2f2e [mlir] Add a new MutableOperandRange class for adding/remove operands
This class allows for mutating an operand range in-place, and provides vector like API for adding/erasing/setting. ODS now uses this class to generate mutable wrappers for named operands, with the name `MutableOperandRange <operand-name>Mutable()`

Differential Revision: https://reviews.llvm.org/D78892
2020-04-29 16:48:14 -07:00
Jacques Pienaar 5439582781 Rename NamedAttributeList to MutableDictionaryAttr
Makes the relationship and function clearer. Accordingly rename getAttrList to getMutableAttrDict.

Differential Revision: https://reviews.llvm.org/D79125
2020-04-29 14:58:02 -07:00
Alex Zinenko bb1d976feb [mlir][flang] use OpBuilder& instead of Builder* in <Op>::build methods
As we start defining more complex Ops, we increasingly see the need for
Ops-with-regions to be able to construct Ops within their regions in
their ::build methods. However, these methods only have access to
Builder, and not OpBuilder. Creating a local instance of OpBuilder
inside ::build and using it fails to trigger the operation creation
hooks in derived builders (e.g., ConversionPatternRewriter). In this
case, we risk breaking the logic of the derived builder. At the same
time, OpBuilder::create, which is by far the largest user of ::build
already passes "this" as the first argument, so an OpBuilder instance is
already available.

Update all ::build methods in all Ops in MLIR and Flang to take
"OpBuilder &" instead of "Builder *". Note the change from pointer and
to reference to comply with the common style in MLIR, this also ensures
all other users must change their ::build methods.

Differential Revision: https://reviews.llvm.org/D78713
2020-04-28 10:42:08 +02:00
River Riddle 1956a8a7cb [mlir] Don't allocate an operand storage if the operation is known to never have operands
Certain classes of operations, such as FuncOp, are known to never have operands. This revision adds a bit to operation to detect this case and avoid allocating the unnecessary operand storage. This saves 1 word for each instance of these operations.

Differential Revision: https://reviews.llvm.org/D78876
2020-04-26 21:34:02 -07:00
River Riddle 4dfd1b5fcb [mlir] Optimize operand storage such that all operations can have resizable operand lists
This revision refactors the structure of the operand storage such that there is no additional memory cost for resizable operand lists until it is required. This is done by using two different internal representations for the operand storage:
* One using trailing operands
* One using a dynamically allocated std::vector<OpOperand>

This allows for removing the resizable operand list bit, and will free up APIs from needing to workaround non-resizable operand lists.

Differential Revision: https://reviews.llvm.org/D78875
2020-04-26 21:34:01 -07:00
River Riddle 48e9ef4320 [mlir] Give each OpResult its own use list
This revision removes the multi use-list to ensure that each result gets its own. This decision was made by doing some extensive benchmarking of programs that actually use multiple results. This results in a size increase of 1-word per result >1, but the common case of 1-result remains unaffected. A side benefit is that 0-result operations now shrink by 1-word.

Differential Revision: https://reviews.llvm.org/D78701
2020-04-23 16:28:55 -07:00
River Riddle 0359b86d8b [mlir][ODS] Add support for variadic regions.
Summary: This revision adds support for marking the last region as variadic in the ODS region list with the VariadicRegion directive.

Differential Revision: https://reviews.llvm.org/D77455
2020-04-05 01:03:38 -07:00
Kazuaki Ishizaki 5aacce3db2 [mlir] NFC: Fix trivial typo
Differential Revision: https://reviews.llvm.org/D77473
2020-04-05 11:30:30 +09:00
River Riddle 79afdfab9a [mlir] Change the default of `mlir-print-op-on-diagnostic` to true
Summary: It is a very common user trap to think that the location printed along with the diagnostic is the same as the current operation that caused the error. This revision changes the behavior to always print the current operation, except for when diagnostics are being verified. This is achieved by moving the command line flags in IR/ to be options on the MLIRContext.

Differential Revision: https://reviews.llvm.org/D77095
2020-04-03 19:02:51 -07:00
Uday Bondhugula ad4b4acbb0 [MLIR][NFC] drop some unnecessary includes
Drop unnecessary includes

Differential Revision: https://reviews.llvm.org/D76898
2020-03-27 09:17:27 +05:30
River Riddle 153720a0a5 [mlir][NFC] Move the interfaces and traits for side effects out of IR/ to Interfaces/
Summary:
Interfaces/ is the designated directory for these types of interfaces, and also removes the need for including them directly in IR/.

Differential Revision: https://reviews.llvm.org/D75886
2020-03-10 12:45:45 -07:00
River Riddle f8923584da [mlir][SideEffects] Define a set of interfaces and traits for defining side effects
This revision introduces the infrastructure for defining side-effects and attaching them to operations. This infrastructure allows for defining different types of side effects, that don't interact with each other, but use the same internal mechanisms. At the base of this is an interface that allows operations to specify the different effect instances that are exhibited by a specific operation instance. An effect instance is comprised of the following:

* Effect: The specific effect being applied.
  For memory related effects this may be reading from memory, storing to memory, etc.

* Value: A specific value, either operand/result/region argument, the effect pertains to.

* Resource: This is a global entity that represents the domain within which the effect is being applied.

MLIR serves many different abstractions, which cover many different domains. Simple effects are may have very different context, for example writing to an in-memory buffer vs a database. This revision defines uses this infrastructure to define a set of initial MemoryEffects. The are effects that generally correspond to memory of some kind; Allocate, Free, Read, Write.

This set of memory effects will be used in follow revisions to generalize various parts of the compiler, and make others more powerful(e.g. DCE).

This infrastructure was originally proposed here:
https://groups.google.com/a/tensorflow.org/g/mlir/c/v2mNl4vFCUM

Differential Revision: https://reviews.llvm.org/D74439
2020-03-06 14:04:36 -08:00
River Riddle cb1777127c [mlir] Remove successor operands from the Operation class
Summary:
This revision removes all of the functionality related to successor operands on the core Operation class. This greatly simplifies a lot of handling of operands, as well as successors. For example, DialectConversion no longer needs a special "matchAndRewrite" for branching terminator operations.(Note, the existing method was also broken for operations with variadic successors!!)

This also enables terminator operations to define their own relationships with successor arguments, instead of the hardcoded "pass-through" behavior that exists today.

Differential Revision: https://reviews.llvm.org/D75318
2020-03-05 12:53:02 -08:00
River Riddle 621d7cca37 [mlir] Add a new BranchOpInterface to allow for opaquely interfacing with branching terminator operations.
This interface contains the necessary components to provide the same builtin behavior that terminators have. This will be used in future revisions to remove many of the hardcoded constraints placed on successors and successor operands. The interface initially contains three methods:

```c++
// Return a set of values corresponding to the operands for successor 'index', or None if the operands do not correspond to materialized values.
Optional<OperandRange> getSuccessorOperands(unsigned index);

// Return true if this terminator can have it's successor operands erased.
bool canEraseSuccessorOperand();

// Erase the operand of a successor. This is only valid to call if 'canEraseSuccessorOperand' returns true.
void eraseSuccessorOperand(unsigned succIdx, unsigned opIdx);
```

Differential Revision: https://reviews.llvm.org/D75314
2020-03-05 12:50:35 -08:00
River Riddle c0fd5e657e [mlir] Add traits for verifying the number of successors and providing relevant accessors.
This allows for simplifying OpDefGen, as well providing specializing accessors for the different successor counts. This mirrors the existing traits for operands and results.

Differential Revision: https://reviews.llvm.org/D75313
2020-03-05 12:49:59 -08:00
Lei Zhang 35b685270b [mlir] Add a signedness semantics bit to IntegerType
Thus far IntegerType has been signless: a value of IntegerType does
not have a sign intrinsically and it's up to the specific operation
to decide how to interpret those bits. For example, std.addi does
two's complement arithmetic, and std.divis/std.diviu treats the first
bit as a sign.

This design choice was made some time ago when we did't have lots
of dialects and dialects were more rigid. Today we have much more
extensible infrastructure and different dialect may want different
modelling over integer signedness. So while we can say we want
signless integers in the standard dialect, we cannot dictate for
others. Requiring each dialect to model the signedness semantics
with another set of custom types is duplicating the functionality
everywhere, considering the fundamental role integer types play.

This CL extends the IntegerType with a signedness semantics bit.
This gives each dialect an option to opt in signedness semantics
if that's what they want and helps code sharing. The parser is
modified to recognize `si[1-9][0-9]*` and `ui[1-9][0-9]*` as
signed and unsigned integer types, respectively, leaving the
original `i[1-9][0-9]*` to continue to mean no indication over
signedness semantics. All existing dialects are not affected (yet)
as this is a feature to opt in.

More discussions can be found at:

https://groups.google.com/a/tensorflow.org/d/msg/mlir/XmkV8HOPWpo/7O4X0Nb_AQAJ

Differential Revision: https://reviews.llvm.org/D72533
2020-02-21 09:16:54 -05:00
River Riddle aff4ed7326 [mlir][NFC] Update Operation::getResultTypes to use ArrayRef<Type> instead of iterator_range.
Summary: The new internal representation of operation results now allows for accessing the result types to be more efficient. Changing the API to ArrayRef is more efficient and removes the need to explicitly materialize vectors in several places.

Differential Revision: https://reviews.llvm.org/D73429
2020-01-27 19:57:48 -08:00
Mehdi Amini 308571074c Mass update the MLIR license header to mention "Part of the LLVM project"
This is an artifact from merging MLIR into LLVM, the file headers are
now aligned with the rest of the project.
2020-01-26 03:58:30 +00:00
River Riddle 2bdf33cc4c [mlir] NFC: Remove Value::operator* and Value::operator-> now that Value is properly value-typed.
Summary: These were temporary methods used to simplify the transition.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D72548
2020-01-11 08:54:39 -08:00
River Riddle fd01d8626c [mlir] Rewrite the internal representation of OpResult to be optimized for memory.
Summary:
This changes the implementation of OpResult to have some of the results be represented inline in Value, via a pointer int pair of Operation*+result number, and the rest being trailing objects on the main operation. The full details of the new representation is detailed in the proposal here:
https://groups.google.com/a/tensorflow.org/g/mlir/c/XXzzKhqqF_0/m/v6bKb08WCgAJ

The only difference between here and the above proposal is that we only steal 2-bits for the Value kind instead of 3. This means that we can only fit 2-results inline instead of 6. This allows for other users to steal the final bit for PointerUnion/etc. If necessary, we can always steal this bit back in the future to save more space if 3-6 results are common enough.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D72020
2020-01-02 14:40:09 -08:00
River Riddle 0d6ebb4f0d [mlir] Refactor operation results to use a single use list for all results of the operation.
Summary: A new class is added, IRMultiObjectWithUseList, that allows for representing an IR use list that holds multiple sub values(used in this case for OpResults). This class provides all of the same functionality as the base IRObjectWithUseList, but for specific sub-values. This saves a word per operation result and is a necessary step in optimizing the layout of operation results. For now the use list is placed on the operation itself, so zero-result operations grow by a word. When the work for optimizing layout is finished, this can be moved back to being a trailing object based on memory/runtime benchmarking.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D71955
2019-12-30 20:50:07 -08:00
River Riddle f83a8efe87 [mlir] Merge the successor operand count into BlockOperand.
Summary: The successor operand counts are directly tied to block operands anyways, and this simplifies the trailing objects of Operation(i.e. one less computation to perform).

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D71949
2019-12-27 20:35:31 -08:00
River Riddle e62a69561f NFC: Replace ValuePtr with Value and remove it now that Value is value-typed.
ValuePtr was a temporary typedef during the transition to a value-typed Value.

PiperOrigin-RevId: 286945714
2019-12-23 16:36:53 -08:00
River Riddle ab46543ceb Resubmit: ReImplement the Value classes as value-typed objects wrapping an internal pointer storage.
This will enable future commits to reimplement the internal implementation of OpResult without needing to change all of the existing users. This is part of a chain of commits optimizing the size of operation results.

PiperOrigin-RevId: 286930047
2019-12-23 16:05:05 -08:00
MLIR Team 268365ab01 Automated rollback of commit f603a50109
PiperOrigin-RevId: 286924059
2019-12-23 15:54:44 -08:00
River Riddle f603a50109 ReImplement the Value classes as value-typed objects wrapping an internal pointer storage.
This will enable future commits to reimplement the internal implementation of OpResult without needing to change all of the existing users. This is part of a chain of commits optimizing the size of operation results.

PiperOrigin-RevId: 286919966
2019-12-23 15:44:00 -08:00
Mehdi Amini 56222a0694 Adjust License.txt file to use the LLVM license
PiperOrigin-RevId: 286906740
2019-12-23 15:33:37 -08:00
River Riddle 35807bc4c5 NFC: Introduce new ValuePtr/ValueRef typedefs to simplify the transition to Value being value-typed.
This is an initial step to refactoring the representation of OpResult as proposed in: https://groups.google.com/a/tensorflow.org/g/mlir/c/XXzzKhqqF_0/m/v6bKb08WCgAJ

This change will make it much simpler to incrementally transition all of the existing code to use value-typed semantics.

PiperOrigin-RevId: 286844725
2019-12-22 22:00:23 -08:00
River Riddle 4562e389a4 NFC: Remove unnecessary 'llvm::' prefix from uses of llvm symbols declared in `mlir` namespace.
Aside from being cleaner, this also makes the codebase more consistent.

PiperOrigin-RevId: 286206974
2019-12-18 09:29:20 -08:00
River Riddle 9ed22ae5b8 Refactor the various operand/result/type iterators to use indexed_accessor_range.
This has several benefits:
* The implementation is much cleaner and more efficient.
* The ranges now have support for many useful operations: operator[], slice, drop_front, size, etc.
* Value ranges can now directly query a range for their types via 'getTypes()': e.g:
   void foo(Operation::operand_range operands) {
     auto operandTypes = operands.getTypes();
   }

PiperOrigin-RevId: 284834912
2019-12-10 13:21:22 -08:00
River Riddle 7be6a40ab9 Add new indexed_accessor_range_base and indexed_accessor_range classes that simplify defining index-able ranges.
Many ranges want similar functionality from a range type(e.g. slice/drop_front/operator[]/etc.), so these classes provide a generic implementation that may be used by many different types of ranges. This removes some code duplication, and also empowers many of the existing range types in MLIR(e.g. result type ranges, operand ranges, ElementsAttr ranges, etc.). This change only updates RegionRange and ValueRange, more ranges will be updated in followup commits.

PiperOrigin-RevId: 284615679
2019-12-09 12:55:40 -08:00
Jacques Pienaar 70aeb4566e Add RegionRange for when need to abstract over different region iteration
Follows ValueRange in representing a generic abstraction over the different
ways to represent a range of Regions. This wrapper is not as ValueRange and only
considers the current cases of interest: MutableArrayRef<Region> and
ArrayRef<std::unique_ptr<Region>> as occurs during op construction vs op region
querying.

Note: ArrayRef<std::unique_ptr<Region>> allows for unset regions, so this range
returns a pointer to a Region instead of a Region.
PiperOrigin-RevId: 284563229
2019-12-09 08:57:56 -08:00
River Riddle d6ee6a0310 Update the builder API to take ValueRange instead of ArrayRef<Value *>
This allows for users to provide operand_range and result_range in builder.create<> calls, instead of requiring an explicit copy into a separate data structure like SmallVector/std::vector.

PiperOrigin-RevId: 284360710
2019-12-07 10:35:41 -08:00
River Riddle 9d1a0c72b4 Add a new ValueRange class.
This class represents a generic abstraction over the different ways to represent a range of Values: ArrayRef<Value *>, operand_range, result_range. This class will allow for removing the many instances of explicit SmallVector<Value *, N> construction. It has the same memory cost as ArrayRef, and only suffers cost from indexing(if+elsing the different underlying representations).

This change only updates a few of the existing usages, with more to be changed in followups; e.g. 'build' API.

PiperOrigin-RevId: 284307996
2019-12-06 20:07:23 -08:00
Kazuaki Ishizaki 84a6182ddd minor spelling tweaks
Closes tensorflow/mlir#290

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/290 from kiszk:spelling_tweaks_201912 9d9afd16a723dd65754a04698b3976f150a6054a
PiperOrigin-RevId: 284169681
2019-12-06 05:59:30 -08:00
River Riddle d9da8b647a Optimize operation ordering to support non-congruent indices.
This change adds support for non-congruent indices in the operation ordering within a basic block. This effect of this is that insertions are less likely to cause an invalidation of the ordering within a block. This has a big effect on modules that have very large basic blocks.

PiperOrigin-RevId: 283858136
2019-12-04 16:10:13 -08:00
Sean Silva 67515e8d7a Verifier: Better error message in case of successor operand mismatch.
In particular, print the successor number in the diagnostic.

PiperOrigin-RevId: 283585084
2019-12-03 11:24:31 -08:00
Jacques Pienaar 52a7415178 Fix redundant convert and use NamedAttributeList as value
* Had leftover call that would result in converting to dictionary attr before
  being implicitedly converted back to NamedAttributeList;
* NamedAttributeList is value typed, so don't use const reference;

PiperOrigin-RevId: 283072576
2019-11-29 10:26:56 -08:00
Jacques Pienaar f27ceb7261 Add create method that takes equivalent of OperationState with NamedAttributeList
This method is close to creating an OperationState first and then unpacking it
but avoids creating the OperationState and takes a NamedAttributeList for
attributes rather than array of NamedAttribute (to enable reusing an already
created NamedAttributeList).

Reuse this new method via create that takes OperationState. I'll update inferReturnTypes in follow up to also take NamedAttributeList and so a build method that uses both inferReturnTypes and create can reuse the same list.

PiperOrigin-RevId: 282651642
2019-11-26 15:30:35 -08:00
Lei Zhang 13c6e419ca Add support for AttrSizedOperandSegments/AttrSizedResultSegments
Certain operations can have multiple variadic operands and their size
relationship is not always known statically. For such cases, we need
a per-op-instance specification to divide the operands into logical
groups or segments. This can be modeled by attributes.

This CL introduces C++ trait AttrSizedOperandSegments for operands and
AttrSizedResultSegments for results. The C++ trait just guarantees
such size attribute has the correct type (1D vector) and values
(non-negative), etc. It serves as the basis for ODS sugaring that
with ODS argument declarations we can further verify the number of
elements match the number of ODS-declared operands and we can generate
handy getter methods.

PiperOrigin-RevId: 282467075
2019-11-25 17:26:50 -08:00
Sean Silva e4f83c6c26 Add multi-level DCE pass.
This is a simple multi-level DCE pass that operates pretty generically on
the IR. Its key feature compared to the existing peephole dead op folding
that happens during canonicalization is being able to delete recursively
dead cycles of the use-def graph, including block arguments.

PiperOrigin-RevId: 281568202
2019-11-20 12:55:10 -08:00
River Riddle 626e1fd95e Add an option to print an operation if a diagnostic is emitted on it
It is often helpful to inspect the operation that the error/warning/remark/etc. originated from, especially in the context of debugging or in the case of a verifier failure. This change adds an option 'mlir-print-op-on-diagnostic' that attaches the operation as a note to any diagnostic that is emitted on it via Operation::emit(Error|Warning|Remark). In the case of an error, the operation is printed in the generic form.

PiperOrigin-RevId: 280021438
2019-11-12 11:59:19 -08:00
Sean Silva f6188b5b07 Replace some remnant uses of "inst" with "op".
PiperOrigin-RevId: 278961676
2019-11-06 16:09:23 -08:00
River Riddle 8fa9d82606 NFC: Rename parseOptionalAttributeDict -> parseOptionalAttrDict to match the name of the print method.
PiperOrigin-RevId: 278696668
2019-11-05 13:32:47 -08:00
Smit Hinsu 85b46314c0 Allow dynamic but ranked types in ops with SameOperandsAndResultShape and SameOperandsAndResultType traits
Currently SameOperandsAndResultShape trait allows operands to have tensor<*xf32> and tensor<2xf32> but doesn't allow tensor<?xf32> and tensor<10xf32>.

Also, use the updated shape compatibility helper function in TensorCastOp::areCastCompatible method.

PiperOrigin-RevId: 273658336
2019-10-08 19:37:11 -07:00
Geoffrey Martin-Noble 18db4ce493 Allow element type traits to operate on scalars
This allows confirming that a scalar argument has the same element type as a shaped one. It's easy to validate a type is shaped on its own if that's desirable, so this shouldn't make that use case harder. This matches the behavior of other traits that operate on element type (e.g. AllElementTypesMatch). Also this makes the code simpler because now we just use getElementTypeOrSelf.

Verified that all uses in core already check the type is shaped in another way.

PiperOrigin-RevId: 273068507
2019-10-05 10:06:06 -07:00
Christian Sigg 496f4590a1 Generalize parse/printBinaryOp to parse/printOneResultOp.
PiperOrigin-RevId: 272722539
2019-10-03 13:00:12 -07:00
Christian Sigg 8503ffbe3a Add verification error message for ops that require at least one operand or result.
PiperOrigin-RevId: 272153634
2019-10-01 00:57:18 -07:00
Jacques Pienaar c57f202c8c Switch explicit create methods to match generated build's order
The generated build methods have result type before the arguments (operands and attributes, which are also now adjacent in the explicit create method). This also results in changing the create method's ordering to match most build method's ordering.

PiperOrigin-RevId: 271755054
2019-09-28 09:35:58 -07:00
River Riddle 3a643de92b NFC: Pass OpAsmPrinter by reference instead of by pointer.
MLIR follows the LLVM style of pass-by-reference.

PiperOrigin-RevId: 270401378
2019-09-20 20:43:35 -07:00
River Riddle 729727ebc7 NFC: Pass OperationState by reference instead of by pointer.
MLIR follows the LLVM convention of passing by reference instead of by pointer.

PiperOrigin-RevId: 270396945
2019-09-20 19:47:32 -07:00
River Riddle 2797517ecf NFC: Pass OpAsmParser by reference instead of by pointer.
MLIR follows the LLVM style of pass-by-reference.

PiperOrigin-RevId: 270315612
2019-09-20 11:37:21 -07:00
River Riddle 35df51086a Fix nested dominance relationship between parent results and child operations.
This modifies DominanceInfo::properlyDominates(Value *value, Operation *op) to return false if the value is defined by a parent operation of 'op'. This prevents using values defined by the parent operation from within any child regions.

PiperOrigin-RevId: 269934920
2019-09-18 18:23:41 -07:00
Jacques Pienaar 2660623a88 Add pass generate per block in a function a GraphViz Dot graph with ops as nodes
* Add GraphTraits that treat a block as a graph, Operation* as node and use-relationship for edges;
  - Just basic graph output;
* Add use iterator to iterate over all uses of an Operation;
* Add testing pass to generate op graph;

This does not support arbitrary operations other than function nor nested regions yet.

PiperOrigin-RevId: 268121782
2019-09-09 18:12:41 -07:00
River Riddle 4bfae66d70 Refactor the 'walk' methods for operations.
This change refactors and cleans up the implementation of the operation walk methods. After this refactoring is that the explicit template parameter for the operation type is no longer needed for the explicit op walks. For example:

    op->walk<AffineForOp>([](AffineForOp op) { ... });

is now accomplished via:

    op->walk([](AffineForOp op) { ... });

PiperOrigin-RevId: 266209552
2019-08-29 13:04:50 -07:00
Stephan Herhut c60c490356 Add implementation for tensor_load and tensor_store operations.
This change adds definitions, parsing and verification for both ops.

PiperOrigin-RevId: 265954051
2019-08-28 11:25:52 -07:00
River Riddle 2f59f76876 NFC: Remove the explicit context from Operation::create and OperationState.
The context can easily be recovered from the Location in these situations.

PiperOrigin-RevId: 265578574
2019-08-26 17:34:48 -07:00
River Riddle 1e42954032 NFC: Standardize the terminology used for parent ops/regions/etc.
There are currently several different terms used to refer to a parent IR unit in 'get' methods: getParent/getEnclosing/getContaining. This cl standardizes all of these methods to use 'getParent*'.

PiperOrigin-RevId: 262680287
2019-08-09 20:07:52 -07:00
Alex Zinenko 4dfe6d457b FuncOp::eraseBody: drop all references before erasing blocks
Operations in a block can use a value defined in a dominating block.  When a
block, and therefore all its operations, is deleted, the operations are not
allowed to have any remaining uses.  Drop all uses of values in all blocks
before deleting them in FuncOp::eraseBody to avoid deleting an operation before
deleting the users of its results.

PiperOrigin-RevId: 257628002
2019-07-12 08:43:35 -07:00
River Riddle ce502af9cd NFC: Remove the various "::getFunction" methods.
These methods assume that a function is a valid builtin top-level operation, and removing these methods allows for decoupling FuncOp and IR/. Utility "getParentOfType" methods have been added to Operation/OpState to allow for querying the first parent operation of a given type.

PiperOrigin-RevId: 257018913
2019-07-08 12:40:08 -07:00
River Riddle e7d594bb1c Replace the implementation of Function and Module with FuncOp and ModuleOp.
This is an important step in allowing for the top-level of the IR to be extensible. FuncOp and ModuleOp contain all of the necessary functionality, while using the existing operation infrastructure. As an interim step, many of the usages of Function and Module, including the name, will remain the same. In the future, many of these will be relaxed to allow for many different types of top-level operations to co-exist.

PiperOrigin-RevId: 256427100
2019-07-03 14:37:18 -07:00
River Riddle 25f29e1b15 NFC: Update the Operation 'walk' methods to use llvm::function_ref instead of std::function.
PiperOrigin-RevId: 256099638
2019-07-02 10:28:12 -07:00
River Riddle 54cd6a7e97 NFC: Refactor Function to be value typed.
Move the data members out of Function and into a new impl storage class 'FunctionStorage'. This allows for Function to become value typed, which will greatly simplify the transition of Function to FuncOp(given that FuncOp is also value typed).

PiperOrigin-RevId: 255983022
2019-07-01 11:39:00 -07:00
River Riddle 929466b5c9 Cleanup the 'clone' methods and remove the need to explicitly pass in the context.
This also adds a new 'Region::cloneInto' method that accepts an insertion position.

PiperOrigin-RevId: 255504640
2019-06-27 16:43:18 -07:00
River Riddle a4c3a6455c Move the emitError/Warning/Remark utility methods out of MLIRContext and into the mlir namespace.
Now that Locations are attributes, they have direct access to the MLIR context. This allows for simplifying error emission by removing unnecessary context lookups.

PiperOrigin-RevId: 255112791
2019-06-25 21:32:23 -07:00
River Riddle 52ba785758 NFC: Simplify Operation::getContext to use the context within the location.
PiperOrigin-RevId: 254771979
2019-06-24 13:49:38 -07:00
River Riddle 25734596e4 Define a ModuleOp that represents a Module as an Operation.
The ModuleOp contains a single region that must contain a single block. This block must be terminated by a new pseudo operation 'module_terminator'. The syntax for this operations is as follows:

  `module` (`attributes` attr-dict)? region

Example:

  module {
    ...
  }

  module attributes { ... } {
    ...
  }

PiperOrigin-RevId: 254513752
2019-06-22 09:18:36 -07:00
Mehdi Amini 74df13fdda Refactor generic op printing: extract a public printFunctionalType() on OpAsmPrinter (NFC)
PiperOrigin-RevId: 253674584
2019-06-19 23:04:59 -07:00
Lei Zhang 31e2a6efe5 Also consider attributes when getting context for Operation
This CL also updates to use containing region as a fallback way to find
context since functions will eventually become ops with regions.

PiperOrigin-RevId: 253627322
2019-06-19 23:04:19 -07:00
River Riddle f1b848e470 NFC: Rename FuncBuilder to OpBuilder and refactor to take a top level region instead of a function.
PiperOrigin-RevId: 251563898
2019-06-09 16:17:59 -07:00
River Riddle 42c19e8272 Add a utility function to OperationName for extracting the dialect name.
PiperOrigin-RevId: 251333376
2019-06-03 19:27:35 -07:00
Geoffrey Martin-Noble e2032c7d4e Replace comments referring to "vector or tensor" with "shaped" where appropriate
PiperOrigin-RevId: 251306752
2019-06-03 19:27:19 -07:00
River Riddle ca885b3c81 Move the definitions of CmpIOp, CmpFOp, and SelectOp to the ODG framework.
--

PiperOrigin-RevId: 249928953
2019-06-01 20:01:42 -07:00
Geoffrey Martin-Noble 15075d5a22 Replace checks for rank -1 with direct calls to hasRank
Also removed a redundant check for rank after already checking for static shape (which implies rank)

--

PiperOrigin-RevId: 249927636
2019-06-01 20:01:33 -07:00
River Riddle 06734badbc Add operand type iterators to Operation and cleanup usages of operand->getType. This also simplifies some lingering usages of result->getType.
--

PiperOrigin-RevId: 249889174
2019-06-01 20:00:43 -07:00
Stephan Herhut b52112275d Add LLVM::IntToPtrOp and LLVM::PtrToIntOp to LLVM dialect.
--

PiperOrigin-RevId: 249604199
2019-06-01 19:57:34 -07:00
River Riddle 039800bfb6 Add support for streaming an OperationName into a Diagnostic.
--

PiperOrigin-RevId: 248987646
2019-05-20 13:48:28 -07:00
River Riddle 1e2d2f5d66 Add a utility function 'Operation::replaceUsesOfWith' to replace uses of a value within a single operation.
--

PiperOrigin-RevId: 248961779
2019-05-20 13:47:36 -07:00
Geoffrey Martin-Noble 22a8bc6ec3 Make shape matching work for any shaped type.
The current implementation makes some assumptions about what can be a shaped type, which aren't really necessary. It also has strange behavior for types that aren't in the limited set it handles (e.g. dialect-defined types)

    Updated the comment to match the implementation.

    This is partially motivated by the desire to make MemRef a subclass of ShapedType

--

PiperOrigin-RevId: 248859674
2019-05-20 13:47:09 -07:00
Jacques Pienaar e489e59246 Don't fail verifying unranked shapes as being the same as this could be valid at runtime.
tensor<*xf32> could be a tensor<1xf32> at runtime but this verifyShapeMatch would return failure and say function is invalid.

--

PiperOrigin-RevId: 248583038
2019-05-20 13:44:33 -07:00
River Riddle 1982afb145 Unify the 'constantFold' and 'fold' hooks on an operation into just 'fold'. This new unified fold hook will take constant attributes as operands, and may return an existing 'Value *' or a constant 'Attribute' when folding. This removes the awkward situation where a simple canonicalization like "sub(x,x)->0" had to be written as a canonicalization pattern as opposed to a fold.
--

PiperOrigin-RevId: 248582024
2019-05-20 13:44:24 -07:00
Geoffrey Martin-Noble 090662c5f3 Rename VectorOrTensorType to ShapedType
This is in preparation for making it also support/be a parent class of MemRefType. MemRefs have similar shape/rank/element semantics and it would be useful to be able to use these same utilities for them.

    This CL should not change any semantics and only change variables, types, string literals, and comments. In follow-up CLs I will prepare all callers to handle MemRef types or remove their dependence on ShapedType.

    Discussion/Rationale in https://groups.google.com/a/tensorflow.org/forum/#!topic/mlir/cHLoyfGu8y8

--

PiperOrigin-RevId: 248476449
2019-05-20 13:43:58 -07:00
River Riddle b7dc252683 NFC: Make ParseResult public and update the OpAsmParser(and thus all of the custom operation parsers) to use it instead of bool.
--

PiperOrigin-RevId: 246955523
2019-05-10 19:23:24 -07:00
Geoffrey Martin-Noble c34386e3e5 CmpFOp. Add float comparison op
This closely mirrors the llvm fcmp instruction, defining 16 different predicates

    Constant folding is unsupported for NaN and Inf because there's no way to represent those as constants at the moment

--

PiperOrigin-RevId: 246932358
2019-05-10 19:22:58 -07:00
River Riddle 983e0eea95 Simplify several usages of attributes now that they always have a type and, transitively, access to the context.
This also fixes a bug where FunctionAttrs were not being remapped for function and function argument attributes.

--

PiperOrigin-RevId: 246876924
2019-05-10 19:22:41 -07:00
River Riddle 4ea887be41 Namespaceify a few explicit template specializations to appease errors caused by a bug in gcc versions < 7.0.
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480)

--

PiperOrigin-RevId: 246664463
2019-05-06 08:29:09 -07:00
Jacques Pienaar dcab80115f Add SameOperandsAndResultElementType trait.
This trait only works for tensor and vector types at the moment, verifying that the element type of an op with only tensor and vector types match. Added a unit test for it as there is no op currently in core that uses this trait.

--

PiperOrigin-RevId: 246661697
2019-05-06 08:28:59 -07:00
River Riddle 777e7b4f4f Make the Twine parameter of the current diagnostic emit functions optional. This allows for the ability to exclusively use the new diagnostic interface without breaking all of the existing usages. Several diagnostics emitted in lib/IR have been updated to make use of this functionality.
--

PiperOrigin-RevId: 246546044
2019-05-06 08:27:13 -07:00
River Riddle ffa0246bc2 Add an MLIRContext::emitWarning utility method.
--

PiperOrigin-RevId: 246546015
2019-05-06 08:27:03 -07:00
River Riddle baa656352a Add the ability to attach notes to Diagnostic/InFlightDiagnostic.
Notes are a way to add additional context to a diagnostic, but don't really make sense as standalone diagnostics. Moving forward, notes will no longer be able to be constructed directly and must be attached to a parent Diagnostic.

    Notes can be attached via `attachNote`:

      auto diag = ...;
      diag.attachNote() << "This is a note";

--

PiperOrigin-RevId: 246545971
2019-05-06 08:26:54 -07:00
River Riddle ff6e7cf558 Introduce a new API for emitting diagnostics with Diagnostic and InFlightDiagnostic.
The Diagnostic class contains all of the information necessary to report a diagnostic to the DiagnosticEngine. It should generally not be constructed directly, and instead used transitively via InFlightDiagnostic. A diagnostic is currently comprised of several different elements:
    * A severity level.
    * A source Location.
    * A list of DiagnosticArguments that help compose and comprise the output message.
      * A DiagnosticArgument represents any value that may be part of the diagnostic, e.g. string, integer, Type, Attribute, etc.
      * Arguments can be added to the diagnostic via the stream(<<) operator.
    * (In a future cl) A list of attached notes.
      * These are in the form of other diagnostics that provide supplemental information to the main diagnostic, but do not have context on their own.

    The InFlightDiagnostic class represents an RAII wrapper around a Diagnostic that is set to be reported with the diagnostic engine. This allows for the user to modify a diagnostic that is inflight. The internally wrapped diagnostic can be reported directly or automatically upon destruction.

    These classes allow for more natural composition of diagnostics by removing the restriction that the message of a diagnostic is comprised of a single Twine. They should also allow for nice incremental improvements to the diagnostics experience in the future, e.g. formatv style diagnostics.

    Simple Example:

    emitError(loc, "integer bitwidth is limited to " + Twine(IntegerType::kMaxWidth) + " bits");
    emitError(loc) << "integer bitwidth is limited to " << IntegerType::kMaxWidth << " bits";

--

PiperOrigin-RevId: 246526439
2019-05-06 08:26:34 -07:00
River Riddle b14c4b4ca8 Add support for basic remark diagnostics. This is the minimal functionality needed to separate notes from remarks. It also provides a starting point to start building out better remark infrastructure.
--

PiperOrigin-RevId: 246175216
2019-05-06 08:24:02 -07:00