summaryrefslogtreecommitdiffstats
path: root/mlir/lib/IR/AffineMap.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Adjust License.txt file to use the LLVM licenseMehdi Amini2019-12-231-13/+4
| | | | PiperOrigin-RevId: 286906740
* NFC: Remove unnecessary 'llvm::' prefix from uses of llvm symbols declared ↵River Riddle2019-12-181-4/+4
| | | | | | | | in `mlir` namespace. Aside from being cleaner, this also makes the codebase more consistent. PiperOrigin-RevId: 286206974
* [Linalg] Add permutation information to tilingJose Ignacio Gomez2019-12-051-0/+14
| | | | | | | | | | | This patch closes issue tensorflow/mlir#271. It adds an optional permutation map to declarative tiling transformations. The map is expressed as a list of integers. Closes tensorflow/mlir#288 COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/288 from tetuante:issue271 2df2938d6a1f01b3bc404ded08dea2dd1e10b588 PiperOrigin-RevId: 284064151
* Fix build of affine load/store with empty mapDiego Caballero2019-08-201-1/+5
| | | | | | | | | | | | | | | tensorflow/mlir#58 fixed and exercised verification of load/store ops using empty affine maps. Unfortunately, it didn't exercise the creation of them. This PR addresses that aspect. It removes the assumption of AffineMap having at least one result and stores a pointer to MLIRContext as member of AffineMap. * Add empty map support to affine.store + test * Move MLIRContext to AffineMapStorage Closes tensorflow/mlir#74 PiperOrigin-RevId: 264416260
* Add a generic Linalg opNicolas Vasilache2019-08-021-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This CL introduces a linalg.generic op to represent generic tensor contraction operations on views. A linalg.generic operation requires a numbers of attributes that are sufficient to emit the computation in scalar form as well as compute the appropriate subviews to enable tiling and fusion. These attributes are very similar to the attributes for existing operations such as linalg.matmul etc and existing operations can be implemented with the generic form. In the future, most existing operations can be implemented using the generic form. This CL starts by splitting out most of the functionality of the linalg::NInputsAndOutputs trait into a ViewTrait that queries the per-instance properties of the op. This allows using the attribute informations. This exposes an ordering of verifiers issue where ViewTrait::verify uses attributes but the verifiers for those attributes have not been run. The desired behavior would be for the verifiers of the attributes specified in the builder to execute first but it is not the case atm. As a consequence, to emit proper error messages and avoid crashing, some of the linalg.generic methods are defensive as such: ``` unsigned getNumInputs() { // This is redundant with the `n_views` attribute verifier but ordering of verifiers // may exhibit cases where we crash instead of emitting an error message. if (!getAttr("n_views") || n_views().getValue().size() != 2) return 0; ``` In pretty-printed form, the specific attributes required for linalg.generic are factored out in an independent dictionary named "_". When parsing its content is flattened and the "_name" is dropped. This allows using aliasing for reducing boilerplate at each linalg.generic invocation while benefiting from the Tablegen'd verifier form for each named attribute in the dictionary. For instance, implementing linalg.matmul in terms of linalg.generic resembles: ``` func @mac(%a: f32, %b: f32, %c: f32) -> f32 { %d = mulf %a, %b: f32 %e = addf %c, %d: f32 return %e: f32 } #matmul_accesses = [ (m, n, k) -> (m, k), (m, n, k) -> (k, n), (m, n, k) -> (m, n) ] #matmul_trait = { doc = "C(m, n) += A(m, k) * B(k, n)", fun = @mac, indexing_maps = #matmul_accesses, library_call = "linalg_matmul", n_views = [2, 1], n_loop_types = [2, 1, 0] } ``` And can be used in multiple places as: ``` linalg.generic #matmul_trait %A, %B, %C [other-attributes] : !linalg.view<?x?xf32>, !linalg.view<?x?xf32>, !linalg.view<?x?xf32> ``` In the future it would be great to have a mechanism to alias / register a new linalg.op as a pair of linalg.generic, #trait. Also, note that with one could theoretically only specify the `doc` string and parse all the attributes from it. PiperOrigin-RevId: 261338740
* More general subview calculation in tilingNicolas Vasilache2019-07-031-0/+9
| | | | | | This CL refactors tiling to enable tiling of views that are not just specified by a simple permutation. This allows the tiling of convolutions for which a new example is added. PiperOrigin-RevId: 256346028
* Add a Linalg convolution op.Nicolas Vasilache2019-06-221-5/+9
| | | | | | | | | | | This CL adds a conv op that corresponds to the TF description along with its lowering to loops (https://www.tensorflow.org/api_docs/python/tf/nn/convolution). The dimension of the convolution is inferred from the rank of the views. The other logical dimensions correspond to the TF description. The computation of tiled views need to be updated to work for the input tensor. This is left for a future CL. PiperOrigin-RevId: 254505644
* Support for 0-D case in Linalg opsNicolas Vasilache2019-06-221-1/+3
| | | | | | | | | | | This CL adds support for O-D ops in Linalg ops by: 1. making the CopyOp maps optional instead of default valued 2. allowing certain map operations to accept and return empty maps 3. making linalg::LowerToLoops aware of these changes 4. providing a proper 0-D impl for CopyOp and FillOp 5. adding the relevant tests PiperOrigin-RevId: 254381908
* Add Linalg CopyOpNicolas Vasilache2019-06-191-0/+22
| | | | | | | | | | This CL adds a generic CopyOp to Linalg and its lowering to loops. The CopyOp supports input and output permutation maps. When combined with tiling and allocating a new local buffer, this should provide basic support for implementing simple memory transfers with coalescing. At the moment, lowering copies to a library call is not supported. PiperOrigin-RevId: 253250497
* Remove "size" property of affine maps.MLIR Team2019-06-011-36/+9
| | | | | | -- PiperOrigin-RevId: 250572818
* Add llvm_unreachable in unreachable path to silence GCC warning (NFC)Mehdi Amini2019-05-101-0/+1
| | | | | | | | | The switch is supposed to be fully covered, but GCC warns that: "control reaches end of non-void function" -- PiperOrigin-RevId: 247672430
* [Linalg] Add a primitive tiling passNicolas Vasilache2019-05-061-0/+38
| | | | | | | | | | | | | | | | | | | | | This CL adds a primitive tiling pass for Linalg. The tiling pass uses the loopToOperandRangesMaps property which should be ideally Tablegen'd and in-class. The tiling specification uses 0 as a convention to skip loops that should not be tiled. Tiling proceeds in 3 steps, for each op: 1. Pad tile sizes with 0 to match the number of loops, this simplifies the implementation and avoids affine map manipulations to align dimensions. 2. Create loop ranges that represent the min/max/step by which to iterate. This should be later complemented by a range intersection to avoid the out-of-bounds case. 3. Map the loop ranges to view ranges in order to create subviews on which the op can be called. Relevant utility and helper functions are added separately that support writing the transformation in a declarative fashion. Simplifying assumptions are made for now on the views and the ranges that are constructed in the function and are not passed as function arguments. This restriction will be lifted in the future. -- PiperOrigin-RevId: 246124419
* Optimize the implementation of AffineExprConstantFolder to avoid the ↵River Riddle2019-03-291-22/+29
| | | | | | redundant creation of IntegerAttrs and IndexType. This becomes a much bigger performance issue when MLIRContext is thread-safe; as each unnecessary call may need to lock a mutex. PiperOrigin-RevId: 238484632
* Update the constantFold/fold API to use LogicalResult instead of bool.River Riddle2019-03-291-4/+6
| | | | PiperOrigin-RevId: 237719658
* Make IndexType a standard type instead of a builtin. This also cleans up ↵River Riddle2019-03-291-2/+2
| | | | | | some unnecessary factory methods on the Type class. PiperOrigin-RevId: 233640730
* Refactor the affine analysis by moving some functionality to IR and some to ↵River Riddle2019-03-291-0/+13
| | | | | | | | | | | | | | AffineOps. This is important for allowing the affine dialect to define canonicalizations directly on the operations instead of relying on transformation passes, e.g. ComposeAffineMaps. A summary of the refactoring: * AffineStructures has moved to IR. * simplifyAffineExpr/simplifyAffineMap/getFlattenedAffineExpr have moved to IR. * makeComposedAffineApply/fullyComposeAffineMapAndOperands have moved to AffineOps. * ComposeAffineMaps is replaced by AffineApplyOp::canonicalize and deleted. PiperOrigin-RevId: 232586468
* Simplify compositions of AffineApplyNicolas Vasilache2019-03-291-5/+23
| | | | | | | | This CL is the 6th and last on the path to simplifying AffineMap composition. This removes `AffineValueMap::forwardSubstitutions` and replaces it by simple calls to `fullyComposeAffineMapAndOperands`. PiperOrigin-RevId: 228962580
* Introduce AffineMap::compose(AffineMap)Nicolas Vasilache2019-03-291-0/+27
| | | | | | | | | | | This CL is the 2nd on the path to simplifying AffineMap composition. This CL uses the now accepted `AffineExpr::compose(AffineMap)` to implement `AffineMap::compose(AffineMap)`. Implications of keeping the simplification function in Analysis are documented where relevant. PiperOrigin-RevId: 228276646
* Introduce a simple canonicalization of affine_apply that drops unused dims andChris Lattner2019-03-291-0/+35
| | | | | | | | | | | | | | | | | | | symbols. Included with this is some other infra: - Testcases for other canonicalizations that I will implement next. - Some helpers in AffineMap/Expr for doing simple walks without defining whole visitor classes. - A 'replaceDimsAndSymbols' facility that I'll be using to simplify maps and exprs, e.g. to fold one constant into a mapping and to drop/renumber unused dims. - Allow index (and everything else) to work in memref's, as we previously discussed, to make the testcase easier to write. - A "getAffineBinaryExpr" helper to produce a binop when you know the kind as an enum. This line of work will eventually subsume the ComposeAffineApply pass, but it is no where close to that yet :-) PiperOrigin-RevId: 227852951
* Add Type to int/float attributes.Jacques Pienaar2019-03-291-3/+4
| | | | | | | | | | | | * Optionally attach the type of integer and floating point attributes to the attributes, this allows restricting a int/float to specific width. - Currently this allows suffixing int/float constant with type [this might be revised in future]. - Default to i64 and f32 if not specified. * For index types the APInt width used is 64. * Change callers to request a specific attribute type. * Store iN type with APInt of width N. * This change does not handle the folding of constants of different types (e.g., doing int type promotions to support constant folding i3 and i32), and instead restricts the constant folding to only operate on the same types. PiperOrigin-RevId: 221722699
* Switch IntegerAttr to use APInt.Jacques Pienaar2019-03-291-2/+2
| | | | | | | | Change the storage type to APInt from int64_t for IntegerAttr (following the change to APFloat storage in FloatAttr). Effectively a direct change from int64_t to 64-bit APInt throughout (the bitwidth hardcoded). This change also adds a getInt convenience method to IntegerAttr and replaces previous getValue calls with getInt calls. While this changes updates the storage type, it does not update all constant folding calls. PiperOrigin-RevId: 221082788
* Adds a dependence check to test whether two accesses to the same memref ↵MLIR Team2019-03-291-0/+9
| | | | | | | | | | | | access the same element. - Builds access functions and iterations domains for each access. - Builds dependence polyhedron constraint system which has equality constraints for equated access functions and inequality constraints for iteration domain loop bounds. - Runs elimination on the dependence polyhedron to test if no dependence exists between the accesses. - Adds a trivial LoopFusion transformation pass with a simple test policy to test dependence between accesses to the same memref in adjacent loops. - The LoopFusion pass will be extended in subsequent CLs. PiperOrigin-RevId: 219630898
* Implement value type abstraction for attributes.River Riddle2019-03-291-15/+15
| | | | | | This is done by changing Attribute to be a POD interface around an underlying pointer storage and adding in-class support for isa/dyn_cast/cast. PiperOrigin-RevId: 218764173
* Introduce Fourier-Motzkin variable elimination + other cleanup/supportUday Bondhugula2019-03-291-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | - Introduce Fourier-Motzkin variable elimination to eliminate a dimension from a system of linear equalities/inequalities. Update isEmpty to use this. Since FM is only exact on rational/real spaces, an emptiness check based on this is guaranteed to be exact whenever it says the underlying set is empty; if it says, it's not empty, there may still be no integer points in it. Also, supports a version that computes "dark shadows". - Test this by checking for "always false" conditionals in if statements. - Unique IntegerSet's that are small (few constraints, few variables). This basically means the canonical empty set and other small sets that are likely commonly used get uniqued; allows checking for the canonical empty set by pointer. IntegerSet::kUniquingThreshold gives the threshold constraint size for uniqui'ing. - rename simplify-affine-expr -> simplify-affine-structures Other cleanup - IntegerSet::numConstraints, AffineMap::numResults are no longer needed; remove them. - add copy assignment operators for AffineMap, IntegerSet. - rename Invalid() -> Null() on AffineExpr, AffineMap, IntegerSet - Misc cleanup for FlatAffineConstraints API PiperOrigin-RevId: 218690456
* Random cleanups:Chris Lattner2019-03-291-0/+2
| | | | | | | | | | - Change AllocOp to have a getType() that always returns a MemRefType, since that is what it requires. - Rename StandardOps/StandardOpRegistration.cpp -> StandardOps/OpRegistration.cpp to align with other op sets. - Add AffineMap::getContext() helper and use it in the asmprinter. PiperOrigin-RevId: 218205527
* [MLIR] AffineMap value typeNicolas Vasilache2019-03-291-16/+26
| | | | | | | | This CL applies the same pattern as AffineExpr to AffineMap: a simple struct that acts as the storage is allocated in the bump pointer. The AffineMap is immutable and accessed everywhere by value. PiperOrigin-RevId: 216445930
* [MLIR] Sketch AffineExpr value typeNicolas Vasilache2019-03-291-18/+17
| | | | | | | | | | | | | | | | This CL sketches what it takes for AffineExpr to fully have by-value semantics and not be a not-so-smart pointer anymore. This essentially makes the underyling class a simple storage struct and implements the operations on the value type directly. Since there is no forwarding of operations anymore, we can full isolate the storage class and make a hard visibility barrier by moving detail::AffineExpr into AffineExprDetail.h. AffineExprDetail.h is only included where storage-related information is needed. PiperOrigin-RevId: 216385459
* [MLIR] AffineExpr final cleanupsNicolas Vasilache2019-03-291-15/+15
| | | | | | | | | | | This CL: 1. performs the global codemod AffineXExpr->AffineXExprClass and AffineXExprRef -> AffineXExpr; 2. simplifies function calls by removing the redundant MLIRContext parameter; 3. adds missing binary operator versions of scalar op AffineExpr where it makes sense. PiperOrigin-RevId: 216242674
* [MLIR] Cleanup AffineExprNicolas Vasilache2019-03-291-187/+9
| | | | | | | | | | | | | | | | | | | | | | | | This CL introduces a series of cleanups for AffineExpr value types: 1. to make it clear that the value types should be used, the pointer AffineExpr types are put in the detail namespace. Unfortunately, since the value type operator-> only forwards to the underlying pointer type, we still need to expose this in the include file for now; 2. AffineExprKind is ok to use, it thus comes out of detail and thus of AffineExpr 3. getAffineDimExpr, getAffineSymbolExpr, getAffineConstantExpr are similarly extracted as free functions and their naming is mande consistent across Builder, MLContext and AffineExpr 4. AffineBinaryOpEx::simplify functions are made into static free functions. In particular it is moved away from AffineMap.cpp where it does not belong 5. operator AffineExprType is made explicit 6. uses the binary operators everywhere possible 7. drops the pointer usage everywhere outside of AffineExpr.cpp, MLIRContext.cpp and AsmPrinter.cpp PiperOrigin-RevId: 216207212
* [MLIR] Value types for AffineXXXExprNicolas Vasilache2019-03-291-42/+30
| | | | | | | | | | | | | | | | | | | | | This CL makes AffineExprRef into a value type. Notably: 1. drops llvm isa, cast, dyn_cast on pointer type and uses member functions on the value type. It may be possible to still use classof (in a followup CL) 2. AffineBaseExprRef aggressively casts constness away: if we mean the type is immutable then let's jump in with both feet; 3. Drop implicit casts to the underlying pointer type because that always results in surprising behavior and is not needed in practice once enough cleanup has been applied. The remaining negative I see is that we still need to mix operator. and operator->. There is an ugly solution that forwards the methods but that ends up duplicating the class hierarchy which I tried to avoid as much as possible. But maybe it's not that bad anymore since AffineExpr.h would still contain a single class hierarchy (the duplication would be impl detail in.cpp) PiperOrigin-RevId: 216188003
* Constant folding for loop bounds.Uday Bondhugula2019-03-291-0/+88
| | | | | | | | | | | | | | - Fold the lower/upper bound of a loop to a constant whenever the result of the application of the bound's affine map on the operand list yields a constant. - Update/complete 'for' stmt's API to set lower/upper bounds with operands. Resolve TODOs for ForStmt::set{Lower,Upper}Bound. - Moved AffineExprConstantFolder into AffineMap.cpp and added AffineMap::constantFold to be used by both AffineApplyOp and ForStmt::constantFoldBound. PiperOrigin-RevId: 215997346
* [RFC][MLIR] Use AffineExprRef in place of AffineExpr* in IRNicolas Vasilache2019-03-291-29/+48
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This CL starts by replacing AffineExpr* with value-type AffineExprRef in a few places in the IR. By a domino effect that is pretty telling of the inconsistencies in the codebase, const is removed where it makes sense. The rationale is that the decision was concisously made that unique'd types have pointer semantics without const specifier. This is fine but we should be consistent. In the end, the only logical invariant is that there should never be such a thing as a const AffineExpr*, const AffineMap* or const IntegerSet* in our codebase. This CL takes a number of shortcuts to killing const with fire, in particular forcing const AffineExprRef to return the underlying non-const AffineExpr*. This will be removed once AffineExpr* has disappeared in containers but for now such shortcuts allow a bit of sanity in this long quest for cleanups. The **only** places where const AffineExpr*, const AffineMap* or const IntegerSet* may still appear is by transitive needs from containers, comparison operators etc. There is still one major thing remaining here: figure out why cast/dyn_cast return me a const AffineXXX*, which in turn requires a bunch of ugly const_casts. I suspect this is due to the classof taking const AffineXXXExpr*. I wonder whether this is a side effect of 1., if it is coming from llvm itself (I'd doubt it) or something else (clattner@?) In light of this, the whole discussion about const makes total sense to me now and I would systematically apply the rule that in the end, we should never have any const XXX in our codebase for unique'd types (assuming we can remove them all in containers and no additional constness constraint is added on us from the outside world). PiperOrigin-RevId: 215811554
* [MLIR] Templated AffineExprBaseRefNicolas Vasilache2019-03-291-32/+12
| | | | | | | | | | | | | | | | | | | This CL implements AffineExprBaseRef as a templated type to allow LLVM-style casts to work properly. This also allows making AffineExprBaseRef::expr private. To achieve this, it is necessary to use llvm::simplify_type and make AffineConstExpr derive from both AffineExpr and llvm::simplify<AffineExprRef>. Note that llvm::simplify_type is just an interface to enable the proper template resolution of isa/cast/dyn_cast but it otherwise holds no value. Lastly note that certain dyn_cast operations wanted the const AffineExpr* form of AffineExprBaseRef so I made the implicit constructor take that by default and documented the immutable behavior. I think this is consistent with the decision to make unique'd type immutable by convention and never use const on them. PiperOrigin-RevId: 215642247
* [MLIR] Remove uses of AffineExpr* outside of IRNicolas Vasilache2019-03-291-7/+7
| | | | | | | | | | | | | This CL uniformizes the uses of AffineExprWrap outside of IR. The public API of AffineExpr builder is modified to only use AffineExprWrap. A few places access AffineExprWrap.expr, this is only while the API is in transition to easily keep track (i.e. make expr private and let the compiler track the errors). Parser.cpp exhibits patterns that are dependent on nullptr values so converting it is left for another CL. PiperOrigin-RevId: 215642005
* Fix MLIR's floordiv, ceildiv, and mod for constant inputs (for negative lhs's)Uday Bondhugula2019-03-291-8/+6
| | | | | | | | - introduce mlir::{floorDiv, ceilDiv, mod} for constant inputs in mlir/Support/MathExtras.h - consistently use these everywhere in IR, Analysis, and Transforms. PiperOrigin-RevId: 215580677
* Add misc builder convenience methods for AffineMap's, for statement's.Uday Bondhugula2019-03-291-0/+6
| | | | | | | Use these methods to simplify existing code. Rename getConstantMap getConstantAffineMap. Move declarations to group similar ones together. PiperOrigin-RevId: 212814829
* Extend getConstantTripCount to deal with a larger subset of loop bounds; ↵Uday Bondhugula2019-03-291-19/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | make loop unroll/unroll-and-jam more powerful; add additional affine expr builder methods - use previously added analysis/simplification to infer multiple of unroll factor trip counts, making loop unroll/unroll-and-jam more general. - for loop unroll, support bounds that are single result affine map's with the same set of operands. For unknown loop bounds, loop unroll will now work as long as trip count can be determined to be a multiple of unroll factor. - extend getConstantTripCount to deal with single result affine map's with the same operands. move it to mlir/Analysis/LoopAnalysis.cpp - add additional builder utility methods for affine expr arithmetic (difference, mod/floordiv/ceildiv w.r.t postitive constant). simplify code to use the utility methods. - move affine analysis routines to AffineAnalysis.cpp/.h from AffineStructures.cpp/.h. - Rename LoopUnrollJam to LoopUnrollAndJam to match class name. - add an additional simplification for simplifyFloorDiv, simplifyCeilDiv - Rename AffineMap::getNumOperands() getNumInputs: an affine map by itself does not have operands. Operands are passed to it through affine_apply, from loop bounds/if condition's, etc., operands are stored in the latter. This should be sufficiently powerful for now as far as unroll/unroll-and-jam go for TPU code generation, and can move to other analyses/transformations. Loop nests like these are now unrolled without any cleanup loop being generated. for %i = 1 to 100 { // unroll factor 4: no cleanup loop will be generated. for %j = (d0) -> (d0) (%i) to (d0) -> (5*d0 + 3) (%i) { %x = "foo"(%j) : (affineint) -> i32 } } for %i = 1 to 100 { // unroll factor 4: no cleanup loop will be generated. for %j = (d0) -> (d0) (%i) to (d0) -> (d0 - d mod 4 - 1) (%i) { %y = "foo"(%j) : (affineint) -> i32 } } for %i = 1 to 100 { for %j = (d0) -> (d0) (%i) to (d0) -> (d0 + 128) (%i) { %x = "foo"() : () -> i32 } } TODO(bondhugula): extend this to LoopUnrollAndJam as well in the next CL (with minor changes). PiperOrigin-RevId: 212661212
* Fix cast in AffineMap::getSingleConstantValue and rename toUday Bondhugula2019-03-291-2/+2
| | | | | | getSingleConstantResult. PiperOrigin-RevId: 212544394
* Affine expression analysis and simplification.Uday Bondhugula2019-03-291-10/+6
| | | | | | | | | | | | | | | | | | | | | | | Outside of IR/ - simplify a MutableAffineMap by flattening the affine expressions - add a simplify affine expression pass that uses this analysis - update the FlatAffineConstraints API (to be used in the next CL) In IR: - add isMultipleOf and getKnownGCD for AffineExpr, and make the in-IR simplication of simplifyMod simpler and more powerful. - rename the AffineExpr visitor methods to distinguish b/w visiting and walking, and to simplify API names based on context. The next CL will use some of these for the loop unrolling/unroll-jam to make the detection for the need of cleanup loop powerful/non-trivial. A future CL will finally move this simplification to FlatAffineConstraints to make it more powerful. For eg., currently, even if a mod expr appearing in a part of the expression tree can't be simplified, the whole thing won't be simplified. PiperOrigin-RevId: 211012256
* Implement operands for the lower and upper bounds of the for statement.Tatiana Shpeisman2019-03-291-0/+9
| | | | | | | | | | | | | | | This revamps implementation of the loop bounds in the ForStmt, using general representation that supports operands. The frequent case of constant bounds is supported via special access methods. This also includes: - Operand iterators for the Statement class. - OpPointer::is() method to query the class of the Operation. - Support for the bound shorthand notation parsing and printing. - Validity checks for the bound operands used as dim ids and symbols I didn't mean this CL to be so large. It just happened this way, as one thing led to another. PiperOrigin-RevId: 210204858
* Sketch out affine analysis structures: AffineValueMap, IntegerValueSet,Uday Bondhugula2019-03-291-10/+23
| | | | | | | | | | | | | FlatAffineConstraints, and MutableAffineMap. All four classes introduced reside in lib/Analysis and are not meant to be used in the IR (from lib/IR or lib/Parser/). They are all mutable, alloc'ed, dealloc'ed - although with their fields pointing to immutable affine expressions (AffineExpr *). While on this, update simplifyMod to fold mod to a zero when possible. PiperOrigin-RevId: 209618437
* AffineMap::isIdentity clean up from previous CL review.MLIR Team2019-03-291-4/+3
| | | | PiperOrigin-RevId: 208891864
* Add AffineMap::isIdentity helper function.MLIR Team2019-03-291-0/+13
| | | | PiperOrigin-RevId: 208694482
* More simplification for affine binary op expr's.Uday Bondhugula2019-03-291-29/+129
| | | | | | | | | | | | | | | - simplify operations with identity elements (multiply by 1, add with 0). - simplify successive add/mul: fold constants, propagate constants to the right. - simplify floordiv and ceildiv when divisors are constants, and the LHS is a multiply expression with RHS constant. - fix an affine expression printing bug on paren emission. - while on this, fix affine-map test cases file (memref's using layout maps that were duplicates of existing ones should be emitted pointing to the unique'd one). PiperOrigin-RevId: 207046738
* Simplify affine binary op expression class hierarchyUday Bondhugula2019-03-291-12/+2
| | | | | | | | | | | | | | | - Drop sub-classing of affine binary op expressions. - Drop affine expr op kind sub. Represent it as multiply by -1 and add. This will also be in line with the math form when we'll need to represent a system of linear equalities/inequalities: the negative number goes into the coefficient of an affine form. (For eg. x_1 + (-1)*x_2 + 3*x_3 + (-2) >= 0). The folding simplification will transparently deal with multiplying the -1 with any other constants. This also means we won't need to simplify a multiply expression like in x_1 + (-2)*x_2 to a subtract expression (x_1 - 2*x_2) for canonicalization/uniquing. - When we print the IR, we will still pretty print to a subtract when possible. PiperOrigin-RevId: 205298958
* Rename isSymbolic to isSymbolicOrConstant to avoid confusion.Uday Bondhugula2019-03-291-3/+4
| | | | PiperOrigin-RevId: 205288794
* Parse affine map range sizes.Uday Bondhugula2019-03-291-2/+2
| | | | PiperOrigin-RevId: 204240947
* Implement some simple affine expr canonicalization/simplification.Uday Bondhugula2019-03-291-8/+90
| | | | | | | | | | | | | | | - fold constants when possible. - for a mul expression, canonicalize to always keep the LHS as the constant/symbolic term, and similarly, the RHS for an add expression to keep it closer to the mathematical form. (Eg: f(x) = 3*x + 5)); other similar simplifications; - verify binary op expressions at creation time. TODO: we can completely drop AffineSubExpr, and instead use add and mul by -1. This way something like x - 4 and -4 + x get canonicalized to x + -1 * 4 instead of being x - 4 and x + -4. (The other alternative if wanted to retain AffineSubExpr would be to simplify x + -1*y to x - y and x + <neg number> to x - <pos number>). PiperOrigin-RevId: 204240258
* Complete affine expr parsing supportUday Bondhugula2019-03-291-0/+13
| | | | | | | | | | - check for non-affine expressions - handle negative numbers and negation of id's, expressions - functions to check if a map is pure affine or semi-affine - simplify/clean up affine map parsing code - report more errors messages, more accurate error messages PiperOrigin-RevId: 203773633
* Parsing support for affine maps and affine expressionsUday Bondhugula2019-03-291-7/+4
| | | | | | | | A recursive descent parser for affine maps/expressions with operator precedence and associativity. (While on this, sketch out uniqui'ing functionality for affine maps and affine binary op expressions (partly).) PiperOrigin-RevId: 203222063
OpenPOWER on IntegriCloud