Commit Graph

148 Commits

Author SHA1 Message Date
River Riddle
09f7a55fad [mlir][Types][NFC] Move all of the builtin Type classes to BuiltinTypes.h
This is part of a larger refactoring the better congregates the builtin structures under the BuiltinDialect. This also removes the problematic "standard" naming that clashes with the "standard" dialect, which is not defined within IR/. A temporary forward is placed in StandardTypes.h to allow time for downstream users to replaced references.

Differential Revision: https://reviews.llvm.org/D92435
2020-12-03 18:02:10 -08:00
Nicolas Vasilache
047400ed82 [mlir][LLVMIR] Add support for InlineAsmOp
The InlineAsmOp mirrors the underlying LLVM semantics with a notable
exception: the embedded `asm_string` is not allowed to define or reference
any symbol or any global variable: only the operands of the op may be read,
written, or referenced.
Attempting to define or reference any symbol or any global behavior is
considered undefined behavior at this time.

The asm dialect syntax is currently specified with an integer (0 [default] for the "att dialect", 1 for the intel dialect) to circumvent the ODS limitation on string enums.

Translation to LLVM is provided and raises the fact that the asm constraints string must be well-formed with respect to in/out operands. No check is performed on the asm_string.

An InlineAsm instruction in LLVM is a special call operation to a function that is constructed on the fly.
It does not fit the current model of MLIR calls with symbols.
As a consequence, the current implementation constructs the function type in ModuleTranslation.cpp.
This should be refactored in the future.

The mlir-cpu-runner is augmented with the global initialization of the X86 asm parser to allow proper execution in JIT mode. Previously, only the X86 asm printer was initialized.

Differential revision: https://reviews.llvm.org/D92166
2020-11-30 08:32:02 +00:00
River Riddle
65fcddff24 [mlir][BuiltinDialect] Resolve comments from D91571
* Move ops to a BuiltinOps.h
* Add file comments
2020-11-19 11:12:49 -08:00
River Riddle
73ca690df8 [mlir][NFC] Remove references to Module.h and Function.h
These includes have been deprecated in favor of BuiltinDialect.h, which contains the definitions of ModuleOp and FuncOp.

Differential Revision: https://reviews.llvm.org/D91572
2020-11-17 00:55:47 -08:00
David Sherwood
4b1a55a92f Fix build failures caused by f4257c5832 2020-08-28 14:56:01 +01:00
Mehdi Amini
f9dc2b7079 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally
registered dialects on construction. Instead Dialects are only loaded explicitly
on demand:
- the Parser is lazily loading Dialects in the context as it encounters them
during parsing. This is the only purpose for registering dialects and not load
them in the context.
- Passes are expected to declare the dialects they will create entity from
(Operations, Attributes, or Types), and the PassManager is loading Dialects into
the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only
need to load the dialect for the IR it will emit, and the optimizer is
self-contained and load the required Dialects. For example in the Toy tutorial,
the compiler only needs to load the Toy dialect in the Context, all the others
(linalg, affine, std, LLVM, ...) are automatically loaded depending on the
optimization pipeline enabled.

To adjust to this change, stop using the existing dialect registration: the
global registry will be removed soon.

1) For passes, you need to override the method:

virtual void getDependentDialects(DialectRegistry &registry) const {}

and registery on the provided registry any dialect that this pass can produce.
Passes defined in TableGen can provide this list in the dependentDialects list
field.

2) For dialects, on construction you can register dependent dialects using the
provided MLIRContext: `context.getOrLoadDialect<DialectName>()`
This is useful if a dialect may canonicalize or have interfaces involving
another dialect.

3) For loading IR, dialect that can be in the input file must be explicitly
registered with the context. `MlirOptMain()` is taking an explicit registry for
this purpose. See how the standalone-opt.cpp example is setup:

  mlir::DialectRegistry registry;
  registry.insert<mlir::standalone::StandaloneDialect>();
  registry.insert<mlir::StandardOpsDialect>();

Only operations from these two dialects can be in the input file. To include all
of the dialects in MLIR Core, you can populate the registry this way:

  mlir::registerAllDialects(registry);

4) For `mlir-translate` callback, as well as frontend, Dialects can be loaded in
the context before emitting the IR: context.getOrLoadDialect<ToyDialect>()

Differential Revision: https://reviews.llvm.org/D85622
2020-08-19 01:19:03 +00:00
Mehdi Amini
e75bc5c791 Revert "Separate the Registration from Loading dialects in the Context"
This reverts commit d14cf45735.
The build is broken with GCC-5.
2020-08-19 01:19:03 +00:00
Mehdi Amini
d14cf45735 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally
registered dialects on construction. Instead Dialects are only loaded explicitly
on demand:
- the Parser is lazily loading Dialects in the context as it encounters them
during parsing. This is the only purpose for registering dialects and not load
them in the context.
- Passes are expected to declare the dialects they will create entity from
(Operations, Attributes, or Types), and the PassManager is loading Dialects into
the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only
need to load the dialect for the IR it will emit, and the optimizer is
self-contained and load the required Dialects. For example in the Toy tutorial,
the compiler only needs to load the Toy dialect in the Context, all the others
(linalg, affine, std, LLVM, ...) are automatically loaded depending on the
optimization pipeline enabled.

To adjust to this change, stop using the existing dialect registration: the
global registry will be removed soon.

1) For passes, you need to override the method:

virtual void getDependentDialects(DialectRegistry &registry) const {}

and registery on the provided registry any dialect that this pass can produce.
Passes defined in TableGen can provide this list in the dependentDialects list
field.

2) For dialects, on construction you can register dependent dialects using the
provided MLIRContext: `context.getOrLoadDialect<DialectName>()`
This is useful if a dialect may canonicalize or have interfaces involving
another dialect.

3) For loading IR, dialect that can be in the input file must be explicitly
registered with the context. `MlirOptMain()` is taking an explicit registry for
this purpose. See how the standalone-opt.cpp example is setup:

  mlir::DialectRegistry registry;
  registry.insert<mlir::standalone::StandaloneDialect>();
  registry.insert<mlir::StandardOpsDialect>();

Only operations from these two dialects can be in the input file. To include all
of the dialects in MLIR Core, you can populate the registry this way:

  mlir::registerAllDialects(registry);

4) For `mlir-translate` callback, as well as frontend, Dialects can be loaded in
the context before emitting the IR: context.getOrLoadDialect<ToyDialect>()

Differential Revision: https://reviews.llvm.org/D85622
2020-08-18 23:23:56 +00:00
Mehdi Amini
d84fe55e0d Revert "Separate the Registration from Loading dialects in the Context"
This reverts commit e1de2b7550.
Broke a build bot.
2020-08-18 22:16:34 +00:00
Mehdi Amini
e1de2b7550 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally
registered dialects on construction. Instead Dialects are only loaded explicitly
on demand:
- the Parser is lazily loading Dialects in the context as it encounters them
during parsing. This is the only purpose for registering dialects and not load
them in the context.
- Passes are expected to declare the dialects they will create entity from
(Operations, Attributes, or Types), and the PassManager is loading Dialects into
the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only
need to load the dialect for the IR it will emit, and the optimizer is
self-contained and load the required Dialects. For example in the Toy tutorial,
the compiler only needs to load the Toy dialect in the Context, all the others
(linalg, affine, std, LLVM, ...) are automatically loaded depending on the
optimization pipeline enabled.

To adjust to this change, stop using the existing dialect registration: the
global registry will be removed soon.

1) For passes, you need to override the method:

virtual void getDependentDialects(DialectRegistry &registry) const {}

and registery on the provided registry any dialect that this pass can produce.
Passes defined in TableGen can provide this list in the dependentDialects list
field.

2) For dialects, on construction you can register dependent dialects using the
provided MLIRContext: `context.getOrLoadDialect<DialectName>()`
This is useful if a dialect may canonicalize or have interfaces involving
another dialect.

3) For loading IR, dialect that can be in the input file must be explicitly
registered with the context. `MlirOptMain()` is taking an explicit registry for
this purpose. See how the standalone-opt.cpp example is setup:

  mlir::DialectRegistry registry;
  mlir::registerDialect<mlir::standalone::StandaloneDialect>();
  mlir::registerDialect<mlir::StandardOpsDialect>();

Only operations from these two dialects can be in the input file. To include all
of the dialects in MLIR Core, you can populate the registry this way:

  mlir::registerAllDialects(registry);

4) For `mlir-translate` callback, as well as frontend, Dialects can be loaded in
the context before emitting the IR: context.getOrLoadDialect<ToyDialect>()
2020-08-18 21:14:39 +00:00
Mehdi Amini
25ee851746 Revert "Separate the Registration from Loading dialects in the Context"
This reverts commit 2056393387.

Build is broken on a few bots
2020-08-15 09:21:47 +00:00
Mehdi Amini
2056393387 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally registered dialects on construction. Instead Dialects are only loaded explicitly on demand:
- the Parser is lazily loading Dialects in the context as it encounters them during parsing. This is the only purpose for registering dialects and not load them in the context.
- Passes are expected to declare the dialects they will create entity from (Operations, Attributes, or Types), and the PassManager is loading Dialects into the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only need to load the dialect for the IR it will emit, and the optimizer is self-contained and load the required Dialects. For example in the Toy tutorial, the compiler only needs to load the Toy dialect in the Context, all the others (linalg, affine, std, LLVM, ...) are automatically loaded depending on the optimization pipeline enabled.

Differential Revision: https://reviews.llvm.org/D85622
2020-08-15 08:07:31 +00:00
Mehdi Amini
ba92dadf05 Revert "Separate the Registration from Loading dialects in the Context"
This was landed by accident, will reland with the right comments
addressed from the reviews.
Also revert dependent build fixes.
2020-08-15 07:35:10 +00:00
Mehdi Amini
ebf521e784 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally registered dialects on construction. Instead Dialects are only loaded explicitly on demand:
- the Parser is lazily loading Dialects in the context as it encounters them during parsing. This is the only purpose for registering dialects and not load them in the context.
- Passes are expected to declare the dialects they will create entity from (Operations, Attributes, or Types), and the PassManager is loading Dialects into the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only need to load the dialect for the IR it will emit, and the optimizer is self-contained and load the required Dialects. For example in the Toy tutorial, the compiler only needs to load the Toy dialect in the Context, all the others (linalg, affine, std, LLVM, ...) are automatically loaded depending on the optimization pipeline enabled.
2020-08-14 09:40:27 +00:00
Alex Zinenko
16b0225377 [mlir] do not require LLVMDialect in conversion from LLVM IR
Historically, LLVMDialect has been required in the conversion from LLVM IR in
order to be able to construct types. This is no longer necessary with the new
type model and the dialect can be replaced with a local LLVM context.

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D85444
2020-08-07 14:27:04 +02:00
Alex Zinenko
b2ab375d1f [mlir] use the new stateful LLVM type translator by default
Previous type model in the LLVM dialect did not support identified structure
types properly and therefore could use stateless translations implemented as
free functions. The new model supports identified structs and must keep track
of the identified structure types present in the target context (LLVMContext or
MLIRContext) to avoid creating duplicate structs due to LLVM's type
auto-renaming. Expose the stateful type translation classes and use them during
translation, storing the state as part of ModuleTranslation.

Drop the test type translation mechanism that is no longer necessary and update
the tests to exercise type translation as part of the main translation flow.

Update the code in vector-to-LLVM dialect conversion that relied on stateless
translation to use the new class in a stateless manner.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D85297
2020-08-06 00:36:33 +02:00
Alex Zinenko
aec38c619d [mlir] LLVMType: make getUnderlyingType private
The current modeling of LLVM IR types in MLIR is based on the LLVMType class
that wraps a raw `llvm::Type *` and delegates uniquing, printing and parsing to
LLVM itself. This is model makes thread-safe type manipulation hard and is
being progressively replaced with a cleaner MLIR model that replicates the type
system. In the new model, LLVMType will no longer have an underlying LLVM IR
type. Restrict access to this type in the current model in preparation for the
change.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D84389
2020-07-29 13:43:38 +02:00
Alex Zinenko
ebbdecdd57 [mlir] Support translating function linkage between MLIR and LLVM IR
Linkage support is already present in the LLVM dialect, and is being translated
for globals other than functions. Translation support has been missing for
functions because their conversion goes through a different code path than
other globals.

Differential Revision: https://reviews.llvm.org/D84149
2020-07-20 14:04:31 +02:00
Rahul Joshi
0d988da6d1 [MLIR] Change ODS collective params build method to provide an empty default value for named attributes
- Provide default value for `ArrayRef<NamedAttribute> attributes` parameter of
  the collective params build method.
- Change the `genSeparateArgParamBuilder` function to not generate build methods
  that may be ambiguous with the new collective params build method.
- This change should help eliminate passing empty NamedAttribue ArrayRef when the
  collective params build method is used
- Extend op-decl.td unit test to make sure the ambiguous build methods are not
  generated.

Differential Revision: https://reviews.llvm.org/D83517
2020-07-13 13:35:44 -07:00
Alex Zinenko
cba733edf5 [mlir] LLVM dialect: use addressof instead of constant to create function pointers
`llvm.mlir.constant` was originally introduced as an LLVM dialect counterpart
to `std.constant`. As such, it was supporting "function pointer" constants
derived from the symbol name. This is different from `std.constant` that allows
for creation of a "function" constant since MLIR, unlike LLVM IR, supports
this. Later, `llvm.mlir.addressof` was introduced as an Op that obtains a
constant pointer to a global in the LLVM dialect. It naturally extends to
functions (in LLVM IR, functions are globals) and should be used for defining
"function pointer" values instead.

Fixes PR46344.

Differential Revision: https://reviews.llvm.org/D82667
2020-06-29 12:21:33 +02:00
Rahul Joshi
d891d738d9 [MLIR][NFC] Adopt variadic isa<>
Differential Revision: https://reviews.llvm.org/D82489
2020-06-24 17:02:44 -07:00
Eli Friedman
4532a50899 Infer alignment of unmarked loads in IR/bitcode parsing.
For IR generated by a compiler, this is really simple: you just take the
datalayout from the beginning of the file, and apply it to all the IR
later in the file. For optimization testcases that don't care about the
datalayout, this is also really simple: we just use the default
datalayout.

The complexity here comes from the fact that some LLVM tools allow
overriding the datalayout: some tools have an explicit flag for this,
some tools will infer a datalayout based on the code generation target.
Supporting this properly required plumbing through a bunch of new
machinery: we want to allow overriding the datalayout after the
datalayout is parsed from the file, but before we use any information
from it. Therefore, IR/bitcode parsing now has a callback to allow tools
to compute the datalayout at the appropriate time.

Not sure if I covered all the LLVM tools that want to use the callback.
(clang? lli? Misc IR manipulation tools like llvm-link?). But this is at
least enough for all the LLVM regression tests, and IR without a
datalayout is not something frontends should generate.

This change had some sort of weird effects for certain CodeGen
regression tests: if the datalayout is overridden with a datalayout with
a different program or stack address space, we now parse IR based on the
overridden datalayout, instead of the one written in the file (or the
default one, if none is specified). This broke a few AVR tests, and one
AMDGPU test.

Outside the CodeGen tests I mentioned, the test changes are all just
fixing CHECK lines and moving around datalayout lines in weird places.

Differential Revision: https://reviews.llvm.org/D78403
2020-05-14 13:03:50 -07:00
Craig Topper
a58b62b4a2 [IR] Replace all uses of CallBase::getCalledValue() with getCalledOperand().
This method has been commented as deprecated for a while. Remove
it and replace all uses with the equivalent getCalledOperand().

I also made a few cleanups in here. For example, to removes use
of getElementType on a pointer when we could just use getFunctionType
from the call.

Differential Revision: https://reviews.llvm.org/D78882
2020-04-27 22:17:03 -07:00
Christopher Tetreault
2dea3f1298 [SVE] Add new VectorType subclasses
Summary:
Introduce new types for fixed width and scalable vectors.

Does not remove getNumElements yet so as to not break code during transition
period.

Reviewers: deadalnix, efriedma, sdesmalen, craig.topper, huntergr

Reviewed By: sdesmalen

Subscribers: jholewinski, arsenm, jvesely, nhaehnle, mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, csigg, arpith-jacob, mgester, lucyrfox, liufengdb, kerbowa, Joonsoo, grosul1, frgossen, lldb-commits, tschuett, hiraditya, rkruppe, psnobl, llvm-commits

Tags: #llvm, #lldb

Differential Revision: https://reviews.llvm.org/D77587
2020-04-22 08:59:01 -07:00
Christopher Tetreault
92dde8a657 Clean up usages of asserting vector getters in Type
Summary:
Remove usages of asserting vector getters in Type in preparation for the
VectorType refactor. The existence of these functions complicates the
refactor while adding little value.

Reviewers: rriddle, efriedma, sdesmalen

Reviewed By: sdesmalen

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

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D77258
2020-04-10 13:46:18 -07: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
River Riddle
67bdda6350 [mlir][NFC] Wrap static DenseMap inside of a function to avoid the need for a global static initializer
This also helps to abstract away the exact implementation details of the loopup method if we wish to change it in the future.
2020-04-08 14:18:35 -07:00
Mehdi Amini
bab5bcf8fd Add a flag on the context to protect against creation of operations in unregistered dialects
Differential Revision: https://reviews.llvm.org/D76903
2020-03-30 19:37:31 +00:00
Shraiysh Vaishay
ff77397fcf [mlir] Added llvm.resume and personality functions in LLVM IR Dialect
`llvm.resume` is similar to `llvm.return` except that has to be exactly
one operand and that should be derived from a `llvm.landingpad`
instruction.  Any function having `llvm.landingpad` instruction must
have a personality attribute.

Example:
LLVM IR
```
define dso_local i32 @main() personality i32 (...)* @__gxx_personality_v0 {
  invoke void @foo(i32 42)
          to label %3 unwind label %1

1:                                                ; preds = %0
  %2 = landingpad i8*
          catch i8** @_ZTIi
          catch i8* bitcast (i8** @_ZTIi to i8*)
  resume i8* %2

3:                                                ; preds = %0
  ret i32 1
}
```

MLIR - LLVM IR Dialect

```
llvm.func @main() -> !llvm.i32 attributes {personality = @__gxx_personality_v0} {
    %0 = llvm.mlir.constant(1 : i32) : !llvm.i32
    %1 = llvm.mlir.addressof @_ZTIi : !llvm<"i8**">
    %2 = llvm.bitcast %1 : !llvm<"i8**"> to !llvm<"i8*">
    %3 = llvm.mlir.addressof @_ZTIi : !llvm<"i8**">
    %4 = llvm.mlir.constant(42 : i32) : !llvm.i32
    llvm.invoke @foo(%4) to ^bb2 unwind ^bb1 : (!llvm.i32) -> ()
  ^bb1:	// pred: ^bb0
    %5 = llvm.landingpad (catch %3 : !llvm<"i8**">) (catch %2 : !llvm<"i8*">) : !llvm<"i8*">
    llvm.resume %5 : !llvm<"i8*">
  ^bb2:	// pred: ^bb0
    llvm.return %0 : !llvm.i32
  }
```

Differential Revision: https://reviews.llvm.org/D71888
2020-03-19 13:14:25 +01:00
Sagar Jain
76cf14035b [MLIR] Added llvm.fence
This patch adds llvm.fence. I tried not to change the syntax much.

syntax:

LLVM IR
`fence [syncscope("<target-scope>")] <ordering>`

MLIR LLVM Dialect

`llvm.fence [syncscope("<target-scope>")] <ordering>`

example:
LLVM IR: `fence syncscope("agent") seq_cst`
MLIR: `llvm.fence syncscope("agent") seq_cst`

Differential Revision: https://reviews.llvm.org/D75645
2020-03-17 17:53:37 +01: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
Sagar Jain
d85821dfa6 [MLIR] Added llvm.freeze
This patch adds llvm.freeze & processes undef constants from LLVM IR.

Syntax:
LLVM IR
`<result> = freeze ty <val>`

MLIR LLVM Dialect:
`llvm.freeze val attr-dict : type`

Example:
LLVM IR: `%3 = freeze i32 5`
MLIR: `%6 = llvm.freeze %5 : !llvm.i32`

Differential Revision: https://reviews.llvm.org/D75329
2020-03-02 10:24:01 +01:00
Mehdi Amini
ea4652ebeb Fix unused variable warning (NFC)
Use isa<> instead of dyn_cast<> when the result isn't used.
2020-02-04 03:38:13 +00:00
Alex Zinenko
eb67bd78dc [mlir] LLVM dialect: Generate conversions between EnumAttrCase and LLVM API
Summary:
MLIR materializes various enumeration-based LLVM IR operands as enumeration
attributes using ODS. This requires bidirectional conversion between different
but very similar enums, currently hardcoded. Extend the ODS modeling of
LLVM-specific enumeration attributes to include the name of the corresponding
enum in the LLVM C++ API as well as the names of specific enumerants. Use this
new information to automatically generate the conversion functions between enum
attributes and LLVM API enums in the two-way conversion between the LLVM
dialect and LLVM IR proper.

Differential Revision: https://reviews.llvm.org/D73468
2020-01-30 21:54:56 +01:00
Shraiysh Vaishay
d242aa245c [MLIR] Added llvm.invoke and llvm.landingpad
Summary:
I have tried to implement `llvm.invoke` and `llvm.landingpad`.

  # `llvm.invoke` is similar to `llvm.call` with two successors added, the first one is the normal label and the second one is unwind label.
  # `llvm.launchpad` takes a variable number of args with either `catch` or `filter` associated with them. Catch clauses are not array types and filter clauses are array types. This is same as the criteria used by LLVM (4f82af81a0/llvm/include/llvm/IR/Instructions.h (L2866))

Examples:
LLVM IR
```
define i32 @caller(i32 %a) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
    invoke i32 @foo(i32 2) to label %success unwind label %fail

  success:
    ret i32 2

  fail:
    landingpad {i8*, i32} catch i8** @_ZTIi catch i8** null catch i8* bitcast (i8** @_ZTIi to i8*) filter [1 x i8] [ i8 1 ]
    ret i32 3
}
```
MLIR LLVM Dialect
```
llvm.func @caller(%arg0: !llvm.i32) -> !llvm.i32 {
  %0 = llvm.mlir.constant(3 : i32) : !llvm.i32
  %1 = llvm.mlir.constant("\01") : !llvm<"[1 x i8]">
  %2 = llvm.mlir.addressof @_ZTIi : !llvm<"i8**">
  %3 = llvm.bitcast %2 : !llvm<"i8**"> to !llvm<"i8*">
  %4 = llvm.mlir.null : !llvm<"i8**">
  %5 = llvm.mlir.addressof @_ZTIi : !llvm<"i8**">
  %6 = llvm.mlir.constant(2 : i32) : !llvm.i32
  %7 = llvm.invoke @foo(%6) to ^bb1 unwind ^bb2 : (!llvm.i32) -> !llvm.i32
^bb1:	// pred: ^bb0
  llvm.return %6 : !llvm.i32
^bb2:	// pred: ^bb0
  %8 = llvm.landingpad (catch %5 : !llvm<"i8**">) (catch %4 : !llvm<"i8**">) (catch %3 : !llvm<"i8*">) (filter %1 : !llvm<"[1 x i8]">) : !llvm<"{ i8*, i32 }">
  llvm.return %0 : !llvm.i32
}
```

Signed-off-by: Shraiysh Vaishay <cs17btech11050@iith.ac.in>

Differential Revision: https://reviews.llvm.org/D72006
2020-01-30 12:55:28 +01:00
Alex Zinenko
84c3f05c8e [mlir] Harden error propagation in LLVM import
Summary:
LLVM importer to MLIR was implemented mostly as a prototype. As such, it did
not deal handle errors in a consistent way, reporting them out stderr in some
cases and continuing the execution in the error state until eventually
crashing. This is not desirable for a user-facing tool. Make sure errors are
returned from functions, consistently checked at call sites and propagated
further. Functions returning nullable IR values return nullptr to denote the
error state. Other functions return LogicalResult. LLVM importer in
mlir-translate should no longer crash on unsupported inputs.

The errors are reported without association with the source file (and therefore
cannot be checked using -verify-diagnostics). Attaching them to the actual
input file is left for future work.

Differential Revision: https://reviews.llvm.org/D72839
2020-01-27 16:15:11 +01:00
Alex Zinenko
07328944ef [mlir] LLVM import: handle constant data and array/vector aggregates
Summary:
Implement the handling of llvm::ConstantDataSequential and
llvm::ConstantAggregate for (nested) array and vector types when imporitng LLVM
IR to MLIR. In all cases, the result is a DenseElementsAttr that can be used in
either a `llvm.mlir.global` or a `llvm.mlir.constant`. Nested aggregates are
unpacked recursively until an element or a constant data is found. Nested
arrays with innermost scalar type are represented as DenseElementsAttr of
tensor type. Nested arrays with innermost vector type are represented as
DenseElementsAttr with (multidimensional) vector type.

Constant aggregates of struct type are not yet supported as the LLVM dialect
does not have a well-defined way of modeling struct-type constants.

Differential Revision: https://reviews.llvm.org/D72834
2020-01-27 16:15:11 +01: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
Alex Zinenko
dc553ce646 [mlir] LLVM import: handle function-typed constants
The current implementation of the LLVM-to-MLIR translation could not handle
functions used as constant values in instructions. The handling is added
trivially as `llvm.mlir.constant` can define constants of function type using
SymbolRef attributes, which works even for functions that have not been
declared yet.
2020-01-15 15:01:49 +01: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
Alex Zinenko
cda94d3e8a [mlir] Floating constants for import-llvm
Summary:
`mlir-translate -import-llvm test.ll`  was going into segmentation fault if `test.ll` had `float` or `double` constants.
For example,
```
%3 = fadd double 3.030000e+01, %0
```
Now, it is handled in `Importer::getConstantAsAttr` (similar behaviour as normal integers)
Added tests for FP arithmetic

Reviewers: ftynse, mehdi_amini

Reviewed By: ftynse, mehdi_amini

Subscribers: shauheen, mehdi_amini, rriddle, jpienaar, burmako, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D71912
2019-12-27 11:48:24 +01: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
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
Alex Zinenko
d5e627f84b Introduce Linkage attribute to the LLVM dialect
LLVM IR supports linkage on global objects such as global variables and
functions. Introduce the Linkage attribute into the LLVM dialect, backed by an
integer storage. Use this attribute on LLVM::GlobalOp and make it mandatory.
Implement parsing/printing of the attribute and conversion to LLVM IR.

See tensorflow/mlir#277.

PiperOrigin-RevId: 283309328
2019-12-02 03:28:10 -08:00
Alex Zinenko
09e8e7107a mlir-translate: support -verify-diagnostics
MLIR translation tools can emit diagnostics and we want to be able to check if
it is indeed the case in tests. Reuse the source manager error handlers
provided for mlir-opt to support the verification in mlir-translate. This
requires us to change the signature of the functions that are registered to
translate sources to MLIR: it now takes a source manager instead of a memory
buffer.

PiperOrigin-RevId: 279132972
2019-11-07 11:42:46 -08:00
James Molloy
250a11ae0f [llvm] Allow GlobalOp to take a region for complex initializers
This allows GlobalOp to either take a value attribute (for simple constants) or a region that can
contain IR instructions (that must be constant-foldable) to create a ConstantExpr initializer.

Example:
  // A complex initializer is constructed with an initializer region.
  llvm.mlir.global constant @int_gep() : !llvm<"i32*"> {
    %0 = llvm.mlir.addressof @g2 : !llvm<"i32*">
    %1 = llvm.mlir.constant(2 : i32) : !llvm.i32
    %2 = llvm.getelementptr %0[%1] : (!llvm<"i32*">, !llvm.i32) -> !llvm<"i32*">
    llvm.return %2 : !llvm<"i32*">
  }
PiperOrigin-RevId: 278717836
2019-11-05 15:11:01 -08:00
James Molloy
6b534ecbcb [llvm] Add initial import of LLVM modules to mlir-translate
This adds an importer from LLVM IR or bitcode to the LLVM dialect. The importer is registered with mlir-translate.

Known issues exposed by this patch but not yet fixed:
  * Globals' initializers are attributes, which makes it impossible to represent a ConstantExpr. This will be fixed in a followup.
  * icmp returns i32 rather than i1.
  * select and a couple of other instructions aren't implemented.
  * llvm.cond_br takes its successors in a weird order.

The testing here is known to be non-exhaustive.

I'd appreciate feedback on where this functionality should live. It looks like the translator *from MLIR to LLVM* lives in Target/, but the SPIR-V deserializer lives in Dialect/ which is why I've put this here too.

PiperOrigin-RevId: 278711683
2019-11-05 14:41:38 -08:00