Avoids including function in C++ side that resulted in OSS C++ errors:
include/mlir-c/Core.h:228:16: error: functions that differ only in their
return type cannot be overloaded
edsc_indexed_t index(edsc_indexed_t indexed, edsc_expr_list_t indices);
~~~~~~~~~~~~~~ ^
/usr/include/string.h:484:14: note: previous declaration is here
extern char *index (const char *__s, int __c)
And as these are going away soon, just removing the function requires the least changes.
PiperOrigin-RevId: 239110470
Previously Value was a pair of name & Type, but for operands/result a TypeConstraint rather then a Type is specified. Update C++ side to match declarative side.
PiperOrigin-RevId: 238984799
This CL introduces a ValueArrayHandle helper to manage the implicit conversion
of ArrayRef<ValueHandle> -> ArrayRef<Value*> by converting first to ValueArrayHandle.
Without this, boilerplate operations that take ArrayRef<Value*> cannot be removed easily.
This all seems to boil down to decoupling Value from Type.
Alternative solutions exist (e.g. MLIR using Value by value everywhere) but they would be very intrusive. This seems to be the lowest impedance change.
Intrinsics are also lowercased by popular demand.
PiperOrigin-RevId: 238974125
This CL removes the dependency of LowerVectorTransfers on the AST version of EDSCs which will be retired.
This exhibited a pretty fundamental staging difference in AST-based vs declarative based emission.
Since the delayed creation with an AST was staged, the loop order came into existence after the clipping expressions were computed.
This now changes as the loops first need to be created declaratively in fixed order and then the clipping expressions are created.
Also, due to lack of staging, coalescing cannot be done on the fly anymore and
needs to be done either as a pre-pass (current implementation) or as a local transformation on the generated IR (future work).
Tests are updated accordingly.
PiperOrigin-RevId: 238971631
* print-ir-before=(comma-separated-pass-list)
- Print the IR before each of the passes provided within the pass list.
* print-ir-before-all
- Print the IR before every pass in the pipeline.
* print-ir-after=(comma-separated-pass-list)
- Print the IR after each of the passes provided within the pass list.
* print-ir-after-all
- Print the IR after every pass in the pipeline.
* print-ir-module-scope
- Always print the Module IR, even for non module passes.
PiperOrigin-RevId: 238523649
In particular, expose comparison operators as Python operator overloads on
ValueHandles. The comparison currently emits signed integer comparisons only,
which is compatible with the behavior of emitter-based EDSC interface. This is
sub-optimal and must be reconsidered in the future. Note that comparison
operators are not overloaded in the C++ declarative builder API precisely
because this avoids the premature decision on the signedness of comparisons.
Implement the declarative construction of boolean expressions using
ValueHandles by overloading the boolean operators in the `op` namespace to
differentiate between `operator!` for nullity check and for boolean negation.
The operands must be of i1 type. Also expose boolean operations as Python
operator overloads on ValueHandles.
PiperOrigin-RevId: 238421615
In particular, expose `cond_br`, `select` and `call` operations with syntax
similar to that of the previous emitter-based EDSC interface. These are
provided for backwards-compatibility. Ideally, we want them to be
Table-generated from the Op definitions when those definitions are declarative.
Additionally, expose the ability to construct any op given its canonical name,
which also exercises the construction of unregistered ops.
PiperOrigin-RevId: 238421583
Expose edsc::IndexedValue using a syntax smilar to that of edsc::Indexed to
ensure backwards-compatibility. It remains possible to write array-indexed
loads and stores as
C.store([i, j], A.load([i, k]) * B.load([k, j]))
after taking a "view" of some value handle using IndexedValue as
A = IndexedValue(originalValueHandle)
provided that all indices are also value handles.
PiperOrigin-RevId: 238421544
In the original implementation, constants could be bound to EDSC expressions in
the binder, independently from other MLIR Values. A rework of EDSC including
early typing provided the functionality to use MLIR's `constant` operation to
define typed constants instead of binding them separately, but only used it for
index types. The new declarative builder implementation followed by providing
a call for building `constant` operations of index types but nothing more.
Expose similar builders for integers, floats and functions to match the what
binders allow one to use.
PiperOrigin-RevId: 238421508
Provide a function `arg` that returns the function argument as a value handle,
similar to block arguments. This makes function context managers in Python
similar to block context managers, which is more consistent given that the
function context manager sets the insertion point to the first block of the
function and that arguments of that block are those of the function. This
prepares the removal of PythonMLIREmitter class and its bind_function_arguments
helper.
Additionally, provide a helper method in PythonMLIRModule to define a function
and immediately create a context for it. Update the tests that are already
using context managers to use the function context manager instead of creating
the function manually.
PiperOrigin-RevId: 238421087
- emit a note on the loop being parallel instead of setting a loop attribute
- rename the pass -test-detect-parallel (from -detect-parallel)
PiperOrigin-RevId: 238122847
- this is really not a hard error; emit a warning instead (for inability to compute
footprint due to the union failing due to unimplemented cases)
- remove a misleading warning from LoopFusion.cpp
PiperOrigin-RevId: 238118711
Add support to create a new attribute from multiple attributes. It extended the
DagNode class to represent attribute creation dag. It also changed the
RewriterGen::emitOpCreate method to support this nested dag emit.
An unit test is added.
PiperOrigin-RevId: 238090229
- fix for getConstantBoundOnDimSize: floordiv -> ceildiv for extent
- make getConstantBoundOnDimSize also return the identifier upper bound
- fix unionBoundingBox to correctly use the divisor and upper bound identified by
getConstantBoundOnDimSize
- deal with loop step correctly in addAffineForOpDomain (covers most cases now)
- fully compose bound map / operands and simplify/canonicalize before adding
dim/symbol to FlatAffineConstraints; fixes false positives in -memref-bound-check; add
test case there
- expose mlir::isTopLevelSymbol from AffineOps
PiperOrigin-RevId: 238050395
This CL sorts attribute kinds in OpBase.td according to a logical order: simple
cases ahead of complicated ones. The logic of attribute kinds involved are
completely untouched.
Comments on AttrConstraint and Attr are revised slightly.
PiperOrigin-RevId: 238031275
This CL also changes IntegerAttrBase to use APInt as return value to defer bitwidth
handling to API call sites and be consistent with FloatAttrBase. Call sites are
adjusted accordingly.
PiperOrigin-RevId: 238030614
multi-result upper bounds, complete TODOs, fix/improve test cases.
- complete TODOs for loop unroll/unroll-and-jam. Something as simple as
"for %i = 0 to %N" wasn't being unrolled earlier (unless it had been written
as "for %i = ()[s0] -> (0)()[%N] to %N"; addressed now.
- update/replace getTripCountExpr with buildTripCountMapAndOperands; makes it
more powerful as it composes inputs into it
- getCleanupLowerBound and getUnrolledLoopUpperBound actually needed the same
code; refactor and remove one.
- reorganize test cases, write previous ones better; most of these changes are
"label replacements".
- fix wrongly labeled test cases in unroll-jam.mlir
PiperOrigin-RevId: 238014653
Expose EDSC block builders as Python context managers, similarly to loop
builders. Note that blocks, unlike loops, are addressable and may need to be
"declared" without necessarily filling their bodies with instructions. This is
the case, for example, when branching to a new block from the existing block.
Therefore, creating the block context manager immediately creates the block
(unless the manager captures an existing block) by creating and destroying the
block builder. With this approach, one can either fill in the block and refer
to it later leveraging Python's dynamic variable lookup
with BlockContext([indexType]) as b:
op(...) # operation inside the block
ret()
op(...) # operation outside the block (in the function entry block)
br(b, [...]) # branching to the block created above
or declare the block contexts upfront and enter them on demand
bb1 = BlockContext() # empty block created in the surrounding function
bb2 = BlockContext() # context
cond_br(bb1.handle, [], bb2.handle, []) # branch to blocks from here
with bb1:
op(...) # operation inside the first block
with bb2:
op(...) # operation inside the second block
with bb1:
op(...) # append operation to the first block
Additionally, one can create multiple throw-away contexts that append to the
same block
with BlockContext() as b:
op(...) # operation inside the block
with BlockContext(appendTo(b)):
op(...) # new context appends to the block
which has a potential of being extended to control the insertion point of the
block at a finer level of granularity.
PiperOrigin-RevId: 238005298
Historically, Python bindings were using full path including third_party for
most headers but not all of them. This is inconsistent with the rest of MLIR.
Drop the prefix path in #include directives.
PiperOrigin-RevId: 237999346
This CL makes some minor changes to the declarative builder Helpers:
1. adds lb, ub, step methods to MemRefView to avoid always having to go through std::get + range;
2. drops MemRefView& from IndexedValue which was just creating ownership concerns. Instead, an IndexedValue only needs to keep track of the ValueHandle from which a MemRefView can be constructed on-demand if necessary.
PiperOrigin-RevId: 237861493