Commit Graph

65 Commits

Author SHA1 Message Date
Alex Zinenko 19db802e7b [mlir] make implementations of translation to LLVM IR interfaces private
There is no need for the interface implementations to be exposed, opaque
registration functions are sufficient for all users, similarly to passes.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D97852
2021-03-04 09:16:32 +01:00
Alex Zinenko ce8f10d6cb [mlir] Simplify ModuleTranslation for LLVM IR
A series of preceding patches changed the mechanism for translating MLIR to
LLVM IR to use dialect interface with delayed registration. It is no longer
necessary for specific dialects to derive from ModuleTranslation. Remove all
virtual methods from ModuleTranslation and factor out the entry point to be a
free function.

Also perform some cleanups in ModuleTranslation internals.

Depends On D96774

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D96775
2021-02-16 18:42:52 +01:00
Alex Zinenko 176379e0c8 [mlir] Use the interface-based translation for LLVM "intrinsic" dialects
Port the translation of five dialects that define LLVM IR intrinsics
(LLVMAVX512, LLVMArmNeon, LLVMArmSVE, NVVM, ROCDL) to the new dialect
interface-based mechanism. This allows us to remove individual translations
that were created for each of these dialects and just use one common
MLIR-to-LLVM-IR translation that potentially supports all dialects instead,
based on what is registered and including any combination of translatable
dialects. This removal was one of the main goals of the refactoring.

To support the addition of GPU-related metadata, the translation interface is
extended with the `amendOperation` function that allows the interface
implementation to post-process any translated operation with dialect attributes
from the dialect for which the interface is implemented regardless of the
operation's dialect. This is currently applied to "kernel" functions, but can
be used to construct other metadata in dialect-specific ways without
necessarily affecting operations.

Depends On D96591, D96504

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D96592
2021-02-15 14:43:07 +01:00
Alex Zinenko 66900b3eae [mlir] Use dialect interfaces to translate OpenMP dialect to LLVM IR
Migrate the translation of the OpenMP dialect operations to LLVM IR to the new
dialect-based mechanism.

Depends On D96503

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D96504
2021-02-12 18:37:47 +01:00
Alex Zinenko b77bac0572 [mlir] Introduce dialect interfaces for translation to LLVM IR
The existing approach to translation to the LLVM IR relies on a single
translation supporting the base LLVM dialect, extensible through inheritance to
support intrinsic-based dialects also derived from LLVM IR such as NVVM and
AVX512. This approach does not scale well as it requires additional
translations to be created for each new intrinsic-based dialect and does not
allow them to mix in the same module, contrary to the rest of the MLIR
infrastructure. Furthermore, OpenMP translation ingrained itself into the main
translation mechanism.

Start refactoring the translation to LLVM IR to operate using dialect
interfaces. Each dialect that contains ops translatable to LLVM IR can
implement the interface for translating them, and the top-level translation
driver can operate on interfaces without knowing about specific dialects.
Furthermore, the delayed dialect registration mechanism allows one to avoid a
dependency on LLVM IR in the dialect that is translated to it by implementing
the translation as a separate library and only registering it at the client
level.

This change introduces the new mechanism and factors out the translation of the
"main" LLVM dialect. The remaining dialects will follow suit.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D96503
2021-02-12 17:49:44 +01:00
Mehdi Amini 2af37cf7ff Check for nullptr before dereferencing in translateModuleToLLVMIR()
This is defensive with respect to invocations of this API with an IR
that isn't ready to be converted to LLVM IR.
2020-11-06 04:09:18 +00:00
Kiran Chandramohan ab8a4cec55 [MLIR] NFC : Move OpenMP dialect include to translation
The OpenMP dialect include is only needed for translation
and is not required in LLVM dialect.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D90510
2020-11-03 22:12:10 +00:00
Tim Shen f0506e4923 [MLIR] Avoid adding debuginfo for a function if it contains calls that has no debug info.
Also add a verifier pass to ExecutionEngine.

It's hard to come up with a test case, since mlir-opt always add location info after parsing it (?)

Differential Revision: https://reviews.llvm.org/D88135
2020-09-29 13:51:56 -07:00
Mehdi Amini 9f9f89d44b Remove dependency from LLVM Dialect on the OpenMP dialect
The OmpDialect is in practice optional during translation to LLVM IR: the code is tolerant
to have a "nullptr" when not present / needed.

The dependency still exists on the export to LLVMIR.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D88351
2020-09-29 01:12:01 +00:00
Mehdi Amini f164534ca8 Add a `dialect_registration` callback for "translations" registered with mlir-translate
This will allow out-of-tree translation to register the dialects they expect
to see in their input, on the model of getDependentDialects() for passes.

Differential Revision: https://reviews.llvm.org/D86409
2020-08-23 01:00:39 +00:00
Alex Zinenko db1c197bf8 [mlir] take LLVMContext in MLIR-to-LLVM-IR translation
Due to the original type system implementation, LLVMDialect in MLIR contains an
LLVMContext in which the relevant objects (types, metadata) are created. When
an MLIR module using the LLVM dialect (and related intrinsic-based dialects
NVVM, ROCDL, AVX512) is converted to LLVM IR, it could only live in the
LLVMContext owned by the dialect. The type system no longer relies on the
LLVMContext, so this limitation can be removed. Instead, translation functions
now take a reference to an LLVMContext in which the LLVM IR module should be
constructed. The caller of the translation functions is responsible for
ensuring the same LLVMContext is not used concurrently as the translation no
longer uses a dialect-wide context lock.

As an additional bonus, this change removes the need to recreate the LLVM IR
module in a different LLVMContext through printing and parsing back, decreasing
the compilation overhead in JIT and GPU-kernel-to-blob passes.

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D85443
2020-08-07 14:22:30 +02:00
Jonathan Roelofs 223154d267 [mlir] Remove need for static global ctors from mlir-translate
Summary: https://bugs.llvm.org/show_bug.cgi?id=45436

Reviewers: mehdi_amini, mravishankar, antiagainst, rriddle, stephenneuendorffer

Reviewed By: mehdi_amini, rriddle, stephenneuendorffer

Subscribers: frgossen, stephenneuendorffer, jholewinski, mgorny, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, Joonsoo, bader, grosul1, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D77515
2020-04-08 16:52:33 -06: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
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 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
Lei Zhang b00a522b80 Change MLIR translation functions signature
This CL changes translation functions to take MemoryBuffer
as input and raw_ostream as output. It is generally better to
avoid handling files directly in a library (unless the library
is specifically for file manipulation) and we can unify all
file handling to the mlir-translate binary itself.

PiperOrigin-RevId: 269625911
2019-09-17 12:16:45 -07:00
River Riddle fec20e590f NFC: Rename Module to ModuleOp.
Module is a legacy name that only exists as a typedef of ModuleOp.

PiperOrigin-RevId: 257427248
2019-07-10 10:11:21 -07:00
Alex Zinenko 6f7f2bced8 Make TranslateFromMLIRFunction type return LogicalResult instead of bool
This interface was created before MLIR introduced LogicalResult.

PiperOrigin-RevId: 256554557
2019-07-04 08:19:14 -07:00
River Riddle 206e55cc16 NFC: Refactor Module to be value typed.
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
2019-07-02 16:43:36 -07:00
Jacques Pienaar cde4d5a6d9 Remove unnecessary C++ specifier in CPP files. NFC.
These are only required in .h files to disambiguate between C and C++ header files.

--

PiperOrigin-RevId: 248219135
2019-05-20 13:42:13 -07:00
Stephan Herhut 5d7231d812 Add transformation of the NVVM dialect to an LLVM module. Only handles
the generation of intrinsics out of NVVM index ops for now.

--

PiperOrigin-RevId: 245933152
2019-05-06 08:22:14 -07:00
Mehdi Amini 7286d43920 Introduce std.varargs attribute to mark variadic arguments functions
This is only teaching the LLVM converter to propagate the attribute onto
    the function type. MLIR will not recognize this arguments, so it would only
    be useful when calling for example `printf` with the same arguments across
    a module. Since varargs is part of the ABI lowering, this is not NFC.

--

PiperOrigin-RevId: 242382427
2019-04-07 18:22:56 -07:00
Alex Zinenko 33285de937 ExecutionEngine: allow for running MLIR passes during JIT-compilation
The existing implementation of the ExecutionEngine unconditionally runs a list
    of "default" MLIR passes on the module upon creation.  These passes include,
    among others, dialect conversions from affine to standard and from standard to
    LLVM IR dialects.  In some cases, these conversions might have been performed
    before ExecutionEngine is created.  More advanced use cases may be performing
    additional transformations that the "default" passes will conflict with.
    Provide an overload for ExecutionEngine::create that takes a PassManager
    configured with the passes to run on the module.  If it is not provided, do not
    run any passes.  The engine will not be created if the input module, after the
    pass manager, has any other dialect than the LLVM IR dialect.

--

PiperOrigin-RevId: 242127393
2019-04-07 18:19:23 -07:00
River Riddle af9760fe18 Replace remaining usages of the Instruction class with Operation.
PiperOrigin-RevId: 240777521
2019-03-29 17:50:04 -07:00
River Riddle 5f3b914a6e Replace remaining usages of "Op::operator->" with "." and remove it.
PiperOrigin-RevId: 240210336
2019-03-29 17:40:25 -07:00
Chris Lattner 986310a68f Remove const from Value, Instruction, Argument, and the various methods on the
*Op classes.  This is a net reduction by almost 400LOC.

PiperOrigin-RevId: 239972443
2019-03-29 17:34:33 -07:00
Chris Lattner 3d6c74fff5 Remove const from mlir::Block.
This also eliminates some incorrect reinterpret_cast logic working around it, and numerous const-incorrect issues (like block argument iteration).

PiperOrigin-RevId: 239712029
2019-03-29 17:30:30 -07:00
Chris Lattner 88e9f418f5 Continue pushing const out of the core IR types - in this case, remove const
from Function.

PiperOrigin-RevId: 239638635
2019-03-29 17:29:58 -07:00
Chris Lattner 8d526ef173 Continue pushing const out of the IR types - removing the notion of a 'const
Module'.  NFC.

PiperOrigin-RevId: 239532885
2019-03-29 17:27:26 -07:00
Alex Zinenko dbaab04a80 TableGen most of the LLVM IR Dialect to LLVM IR conversions
The LLVM IR Dialect strives to be close to the original LLVM IR instructions.
The conversion from the LLVM IR Dialect to LLVM IR proper is mostly mechanical
and can be automated.  Implement TableGen support for generating conversions
from a concise pattern form in the TableGen definition of the LLVM IR Dialect
operations.  It is used for all operations except calls and branches.  These
operations need access to function and block remapping tables and would require
significantly more code to generate the conversions from TableGen definitions
than the current manually written conversions.

This implementation is accompanied by various necessary changes to the TableGen
operation definition infrastructure.  In particular, operation definitions now
contain named accessors to results as well as named accessors to the variadic
operand (returning a vector of operands).  The base operation support TableGen
file now contains a FunctionAttr definition.  The TableGen now allows to query
the names of the operation results.

PiperOrigin-RevId: 237203077
2019-03-29 17:04:50 -07:00
Dimitrios Vytiniotis 480cc2b063 Using llvm.noalias attribute when generating LLVMIR.
PiperOrigin-RevId: 237063104
2019-03-29 17:01:11 -07:00
Lei Zhang 85d9b6c8f7 Use consistent names for dialect op source files
This CL changes dialect op source files (.h, .cpp, .td) to follow the following
convention:

  <full-dialect-name>/<dialect-namespace>Ops.{h|cpp|td}

Builtin and standard dialects are specially treated, though. Both of them do
not have dialect namespace; the former is still named as BuiltinOps.* and the
latter is named as Ops.*.

Purely mechanical. NFC.

PiperOrigin-RevId: 236371358
2019-03-29 16:53:19 -07:00
Alex Zinenko 8cc50208a6 LLVM IR Dialect: unify call and call0 operations
When the LLVM IR dialect was implemented, TableGen operation definition scheme
did not support operations with variadic results.  Therefore, the `call`
instruction was split into `call` and `call0` for the single- and zero-result
calls (LLVM does not support multi-result operations).  Unify `call` and
`call0` using the recently added TableGen support for operations with Variadic
results.  Explicitly verify that the new operation has 0 or 1 results.  As a
side effect, this change enables clean-ups in the conversion to the LLVM IR
dialect that no longer needs to rely on wrapped LLVM IR void types when
constructing zero-result calls.

PiperOrigin-RevId: 236119197
2019-03-29 16:49:59 -07:00
River Riddle 79944e5eef Add a Function::isExternal utility to simplify checks for external functions.
PiperOrigin-RevId: 235746553
2019-03-29 16:43:50 -07:00
Alex Zinenko 1da1b4c321 LLVM IR dialect and translation: support conditional branches with arguments
Since the goal of the LLVM IR dialect is to reflect LLVM IR in MLIR, the
dialect and the conversion procedure must account for the differences betweeen
block arguments and LLVM IR PHI nodes. In particular, LLVM IR disallows PHI
nodes with different values coming from the same source. Therefore, the LLVM IR
dialect now disallows `cond_br` operations that have identical successors
accepting arguments, which would lead to invalid PHI nodes. The conversion
process resolves the potential PHI source ambiguity by injecting dummy blocks
if the same block is used more than once as a successor in an instruction.
These dummy blocks branch unconditionally to the original successors, pass them
the original operands (available in the dummy block because it is dominated by
the original block) and are used instead of them in the original terminator
operation.

PiperOrigin-RevId: 235682798
2019-03-29 16:43:05 -07:00
Alex Zinenko ffc9043604 LLVM dialect conversion and target: support indirect calls
Add support for converting MLIR `call_indirect` instructions to the LLVM IR
dialect.  In LLVM IR, the same instruction is used for direct and indirect
calls.  In the dialect, we have `llvm.call` and `llvm.call0` to work around the
absence of the void type in MLIR.  For direct calls, the callee is stored as
instruction attribute.  Use the same pair of instructions for indirect calls by
omitting the callee attribute.  In the MLIR to LLVM IR translator, check the
presence of attribute to decide whether to construct a direct or an indirect
call using different LLVM IR Builder functions.

Add support for converting constants of function type to the LLVM IR dialect
and for translating them to the LLVM IR proper.  The `llvm.constant` operation
works similarly to other types: its attribute has MLIR function type but the
value it produces has LLVM IR function type wrapped in the dialect type.  While
lowering, look up the pointer to the converted function in the corresponding
mapping.

PiperOrigin-RevId: 234132351
2019-03-29 16:28:56 -07:00
Alex Zinenko 50700b8122 Reimplement LLVM IR translation to use the MLIR LLVM IR dialect
Original implementation of the translation from MLIR to LLVM IR operated on the
Standard+BuiltIn dialect, with a later addition of the SuperVector dialect.
This required the translation to be aware of a potetially large number of other
dialects as the infrastructure extended.  With the recent introduction of the
LLVM IR dialect into MLIR, the translation can be switched to only translate
the LLVM IR dialect, and the translation of the operations becomes largely
mechanical.

The reimplementation of the translator follows the lines of the original
translator in function and basic block conversion.  In particular, block
arguments are converted to LLVM IR PHI nodes, which are connected to their
sources after all blocks of a function had been converted.  Thanks to LLVM IR
types being wrapped in the MLIR LLVM dialect type, type conversion is
simplified to only convert function types, all other types are simply
unwrapped.  Individual instructions are constructed using the LLVM IRBuilder,
which has a great potential for being table-generated from the LLVM IR dialect
operation definitions.

The input of the test/Target/llvmir.mlir is updated to use the MLIR LLVM IR
dialect.  While it is now redundant with the dialect conversion test, the point
of the exercise is to guarantee exactly the same LLVM IR is emitted.  (Only the
name of the allocation function is changed from `__mlir_alloc` to `alloc` in
the CHECK lines.)  It will be simplified in a follow-up commit.

PiperOrigin-RevId: 233842306
2019-03-29 16:27:10 -07:00
River Riddle 44e040dd63 Remove remaining references to OperationInst in all directories except for lib/Transforms.
PiperOrigin-RevId: 232322771
2019-03-29 16:10:38 -07:00
River Riddle de2d0dfbca Fold the functionality of OperationInst into Instruction. OperationInst still exists as a forward declaration and will be removed incrementally in a set of followup cleanup patches.
PiperOrigin-RevId: 232198540
2019-03-29 16:09:19 -07:00
River Riddle c46b0feadb Fix use of llvm::Module::getOrInsertFunction after the upstream opaque pointer type changes.
PiperOrigin-RevId: 232002583
2019-03-29 16:05:39 -07:00
Jacques Pienaar b52dd7f788 Use formatv for the error instead of string stream.
PiperOrigin-RevId: 231507680
2019-03-29 16:01:08 -07:00
River Riddle 6859f33292 Migrate VectorOrTensorType/MemRefType shape api to use int64_t instead of int.
PiperOrigin-RevId: 230605756
2019-03-29 15:33:20 -07:00
Uday Bondhugula 6e4f3e40c7 Fix outdated comments
PiperOrigin-RevId: 229300301
2019-03-29 15:16:08 -07:00
Lei Zhang ac5a50e1e4 Extract openInputFile() into Support/FileUtilities
Multiple binaries have the needs to open input files. Use this function
to de-duplicate the code.

Also changed openOutputFile() to return errors using std::string since
it is a library call and accessing I/O in library call is not friendly.

PiperOrigin-RevId: 228878221
2019-03-29 15:09:11 -07:00
Alex Zinenko caa7e70627 LLVM IR lowering: support integer division and remainder operations
These operations trivially map to LLVM IR counterparts for operands of scalar
and (one-dimensional) vector type.  Multi-dimensional vector and tensor type
operands would fail type conversion before the operation conversion takes
place.  Add tests for scalar and vector cases.  Also add a test for vector
`select` instruction for consistency with other tests.

PiperOrigin-RevId: 228077564
2019-03-29 14:59:07 -07:00
River Riddle 54948a4380 Split the standard types from builtin types and move them into separate source files(StandardTypes.cpp/h). After this cl only FunctionType and IndexType are builtin types, but IndexType will likely become a standard type when the ml/cfgfunc merger is done. Mechanical NFC.
PiperOrigin-RevId: 227750918
2019-03-29 14:54:07 -07:00
Alex Zinenko 0565067495 LLVM IR Lowering: support "select"
This commit adds support for the "select" operation that lowers directly into
its LLVM IR counterpart.  A simple test is included.

PiperOrigin-RevId: 227527893
2019-03-29 14:51:08 -07:00
Chris Lattner 3c8fc797de Simplify the remapFunctionAttrs logic, merging CFG/ML function handling.
Remove an unnecessary restriction in forward substitution.  Slightly
simplify LLVM IR lowering, which previously would crash if given an ML
function, it should now produce a clean error if given a function with an
if/for instruction in it, just like it does any other unsupported op.

This is step 27/n towards merging instructions and statements.

PiperOrigin-RevId: 227324542
2019-03-29 14:49:35 -07:00
Chris Lattner 5b9c3f7cdb Tidy up references to "basic blocks" that should refer to blocks now. NFC.
PiperOrigin-RevId: 227196077
2019-03-29 14:44:59 -07:00
Chris Lattner 456ad6a8e0 Standardize naming of statements -> instructions, revisting the code base to be
consistent and moving the using declarations over.  Hopefully this is the last
truly massive patch in this refactoring.

This is step 21/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227178245
2019-03-29 14:44:30 -07:00