summaryrefslogtreecommitdiffstats
path: root/mlir/lib/Conversion/StandardToLLVM/ConvertStandardToLLVM.cpp
Commit message (Collapse)AuthorAgeFilesLines
...
* Add parentheses around boolean operators in assertAlex Zinenko2019-10-031-2/+3
| | | | | | This removes a warning and is generally a good practice. PiperOrigin-RevId: 272613597
* NFC: rename Conversion/ControlFlowToCFG to Conversion/LoopToStandardAlex Zinenko2019-10-031-1/+1
| | | | | | | | This makes the name of the conversion pass more consistent with the naming scheme, since it actually converts from the Loop dialect to the Standard dialect rather than working with arbitrary control flow operations. PiperOrigin-RevId: 272612112
* Extract MemRefType::getStridesAndOffset as a free function and fix dynamic ↵Nicolas Vasilache2019-10-021-7/+7
| | | | | | | | offset determination. This also adds coverage with a missing test, which uncovered a bug in the conditional for testing whether an offset is dynamic or not. PiperOrigin-RevId: 272505798
* Fix and simplify CallOp/CallIndirectOp to LLVM::CallOp conversionAlex Zinenko2019-10-011-38/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | A recent ABI compatibility change affected the conversion from standard CallOp/CallIndirectOp to LLVM::CallOp by changing its signature. In order to analyze the signature, the code was looking up the callee symbol in the module. This is incorrect since, during the conversion, the module may contain both the original and the converted function op that have the same symbol name. There is no strict guarantee on which of the two symbols will be found by the lookup. The conversion was not failing because the type legalizer converts the LLVM types to themselves making the original and the converted function signatures ultimately produce the same type. Instead of looking up the function signature to get the list of result types, use the types of the CallOp/CallIndirectOp results which must match those of the function in valid IR. These types are guaranteed to be the original, unconverted types when converting the operation. Furthermore, this avoids the need to perform a lookup of a symbol name in the module which may be expensive. Finally, propagate attributes as-is from the original op to the converted op since they share the attribute name for the callee of direct calls and the rest of attributes are not affected by the conversion. This removes the need for additional contorsions between direct and indirect calls to extract the name of the optional callee attribute only to insert it back. This also prevents the conversion from unintentionally dropping the other attributes of the op. PiperOrigin-RevId: 272218871
* Unify Linalg types by using strided memrefsNicolas Vasilache2019-10-011-34/+36
| | | | | | | This CL finishes the implementation of the Linalg + Affine type unification of the [strided memref RFC](https://groups.google.com/a/tensorflow.org/forum/#!topic/mlir/MaL8m2nXuio). As a consequence, the !linalg.view type, linalg::DimOp, linalg::LoadOp and linalg::StoreOp can now disappear and Linalg can use standard types everywhere. PiperOrigin-RevId: 272187165
* Normalize MemRefType lowering to LLVM as strided MemRef descriptorNicolas Vasilache2019-09-301-57/+123
| | | | | | | | | | | | | | | | | | | | | This CL finishes the implementation of the lowering part of the [strided memref RFC](https://groups.google.com/a/tensorflow.org/forum/#!topic/mlir/MaL8m2nXuio). Strided memrefs correspond conceptually to the following templated C++ struct: ``` template <typename Elem, size_t Rank> struct { Elem *ptr; int64_t offset; int64_t sizes[Rank]; int64_t strides[Rank]; }; ``` The linearization procedure for address calculation for strided memrefs is the same as for linalg views: `base_offset + SUM_i index_i * stride_i`. The following CL will unify Linalg and Standard by removing !linalg.view in favor of strided memrefs. PiperOrigin-RevId: 272033399
* Add TODO to revisit coupling of CallOp to MemRefType loweringNicolas Vasilache2019-09-271-0/+3
| | | | PiperOrigin-RevId: 271619132
* Promote MemRefDescriptor to a pointer to struct when passing function ↵Nicolas Vasilache2019-09-271-11/+162
| | | | | | | | | | | | | boundaries in LLVMLowering. The strided MemRef RFC discusses a normalized descriptor and interaction with library calls (https://groups.google.com/a/tensorflow.org/forum/#!topic/mlir/MaL8m2nXuio). Lowering of nested LLVM structs as value types does not play nicely with externally compiled C/C++ functions due to ABI issues. Solving the ABI problem generally is a very complex problem and most likely involves taking a dependence on clang that we do not want atm. A simple workaround is to pass pointers to memref descriptors at function boundaries, which this CL implement. PiperOrigin-RevId: 271591708
* Introduce splat op + provide its LLVM loweringUday Bondhugula2019-09-241-17/+39
| | | | | | | | | | | | | | | - introduce splat op in standard dialect (currently for int/float/index input type, output type can be vector or statically shaped tensor) - implement LLVM lowering (when result type is 1-d vector) - add constant folding hook for it - while on Ops.cpp, fix some stale names Signed-off-by: Uday Bondhugula <uday@polymagelabs.com> Closes tensorflow/mlir#141 COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/141 from bondhugula:splat 48976a6aa0a75be6d91187db6418de989e03eb51 PiperOrigin-RevId: 270965304
* Normalize lowering of MemRef typesNicolas Vasilache2019-09-241-127/+58
| | | | | | | | | | | | | | | | The RFC for unifying Linalg and Affine compilation passes into an end-to-end flow with a predictable ABI and linkage to external function calls raised the question of why we have variable sized descriptors for memrefs depending on whether they have static or dynamic dimensions (https://groups.google.com/a/tensorflow.org/forum/#!topic/mlir/MaL8m2nXuio). This CL standardizes the ABI on the rank of the memrefs. The LLVM struct for a memref becomes equivalent to: ``` template <typename Elem, size_t Rank> struct { Elem *ptr; int64_t sizes[Rank]; }; ``` PiperOrigin-RevId: 270947276
* Add integer sign- and zero-extension and truncation to standard.Manuel Freiberger2019-09-211-2/+18
| | | | | | | | | | | | This adds sign- and zero-extension and truncation of integer types to the standard dialects. This allows to perform integer type conversions without having to go to the LLVM dialect and introduce custom type casts (between standard and LLVM integer types). Closes tensorflow/mlir#134 COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/134 from ombre5733:sext-zext-trunc-in-std c7657bc84c0ca66b304e53ec03797e09152e4d31 PiperOrigin-RevId: 270479722
* NFC: Finish replacing FunctionPassBase/ModulePassBase with OpPassBase.River Riddle2019-09-131-2/+2
| | | | | | These directives were temporary during the generalization of FunctionPass/ModulePass to OpPass. PiperOrigin-RevId: 268970259
* Overload LLVM::TerminatorOp::build() for empty operands list.MLIR Team2019-09-091-8/+7
| | | | PiperOrigin-RevId: 268041584
* Retain address space during MLIR > LLVM conversion.MLIR Team2019-09-041-12/+9
| | | | PiperOrigin-RevId: 267206460
* Add missing lowering to CFG in mlir-cpu-runner + related cleanupMehdi Amini2019-09-011-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - the list of passes run by mlir-cpu-runner included -lower-affine and -lower-to-llvm but was missing -lower-to-cfg (because -lower-affine at some point used to lower straight to CFG); add -lower-to-cfg in between. IR with affine ops can now be run by mlir-cpu-runner. - update -lower-to-cfg to be consistent with other passes (create*Pass methods were changed to return unique ptrs, but -lower-to-cfg appears to have been missed). - mlir-cpu-runner was unable to parse custom form of affine op's - fix link options - drop unnecessary run options from test/mlir-cpu-runner/simple.mlir (none of the test cases had loops) - -convert-to-llvmir was changed to -lower-to-llvm at some point, but the create pass method name wasn't updated (this pass converts/lowers to LLVM dialect as opposed to LLVM IR). Fix this. (If we prefer "convert", the cmd-line options could be changed to "-convert-to-llvm/cfg" then.) Signed-off-by: Uday Bondhugula <uday@polymagelabs.com> Closes tensorflow/mlir#115 PiperOrigin-RevId: 266666909
* Let LLVMOpLowering specify a PatternBenefit - NFCNicolas Vasilache2019-08-221-3/+3
| | | | | | Currently the benefit is always set to 1 which limits the ability to do A->B->C lowering PiperOrigin-RevId: 264854146
* Add support for LLVM lowering of binary ops on n-D vector typesNicolas Vasilache2019-08-201-27/+124
| | | | | | This CL allows binary operations on n-D vector types to be lowered to LLVMIR by performing an (n-1)-D extractvalue, 1-D vector operation and an (n-1)-D insertvalue. PiperOrigin-RevId: 264339118
* NFC: Move LLVMIR, SDBM, and StandardOps to the Dialect/ directory.River Riddle2019-08-191-2/+2
| | | | PiperOrigin-RevId: 264193915
* Refactor linalg lowering to LLVMNicolas Vasilache2019-08-191-4/+1
| | | | | | | | | | | | | The linalg.view type used to be lowered to a struct containing a data pointer, offset, sizes/strides information. This was problematic when passing to external functions due to ABI, struct padding and alignment issues. The linalg.view type is now lowered to LLVMIR as a *pointer* to a struct containing the data pointer, offset and sizes/strides. This simplifies the interfacing with external library functions and makes it trivial to add new functions without creating a shim that would go from a value type struct to a pointer type. The consequences are that: 1. lowering explicitly uses llvm.alloca in lieu of llvm.undef and performs the proper llvm.load/llvm.store where relevant. 2. the shim creation function `getLLVMLibraryCallDefinition` disappears. 3. views are passed by pointer, scalars are passed by value. In the future, other structs will be passed by pointer (on a per-need basis). PiperOrigin-RevId: 264183671
* Change from llvm::make_unique to std::make_uniqueJacques Pienaar2019-08-171-4/+4
| | | | | | | | Switch to C++14 standard method as llvm::make_unique has been removed ( https://reviews.llvm.org/D66259). Also mark some targets as c++14 to ease next integrates. PiperOrigin-RevId: 263953918
* Express ownership transfer in PassManager API through std::unique_ptr (NFC)Mehdi Amini2019-08-121-4/+5
| | | | | | | | | | | | | | Since raw pointers are always passed around for IR construct without implying any ownership transfer, it can be error prone to have implicit ownership transferred the same way. For example this code can seem harmless: Pass *pass = .... pm.addPass(pass); pm.addPass(pass); pm.run(module); PiperOrigin-RevId: 263053082
* Add lowering of vector dialect to LLVM dialect.Nicolas Vasilache2019-08-121-10/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This CL is step 3/n towards building a simple, programmable and portable vector abstraction in MLIR that can go all the way down to generating assembly vector code via LLVM's opt and llc tools. This CL adds support for converting MLIR n-D vector types to (n-1)-D arrays of 1-D LLVM vectors and a conversion VectorToLLVM that lowers the `vector.extractelement` and `vector.outerproduct` instructions to the proper mix of `llvm.vectorshuffle`, `llvm.extractelement` and `llvm.mulf`. This has been independently verified to produce proper avx2 code. Input: ``` func @vec_1d(%arg0: vector<4xf32>, %arg1: vector<8xf32>) -> vector<8xf32> { %2 = vector.outerproduct %arg0, %arg1 : vector<4xf32>, vector<8xf32> %3 = vector.extractelement %2[0 : i32]: vector<4x8xf32> return %3 : vector<8xf32> } ``` Command: ``` mlir-opt vector-to-llvm.mlir -vector-lower-to-llvm-dialect --disable-pass-threading | mlir-opt -lower-to-cfg -lower-to-llvm | mlir-translate --mlir-to-llvmir | opt -O3 | llc -O3 -march=x86-64 -mcpu=haswell -mattr=fma,avx2 ``` Output: ``` vec_1d: # @vec_1d # %bb.0: vbroadcastss %xmm0, %ymm0 vmulps %ymm1, %ymm0, %ymm0 retq ``` PiperOrigin-RevId: 262895929
* NFC: Update usages of OwningRewritePatternList to pass by & instead of &&.River Riddle2019-08-091-2/+1
| | | | | | This will allow for reusing the same pattern list, which may be costly to continually reconstruct, on multiple invocations. PiperOrigin-RevId: 262664599
* Add support for floating-point comparison 'fcmp' to the LLVM dialect.Nagy Mostafa2019-08-081-8/+28
| | | | | | | | This adds support for fcmp to the LLVM dialect and adds any necessary lowerings, as well as support for EDSCs. Closes tensorflow/mlir#69 PiperOrigin-RevId: 262475255
* NFC: Implement OwningRewritePatternList as a class instead of a using directive.River Riddle2019-08-051-3/+2
| | | | | | This allows for proper forward declaration, as opposed to leaking the internal implementation via a using directive. This also allows for all pattern building to go through 'insert' methods on the OwningRewritePatternList, replacing uses of 'push_back' and 'RewriteListBuilder'. PiperOrigin-RevId: 261816316
* Add sitofp to the standard dialectMLIR Team2019-07-231-2/+8
| | | | | | Conversion from integers (window or input size, padding etc) to floating point is required to express many ML kernels, for example average pooling. PiperOrigin-RevId: 259575284
* Refactor region type signature conversion to be explicit via patterns.River Riddle2019-07-201-25/+45
| | | | | | This cl enforces that the conversion of the type signatures for regions, and thus their entry blocks, is handled via ConversionPatterns. A new hook 'applySignatureConversion' is added to the ConversionPatternRewriter to perform the desired conversion on a region. This also means that the handling of rewriting the signature of a FuncOp is moved to a pattern. A default implementation is provided via 'mlir::populateFuncOpTypeConversionPattern'. This removes the hacky implicit 'dynamically legal' status of FuncOp that was present previously, and leaves it up to the user to decide when/how to convert the signature of a function. PiperOrigin-RevId: 259161999
* NFC: Expose a ConversionPatternRewriter for use with ConversionPatterns.River Riddle2019-07-191-29/+38
| | | | | | This specific PatternRewriter will allow for exposing hooks in the future that are only useful for the conversion framework, e.g. type conversions. PiperOrigin-RevId: 258818122
* Refactor the conversion of block argument types in DialectConversion.River Riddle2019-07-191-7/+5
| | | | | | | | This cl begins a large refactoring over how signature types are converted in the DialectConversion infrastructure. The signatures of blocks are now converted on-demand when an operation held by that block is being converted. This allows for handling the case where a region is created as part of a pattern, something that wasn't possible previously. This cl also generalizes the region signature conversion used by FuncOp to work on any region of any operation. This generalization allows for removing the 'apply*Conversion' functions that were specific to FuncOp/ModuleOp. The implementation currently uses a new hook on TypeConverter, 'convertRegionSignature', but this should ideally be removed in favor of using Patterns. That depends on adding support to the PatternRewriter used by ConversionPattern to allow applying signature conversions to regions, which should be coming in a followup. PiperOrigin-RevId: 258645733
* Refactor DialectConversion to support different conversion modes.River Riddle2019-07-161-3/+3
| | | | | | | | | | | Users generally want several different modes of conversion. This cl refactors DialectConversion to provide two: * Partial (applyPartialConversion) - This mode allows for illegal operations to exist in the IR, and does not fail if an operation fails to be legalized. * Full (applyFullConversion) - This mode fails if any operation is not properly legalized to the conversion target. This allows for ensuring that the IR after a conversion only contains operations legal for the target. PiperOrigin-RevId: 258412243
* Remove lowerAffineConstructs and lowerControlFlow in favor of providing ↵River Riddle2019-07-161-4/+1
| | | | | | | | patterns. These methods don't compose well with the rest of conversion framework, and create artificial breaks in conversion. Replace these methods with two(populateAffineToStdConversionPatterns and populateLoopToStdConversionPatterns respectively) that populate a list of patterns to perform the same behavior. PiperOrigin-RevId: 258219277
* Decouple LLVM dialect from Standard dialectAlex Zinenko2019-07-161-3/+24
| | | | | | | | | | | | | | | Due to the absence of ODS support for enum attributes, the implementation of the LLVM dialect `icmp` operation was reusing the comparison predicate from the Standard dialect, creating an avoidable library dependency. With ODS support and ICmpPredicate attribute recently introduced, the dependency is no longer justified. Update the Standard to LLVM convresion to also convert the CmpIPredicate into LLVM::ICmpPredicate and remove the unnecessary includes. Note that the MLIRLLVMIR library did not explicitly depend on MLIRStandardOps, requiring dependees of MLIRLLVMIR to also depend on MLIRStandardOps, which should no longer be the case. PiperOrigin-RevId: 258148456
* Lower affine control flow to std control flow to LLVM dialectNicolas Vasilache2019-07-121-1/+5
| | | | | | | | | | | | | This CL splits the lowering of affine to LLVM into 2 parts: 1. affine -> std 2. std -> LLVM The conversions mostly consists of splitting concerns between the affine and non-affine worlds from existing conversions. Short-circuiting of affine `if` conditions was never tested or exercised and is removed in the process, it can be reintroduced later if needed. LoopParametricTiling.cpp is updated to reflect the newly added ForOp::build. PiperOrigin-RevId: 257794436
* Rename FunctionAttr to SymbolRefAttr.River Riddle2019-07-121-2/+2
| | | | | | This allows for the attribute to hold symbolic references to other operations than FuncOp. This also allows for removing the dependence on FuncOp from the base Builder. PiperOrigin-RevId: 257650017
* NFC: Replace Module::getNamedFunction with lookupSymbol<FuncOp>.River Riddle2019-07-121-2/+3
| | | | | | This allows for removing the last direct reference to FuncOp from ModuleOp. PiperOrigin-RevId: 257498296
* NFC: Remove Function::getModule.River Riddle2019-07-121-6/+5
| | | | | | There is already a more general 'getParentOfType' method, and 'getModule' is likely to be misused as functions get placed within different regions than ModuleOp. PiperOrigin-RevId: 257442243
* NFC: Rename Module to ModuleOp.River Riddle2019-07-101-2/+2
| | | | | | Module is a legacy name that only exists as a typedef of ModuleOp. PiperOrigin-RevId: 257427248
* NFC: Rename Function to FuncOp.River Riddle2019-07-101-4/+4
| | | | PiperOrigin-RevId: 257293379
* NFC: Remove `Module::getFunctions` in favor of a general `getOps<T>`.River Riddle2019-07-081-1/+1
| | | | | | Modules can now contain more than just Functions, this just updates the iteration API to reflect that. The 'begin'/'end' methods have also been updated to iterate over opaque Operations. PiperOrigin-RevId: 257099084
* NFC: Remove the various "::getFunction" methods.River Riddle2019-07-081-4/+5
| | | | | | 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
* Add missing mlir:: namespace in definition of createConvertToLLVMIRPass.Stephan Herhut2019-07-041-2/+2
| | | | PiperOrigin-RevId: 256546769
* Make ConvertStandardToLLVMPass extendable with other patternsAlex Zinenko2019-07-041-7/+43
| | | | | | | | | | | Extend the LLVM lowering pass to accept callbacks that construct an instance of (a subclass of) LLVMTypeConverter and populate a list of conversion patterns. These callbacks will be called when the pass processes a module and their results will be used to set up the dialect conversion infrastructure. Clients can now provide additional conversion patterns to avoid the need of materializing type conversions between LLVM and other types. PiperOrigin-RevId: 256532415
* NFC: Refactor Module to be value typed.River Riddle2019-07-021-8/+8
| | | | | | As with Functions, Module will soon become an operation, which are value-typed. This eases the transition from Module to ModuleOp. A new class, OwningModuleRef is provided to allow for owning a reference to a Module, and will auto-delete the held module on destruction. PiperOrigin-RevId: 256196193
* NFC: Refactor Function to be value typed.River Riddle2019-07-011-9/+9
| | | | | | 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
* Move the emitError/Warning/Remark utility methods out of MLIRContext and ↵River Riddle2019-06-251-6/+4
| | | | | | | | 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
* Refactor the TypeConverter to support more robust type conversions:River Riddle2019-06-191-19/+14
| | | | | | | | | | | | * Support for 1->0 type mappings, i.e. when the argument is being removed. * Reordering types when converting a type signature. * Adding new inputs when converting a type signature. This cl also lays down the initial foundation for supporting 1->N type mappings, but full support will come in a followup. Moving forward, function signature changes will be driven by populating a SignatureConversion instance. This class contains all of the necessary information for adding/removing/remapping function signatures; e.g. addInputs, addResults, remapInputs, etc. PiperOrigin-RevId: 254064665
* Introduce std.index_cast and its lowering+translation to LLVMAlex Zinenko2019-06-191-5/+36
| | | | | | | | | | | | | | | | | | Index types integers of platform-specific bit width. They are used to index memrefs and as loop induction variables, however they could not be obtained from an integer until now, making it virtually impossible to express indirect accesses (given that memrefs of indices are not allowed) or data-dependent loops. Introduce `std.index_cast` to transform indices into integers and vice versa. The semantics of this cast is to sign-extend when casting to a wider integer, and to truncate when casting to a narrower integer. It belongs to StandardOps because both types it operates on are standard types, and because its results are likely to be used in std.load and std.store. Introduce llvm.sext, llvm.zext and llvm.trunc operations to the LLVM dialect. Provide the conversion of `std.index_cast` to llvm.sext or llvm.trunc, depending on the actual bitwidth of `index` known during the conversion. PiperOrigin-RevId: 253624100
* Start moving conversions to {lib,include/mlir}/ConversionAlex Zinenko2019-06-191-0/+1010
Conversions from dialect A to dialect B depend on both A and B. Therefore, it is reasonable for them to live in a separate library that depends on both DialectA and DialectB library, and does not forces dependees of DialectA or DialectB to also link in the conversion. Create the directory layout for the conversions and move the Standard to LLVM dialect conversion as the first example. PiperOrigin-RevId: 253312252
OpenPOWER on IntegriCloud