Commit Graph

88 Commits

Author SHA1 Message Date
River Riddle 3a643de92b NFC: Pass OpAsmPrinter by reference instead of by pointer.
MLIR follows the LLVM style of pass-by-reference.

PiperOrigin-RevId: 270401378
2019-09-20 20:43:35 -07:00
River Riddle 729727ebc7 NFC: Pass OperationState by reference instead of by pointer.
MLIR follows the LLVM convention of passing by reference instead of by pointer.

PiperOrigin-RevId: 270396945
2019-09-20 19:47:32 -07:00
River Riddle 2797517ecf NFC: Pass OpAsmParser by reference instead of by pointer.
MLIR follows the LLVM style of pass-by-reference.

PiperOrigin-RevId: 270315612
2019-09-20 11:37:21 -07:00
Lei Zhang a84bc68acc [spirv] Add support for spv.loop (de)serialization
This CL adds support for serializing and deserializing spv.loop ops.
This adds support for spv.Branch and spv.BranchConditional op
(de)serialization, too, because they are needed for spv.loop.

PiperOrigin-RevId: 268536962
2019-09-11 14:02:59 -07:00
Alex Zinenko 44d8637af1 FunctionSupport: wrap around bool to have a more semantic callback type
This changes the type of the function type-building callback from
(ArrayRef<Type>, ArrayRef<Type>, bool, string &) to (ArrayRef<Type>,
ArrayRef<Type>, VariadicFlag, String &) to make the intended use clear from the
callback signature alone.

Also rearrange type definitions in Parser.cpp to make them more sorted
alphabetically.

PiperOrigin-RevId: 262405851
2019-08-08 12:11:54 -07:00
Alex Zinenko 0126dcf1f0 Introduce support for variadic function signatures for the LLVM dialect
LLVM function type has first-class support for variadic functions.  In the
current lowering pipeline, it is emulated using an attribute on functions of
standard function type.  In LLVMFuncOp that has LLVM function type, this can be
modeled directly.  Introduce parsing support for variadic arguments to the
function and use it to support variadic function declarations in LLVMFuncOp.
Function definitions are currently not supported as that would require modeling
va_start/va_end LLVM intrinsics in the dialect and we don't yet have a
consistent story for LLVM intrinsics.

PiperOrigin-RevId: 262372651
2019-08-08 09:42:16 -07:00
River Riddle f56494f537 NFC: Update FuncOp::addEntryBlock to return the newly inserted block.
The entry block is often used recently after insertion. This removes the need to perform an additional lookup in such cases.

PiperOrigin-RevId: 262265671
2019-08-07 19:24:01 -07:00
Alex Zinenko 6059122601 Introduce custom syntax for llvm.func
Similar to all LLVM dialect operations, llvm.func needs to have the custom
syntax.  Use the generic FunctionLike printer and parser to implement it.

PiperOrigin-RevId: 261641755
2019-08-05 01:57:54 -07:00
Alex Zinenko e63f628473 Genericize function-like printer and parser. NFC
Function-like operations are likely to have similar custom syntax, in
particular they all need to print function signature with argument attributes.

Transform function printer and parser so that they can be applied to any
operation with the FunctionLike trait.  Move them to the trait itself.  To
avoid large member functions in the class template, define a concrete base
class for the trait and implement common functionality in it.  This allows
printer and parser to be implemented in a source file without templating.

PiperOrigin-RevId: 260020893
2019-07-25 14:27:10 -07:00
Alex Zinenko 8543f8aaba Introduce LLVMFuncOp
Originally, MLIR only supported functions of the built-in FunctionType.  On the
conversion path to LLVM IR, we were creating MLIR functions that contained LLVM
dialect operations and used LLVM IR types for everything expect top-level
functions (e.g., a second-order function would have a FunctionType that consume
or produces a wrapped LLVM function pointer type).  With MLIR functions
becoming operations, it is now possible to introduce non-built-in function
operations.  This will let us use conversion patterns for function conversion,
simplify the MLIR-to-LLVM translation by removing the knowledge of the MLIR
built-in function types, and provide stronger correctness verifications (e.g.
LLVM functions only accept LLVM types).

Furthermore, we can currently construct a situation where the same function is
used with two different types: () -> () when its specified and called directly,
and !llvm<"void ()"> when it's passed somewhere on called indirectly.  Having a
special function-op that is always of !llvm<"void ()"> type makes the function
model and the llvm dialect type system more consistent.

Introduce LLVMFuncOp to represent a function in the LLVM dialect.  Unlike
standard FuncOp, this function has an LLVMType wrapping an LLVM IR function
type.  Generalize the common behavior of function-defining operations
(functions live in a symbol table of a module, contain a single region, are
iterable as a list of blocks, and support argument attributes).

This only defines the operation.  Custom syntax, conversion and translation
rules will be added in follow-ups.

The operation name mentions LLVM explicitly to avoid confusion with standard
FuncOp, especially in multiple files that use both `mlir` and `mlir::LLVM`
namespaces.

PiperOrigin-RevId: 259550940
2019-07-23 09:26:39 -07:00
River Riddle 136ccd4948 Update the dialect attribute verifiers related to functions.
Remove the Function specific attribute verifier in favor of the general operation verifier. This also generalizes the function argument verifier to allow use for an argument attached to any region of any operation.

PiperOrigin-RevId: 257689962
2019-07-12 08:43:55 -07:00
River Riddle 9dbef0bf96 Rename FunctionAttr to SymbolRefAttr.
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
2019-07-12 08:43:42 -07:00
Alex Zinenko 4dfe6d457b FuncOp::eraseBody: drop all references before erasing blocks
Operations in a block can use a value defined in a dominating block.  When a
block, and therefore all its operations, is deleted, the operations are not
allowed to have any remaining uses.  Drop all uses of values in all blocks
before deleting them in FuncOp::eraseBody to avoid deleting an operation before
deleting the users of its results.

PiperOrigin-RevId: 257628002
2019-07-12 08:43:35 -07:00
River Riddle 1b247a1247 Drop the trailing newline from the FuncOp syntax.
The ModulePrinter prints the newline now for children of the top-level module. This also fixes the location printing for functions as the location used to be printed on a different line.

PiperOrigin-RevId: 257447633
2019-07-12 08:42:35 -07:00
River Riddle b3e28fca53 NFC: Remove Function::getModule.
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
2019-07-12 08:42:21 -07:00
River Riddle 8c44367891 NFC: Rename Function to FuncOp.
PiperOrigin-RevId: 257293379
2019-07-10 10:10:53 -07:00
River Riddle ee8e8b5539 Generalize the symbol table functionality of ModuleOp into a trait 'OpTrait::SymbolTable'.
Operations must only contain a single region.  Once attached, all operations that contain a 'mlir::SymbolTable::getSymbolAttrName()' StringAttr attribute within the child region will be verified to ensure that the names are uniqued. Operations using this trait also gain access to the 'SymbolTable' class, which can be used to manage the symbol table of the operation. This class also provides constant-time lookup of symbols by name, and will automatically rename symbols on insertion.

PiperOrigin-RevId: 257123573
2019-07-08 22:31:56 -07:00
River Riddle e7d594bb1c Replace the implementation of Function and Module with FuncOp and ModuleOp.
This is an important step in allowing for the top-level of the IR to be extensible. FuncOp and ModuleOp contain all of the necessary functionality, while using the existing operation infrastructure. As an interim step, many of the usages of Function and Module, including the name, will remain the same. In the future, many of these will be relaxed to allow for many different types of top-level operations to co-exist.

PiperOrigin-RevId: 256427100
2019-07-03 14:37:18 -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
River Riddle 25f29e1b15 NFC: Update the Operation 'walk' methods to use llvm::function_ref instead of std::function.
PiperOrigin-RevId: 256099638
2019-07-02 10:28:12 -07:00
River Riddle 54cd6a7e97 NFC: Refactor Function to be value typed.
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
2019-07-01 11:39:00 -07:00
River Riddle 8c47e2ed5c Extract the automatic function renaming and symbol table out of Module.
This functionality is now moved to a new class, ModuleManager. This class allows for inserting functions into a module, and will auto-rename them on insert to ensure a unique name. This now means that users adding new functions to a module must ensure that the function name is unique, as the Module will no longer do it automatically. This also means that Module::getNamedFunction now operates in O(N) instead of the O(c) time it did before. This simplifies the move of Modules to Operations as the ModuleOp will not be able to have this functionality.

PiperOrigin-RevId: 255846088
2019-07-01 09:55:13 -07:00
River Riddle 929466b5c9 Cleanup the 'clone' methods and remove the need to explicitly pass in the context.
This also adds a new 'Region::cloneInto' method that accepts an insertion position.

PiperOrigin-RevId: 255504640
2019-06-27 16:43:18 -07:00
River Riddle a4c3a6455c Move the emitError/Warning/Remark utility methods out of MLIRContext and 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
2019-06-25 21:32:23 -07:00
River Riddle 927b7074a8 Extract the function symbol table functionality, i.e. mapping and name uniquing, out of Module and into a new class SymbolTable. As modules become operations it is necessary to extract out this functionality that cannot be represented with a generic operation.
PiperOrigin-RevId: 254041734
2019-06-19 23:08:22 -07:00
River Riddle 420c1f383a Add a utility to OpAsmPrinter for printing an optional trailing arrow type list. This is useful for any operation that wants to print a set of types in the same format as a FunctionType/Operation signature.
PiperOrigin-RevId: 252647152
2019-06-19 22:58:16 -07:00
River Riddle 82f9be83a3 Add a verify method to FuncOp and check that the type signature matches the signature of the entry block.
PiperOrigin-RevId: 251759848
2019-06-09 16:20:35 -07:00
River Riddle 08d407f243 Add a few utility overloads for OpAsmParser methods:
* Add a getCurrentLocation that returns the location directly.
* Add parseOperandList/parseTrailingOperandList overloads without the required operand count.

PiperOrigin-RevId: 251585488
2019-06-09 16:18:21 -07:00
River Riddle f1b848e470 NFC: Rename FuncBuilder to OpBuilder and refactor to take a top level region instead of a function.
PiperOrigin-RevId: 251563898
2019-06-09 16:17:59 -07:00
River Riddle 70db033190 Add support to FuncOp for managing argument attributes. The syntax for argument attributes is the same as Function:
func @foo(i1 {dialect.attr: 10 : i64})

  func @foo(%arg0: i1 {dialect.attr: 10 : i64}) {
    return
  }

PiperOrigin-RevId: 251473338
2019-06-09 16:16:36 -07:00
River Riddle 62cbdd51fa Start defining a new operation 'FuncOp' that replicates all of the functionality of 'Function', but with an operation. The pretty syntax for the operation is exactly the same as that of Function. This operation is currently builtin, but should hopefully be moved to a different dialect when it has been completely decoupled from IR/. This is the first patch in a large series that refactors Functions to be represented as operations.
PiperOrigin-RevId: 251281612
2019-06-03 19:26:46 -07:00
River Riddle c33862b0ed Refactor FunctionAttr to hold the internal function reference by name instead of pointer. The one downside to this is that the function reference held by a FunctionAttr needs to be explicitly looked up from the parent module. This provides several benefits though:
* There is no longer a need to explicitly remap function attrs.
      - This removes a potentially expensive call from the destructor of Function.
      - This will enable some interprocedural transformations to now run intraprocedurally.
      - This wasn't scalable and forces dialect defined attributes to override
        a virtual function.
    * Replacing a function is now a trivial operation.
    * This is a necessary first step to representing functions as operations.

--

PiperOrigin-RevId: 249510802
2019-06-01 19:56:54 -07:00
River Riddle a23b728034 Allow a function to take the name of another existing function.
--

PiperOrigin-RevId: 248968285
2019-05-20 13:48:02 -07:00
River Riddle 6a6cb40f23 Refactor the includes of Function.h now that the dependency on Operation has been removed. The dependency was on the op casting methods, which have now moved out of Operation, used by the walker.
--

PiperOrigin-RevId: 247944666
2019-05-20 13:38:32 -07:00
River Riddle 983e0eea95 Simplify several usages of attributes now that they always have a type and, transitively, access to the context.
This also fixes a bug where FunctionAttrs were not being remapped for function and function argument attributes.

--

PiperOrigin-RevId: 246876924
2019-05-10 19:22:41 -07:00
River Riddle 777e7b4f4f Make the Twine parameter of the current diagnostic emit functions optional. This allows for the ability to exclusively use the new diagnostic interface without breaking all of the existing usages. Several diagnostics emitted in lib/IR have been updated to make use of this functionality.
--

PiperOrigin-RevId: 246546044
2019-05-06 08:27:13 -07:00
River Riddle ffa0246bc2 Add an MLIRContext::emitWarning utility method.
--

PiperOrigin-RevId: 246546015
2019-05-06 08:27:03 -07:00
River Riddle ff6e7cf558 Introduce a new API for emitting diagnostics with Diagnostic and InFlightDiagnostic.
The Diagnostic class contains all of the information necessary to report a diagnostic to the DiagnosticEngine. It should generally not be constructed directly, and instead used transitively via InFlightDiagnostic. A diagnostic is currently comprised of several different elements:
    * A severity level.
    * A source Location.
    * A list of DiagnosticArguments that help compose and comprise the output message.
      * A DiagnosticArgument represents any value that may be part of the diagnostic, e.g. string, integer, Type, Attribute, etc.
      * Arguments can be added to the diagnostic via the stream(<<) operator.
    * (In a future cl) A list of attached notes.
      * These are in the form of other diagnostics that provide supplemental information to the main diagnostic, but do not have context on their own.

    The InFlightDiagnostic class represents an RAII wrapper around a Diagnostic that is set to be reported with the diagnostic engine. This allows for the user to modify a diagnostic that is inflight. The internally wrapped diagnostic can be reported directly or automatically upon destruction.

    These classes allow for more natural composition of diagnostics by removing the restriction that the message of a diagnostic is comprised of a single Twine. They should also allow for nice incremental improvements to the diagnostics experience in the future, e.g. formatv style diagnostics.

    Simple Example:

    emitError(loc, "integer bitwidth is limited to " + Twine(IntegerType::kMaxWidth) + " bits");
    emitError(loc) << "integer bitwidth is limited to " << IntegerType::kMaxWidth << " bits";

--

PiperOrigin-RevId: 246526439
2019-05-06 08:26:34 -07:00
River Riddle b14c4b4ca8 Add support for basic remark diagnostics. This is the minimal functionality needed to separate notes from remarks. It also provides a starting point to start building out better remark infrastructure.
--

PiperOrigin-RevId: 246175216
2019-05-06 08:24:02 -07:00
River Riddle eaf7f6b671 Start sketching out a new diagnostics infrastructure. Create a new class 'DiagnosticEngine' and move the diagnostic handler support and final diagnostic emission from the MLIRContext to it.
--

PiperOrigin-RevId: 246163897
2019-05-06 08:23:53 -07:00
River Riddle 6fa3181329 Remove the non-postorder walk functions from Function/Block/Instruction and rename walkPostOrder to walk.
--

PiperOrigin-RevId: 241965239
2019-04-05 07:41:23 -07:00
River Riddle 7fa2864954 Update the dialect attribute verification hooks to return LogicalResult instead of bool. This updates Function::emitError to return LogicalResult as well.
--

PiperOrigin-RevId: 241598892
2019-04-02 15:15:56 -07:00
Mehdi Amini 3518122e86 Simplify API uses of `getContext()` (NFC)
The Pass base class is providing a convenience getContext() accessor.

PiperOrigin-RevId: 240634961
2019-03-29 17:47:11 -07:00
River Riddle f9d91531df Replace usages of Instruction with Operation in the /IR directory.
This is step 2/N to renaming Instruction to Operation.

PiperOrigin-RevId: 240459216
2019-03-29 17:43:37 -07:00
Alex Zinenko a7215a9032 Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent.  It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions.  It may be
necessary to work with the regions before the operation is created.  In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions.  Such regions are meant to own a list of
blocks and transfer them to other regions on demand.

Each instruction stores a fixed number of regions as trailing objects and has
ownership of them.  This decreases the size of the Instruction object for the
common case of instructions without regions.  Keep this behavior intact.  To
allow some flexibility in construction, make OperationState store an owning
vector of regions.  When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying.  Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.

PiperOrigin-RevId: 240368183
2019-03-29 17:40:59 -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
Alex Zinenko 276fae1b0d Rename BlockList into Region
NFC.  This is step 1/n to specifying regions as parts of any operation.

PiperOrigin-RevId: 238472370
2019-03-29 17:18:04 -07:00
Dimitrios Vytiniotis a60ba7d908 Supporting conversion of argument attributes along their types.
This fixes a bug: previously, during conversion function argument
attributes were neither beings passed through nor converted. This fix
extends DialectConversion to allow for simultaneous conversion of the
function type and the argument attributes.

This was important when lowering MLIR to LLVM where attribute
information (e.g. noalias) needs to be preserved in MLIR(LLVMDialect).

Longer run it seems reasonable that we want to convert both the
function attribute and its type and the argument attributes, but that
requires a small refactoring in Function.h to aggregate these three
fields in an inner struct, which will require some discussion.

PiperOrigin-RevId: 236709409
2019-03-29 16:55:51 -07:00
River Riddle db1757f858 Add support for named function argument attributes. The attribute dictionary is printed after the argument type:
func @arg_attrs(i32 {arg_attr: 10})

func @arg_attrs(%arg0: i32 {arg_attr: 10})

PiperOrigin-RevId: 236136830
2019-03-29 16:50:15 -07:00
River Riddle 302fb03961 Add a new class NamedAttributeList to deduplicate named attribute handling between Function and Instruction.
PiperOrigin-RevId: 235830304
2019-03-29 16:45:40 -07:00