66 Commits

Author SHA1 Message Date
Tres Popp
c2c83e97c3 Revert "Revert "Reorder MLIRContext location in BuiltinAttributes.h""
This reverts commit 511dd4f4383b1c2873beac4dbea2df302f1f9d0c along with
a couple fixes.

Original message:
Now the context is the first, rather than the last input.

This better matches the rest of the infrastructure and makes
it easier to move these types to being declaratively specified.

Phabricator: https://reviews.llvm.org/D96111
2021-02-08 10:39:58 +01:00
Tres Popp
511dd4f438 Revert "Reorder MLIRContext location in BuiltinAttributes.h"
This reverts commit 7827753f9810e846fb702f3e8dcff0bfb37344e1.
2021-02-08 09:32:42 +01:00
Tres Popp
7827753f98 Reorder MLIRContext location in BuiltinAttributes.h
Now the context is the first, rather than the last input.

This better matches the rest of the infrastructure and makes
it easier to move these types to being declaratively specified.

Differential Revision: https://reviews.llvm.org/D96111
2021-02-08 09:28:09 +01:00
River Riddle
e21adfa32d [mlir] Mark LogicalResult as LLVM_NODISCARD
This makes ignoring a result explicit by the user, and helps to prevent accidental errors with dropped results. Marking LogicalResult as no discard was always the intention from the beginning, but got lost along the way.

Differential Revision: https://reviews.llvm.org/D95841
2021-02-04 15:10:10 -08:00
Alex Zinenko
bd30a796fc [mlir] use built-in vector types instead of LLVM dialect types when possible
Continue the convergence between LLVM dialect and built-in types by using the
built-in vector type whenever possible, that is for fixed vectors of built-in
integers and built-in floats. LLVM dialect vector type is still in use for
pointers, less frequent floating point types that do not have a built-in
equivalent, and scalable vectors. However, the top-level `LLVMVectorType` class
has been removed in favor of free functions capable of inspecting both built-in
and LLVM dialect vector types: `LLVM::getVectorElementType`,
`LLVM::getNumVectorElements` and `LLVM::getFixedVectorType`. Additional work is
necessary to design an implemented the extensions to built-in types so as to
remove the `LLVMFixedVectorType` entirely.

Note that the default output format for the built-in vectors does not have
whitespace around the `x` separator, e.g., `vector<4xf32>` as opposed to the
LLVM dialect vector type format that does, e.g., `!llvm.vec<4 x fp128>`. This
required changing the FileCheck patterns in several tests.

Reviewed By: mehdi_amini, silvas

Differential Revision: https://reviews.llvm.org/D94405
2021-01-12 10:04:28 +01:00
Christian Sigg
d59ddba777 [mlir] Fix gpu-to-llvm lowering for gpu.alloc with dynamic sizes.
Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D94402
2021-01-11 15:55:48 +01:00
Alex Zinenko
2230bf99c7 [mlir] replace LLVMIntegerType with built-in integer type
The LLVM dialect type system has been closed until now, i.e. did not support
types from other dialects inside containers. While this has had obvious
benefits of deriving from a common base class, it has led to some simple types
being almost identical with the built-in types, namely integer and floating
point types. This in turn has led to a lot of larger-scale complexity: simple
types must still be converted, numerous operations that correspond to LLVM IR
intrinsics are replicated to produce versions operating on either LLVM dialect
or built-in types leading to quasi-duplicate dialects, lowering to the LLVM
dialect is essentially required to be one-shot because of type conversion, etc.
In this light, it is reasonable to trade off some local complexity in the
internal implementation of LLVM dialect types for removing larger-scale system
complexity. Previous commits to the LLVM dialect type system have adapted the
API to support types from other dialects.

Replace LLVMIntegerType with the built-in IntegerType plus additional checks
that such types are signless (these are isolated in a utility function that
replaced `isa<LLVMType>` and in the parser). Temporarily keep the possibility
to parse `!llvm.i32` as a synonym for `i32`, but add a deprecation notice.

Reviewed By: mehdi_amini, silvas, antiagainst

Differential Revision: https://reviews.llvm.org/D94178
2021-01-07 19:48:31 +01:00
Kazuaki Ishizaki
f88fab5006 [mlir] NFC: fix trivial typos
fix typo under include and lib directories

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D94220
2021-01-08 02:10:12 +09:00
Ivan Butygin
c1d58c2b00 [mlir] Add fastmath flags support to some LLVM dialect ops
Add fastmath enum, attributes to some llvm dialect ops, `FastmathFlagsInterface` op interface, and `translateModuleToLLVMIR` support.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D92485
2021-01-07 14:00:09 +01:00
Alex Zinenko
c69c9e0f0f [mlir] Remove LLVMType, LLVM dialect types now derive Type directly
BEGIN_PUBLIC
[mlir] Remove LLVMType, LLVM dialect types now derive Type directly

This class has become a simple `isa` hook with no proper functionality.
Removing will allow us to eventually make the LLVM dialect type infrastructure
open, i.e., support non-LLVM types inside container types, which itself will
make the type conversion more progressive.

Introduce a call `LLVM::isCompatibleType` to be used instead of
`isa<LLVMType>`. For now, this is strictly equivalent.
END_PUBLIC

Depends On D93681

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D93713
2021-01-05 17:36:54 +01:00
Lei Zhang
930c74f12d [mlir][spirv] NFC: rename SPIR-V conversion files for consistency
This commit renames various SPIR-V related conversion files for
consistency. It drops the "Convert" prefix to various files and
fixes various comment headers.

Reviewed By: hanchung, ThomasRaoux

Differential Revision: https://reviews.llvm.org/D93489
2020-12-23 14:36:46 -05:00
Alex Zinenko
7ed9cfc7b1 [mlir] Remove static constructors from LLVMType
LLVMType contains numerous static constructors that were initially introduced
for API compatibility with LLVM. Most of these merely forward to arguments to
`SpecificType::get` (MLIR defines classes for all types, unlike LLVM IR), while
some introduce subtle semantics differences due to different modeling of MLIR
types (e.g., structs are not auto-renamed in case of conflicts). Furthermore,
these constructors don't match MLIR idioms and actively prevent us from making
the LLVM dialect type system more open. Remove them and use `SpecificType::get`
instead.

Depends On D93680

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D93681
2020-12-23 13:12:47 +01:00
Alex Zinenko
8de43b926f [mlir] Remove instance methods from LLVMType
LLVMType contains multiple instance methods that were introduced initially for
compatibility with LLVM API. These methods boil down to `cast` followed by
type-specific call. Arguably, they are mostly used in an LLVM cast-follows-isa
anti-pattern. This doesn't connect nicely to the rest of the MLIR
infrastructure and actively prevents it from making the LLVM dialect type
system more open, e.g., reusing built-in types when appropriate. Remove such
instance methods and replaces their uses with apporpriate casts and methods on
derived classes. In some cases, the result may look slightly more verbose, but
most cases should actually use a stricter subtype of LLVMType anyway and avoid
the isa/cast.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D93680
2020-12-22 23:34:54 +01:00
River Riddle
1b97cdf885 [mlir][IR][NFC] Move context/location parameters of builtin Type::get methods to the start of the parameter list
This better matches the rest of the infrastructure, is much simpler, and makes it easier to move these types to being declaratively specified.

Differential Revision: https://reviews.llvm.org/D93432
2020-12-17 13:01:36 -08:00
Lei Zhang
0117865412 [mlir][spirv] NFC: Shuffle code around to better follow convention
This commit shuffles SPIR-V code around to better follow MLIR
convention. Specifically,

* Created IR/, Transforms/, Linking/, and Utils/ subdirectories and
  moved suitable code inside.
* Created SPIRVEnums.{h|cpp} for SPIR-V C/C++ enums generated from
  SPIR-V spec. Previously they are cluttered inside SPIRVTypes.{h|cpp}.
* Fixed include guards in various header files (both .h and .td).
* Moved serialization tests under test/Target/SPIRV.
* Renamed TableGen backend -gen-spirv-op-utils into -gen-spirv-attr-utils
  as it is only generating utility functions for attributes.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D93407
2020-12-17 11:03:26 -05:00
Christian Sigg
1ffc1aaa09 [mlir] Use mlir::OpState::operator->() to get to methods of mlir::Operation.
This is a preparation step to remove those methods from OpState.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D93098
2020-12-13 09:58:16 +01:00
Christian Sigg
0bf4a82a5a [mlir] Use mlir::OpState::operator->() to get to methods of mlir::Operation. This is a preparation step to remove the corresponding methods from OpState.
Reviewed By: silvas, rriddle

Differential Revision: https://reviews.llvm.org/D92878
2020-12-09 12:11:32 +01:00
Christian Sigg
dcec2ca5bd Remove typeConverter from ConvertToLLVMPattern and use the existing one in ConversionPattern.
ftynse

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D92564
2020-12-04 14:27:16 +01:00
Christian Sigg
acb69f3b7c [mlir] Change ConvertOpToLLVMPattern::matchAndRewrite argument to concrete operand type.
Reviewed By: herhut, ftynse

Differential Revision: https://reviews.llvm.org/D92111
2020-11-28 13:09:25 +01: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
Christian Sigg
bedaad4495 [mlir] Simplify std.alloc lowering to LLVM.
std.alloc only supports memrefs with identity layout, which means we can simplify the lowering to LLVM and compute strides only from (static and dynamic) sizes.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D91549
2020-11-17 18:55:34 +01:00
ergawy
9793edd5bf [MLIR][SPIRV] Rename spv._address_of to spv.mlir.addressof
This commit does the renaming mentioned in the title in order to bring
`spv` dialect closer to the MLIR naming conventions.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D91609
2020-11-17 12:12:27 -05: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
George Mitenkov
de3ad5bb09 [MLIR][SPIRVToLLVM] Enhanced conversion for execution mode
This patch introduces a new conversion pattern for `spv.ExecutionMode`.
`spv.ExecutionMode` may contain important information about the entry
point, which we want to preserve. For example, `LocalSize` provides
information about the work-group size that can be reused. Hence, the
pattern for entry-point ops changes to the following:
- `spv.EntryPoint` is still simply removed
- Info from `spv.ExecutionMode` is used to create a global struct variable,
  which looks like:

  ```
  struct {
    int32_t executionMode;
    int32_t values[];          // optional values
  };
  ```

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D89989
2020-11-10 18:33:54 +03:00
George Mitenkov
89eed79c1f [MLIR][SPIRVToLLVM] Added module name conversion
Since SPIR-V module has an optional name, this patch
makes a change to pass it to `ModuleOp` during conversion.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D90904
2020-11-07 12:27:44 +03:00
Kazuaki Ishizaki
41b09f4eff [mlir] NFC: fix trivial typos
fix typos in comments and documents

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D90089
2020-10-29 04:05:22 +09:00
River Riddle
3fffffa882 [mlir][Pattern] Add a new FrozenRewritePatternList class
This class represents a rewrite pattern list that has been frozen, and thus immutable. This replaces the uses of OwningRewritePatternList in pattern driver related API, such as dialect conversion. When PDL becomes more prevalent, this API will allow for optimizing a set of patterns once without the need to do this per run of a pass.

Differential Revision: https://reviews.llvm.org/D89104
2020-10-26 18:01:06 -07:00
George Mitenkov
cae4067ec1 [MLIR][mlir-spirv-cpu-runner] A pass to emulate a call to kernel in LLVM
This patch introduces a pass for running
`mlir-spirv-cpu-runner` - LowerHostCodeToLLVMPass.

This pass emulates `gpu.launch_func` call in LLVM dialect and lowers
the host module code to LLVM. It removes the `gpu.module`, creates a
sequence of global variables that are later linked to the varables
in the kernel module, as well as a series of copies to/from
them to emulate the memory transfer to/from the host or to/from the
device sides. It also converts the remaining Standard dialect into
LLVM dialect, emitting C wrappers.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D86112
2020-10-26 08:11:04 -04:00
George Mitenkov
b81bedf714 [MLIR][SPIRVToLLVM] Conversion for composite extract and insert
A pattern to convert `spv.CompositeInsert` and `spv.CompositeExtract`.
In LLVM, there are 2 ops that correspond to each instruction depending
on the container type. If the container type is a vector type, then
the result of conversion is `llvm.insertelement` or `llvm.extractelement`.
If the container type is an aggregate type (i.e. struct, array), the
result of conversion is `llvm.insertvalue` or `llvm.extractvalue`.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D88205
2020-10-06 11:46:25 +03:00
River Riddle
431bb8b318 [mlir][ODS] Use c++ types for integer attributes of fixed width when possible.
Unsigned and Signless attributes use uintN_t and signed attributes use intN_t, where N is the fixed width. The 1-bit variants use bool.

Differential Revision: https://reviews.llvm.org/D86739
2020-09-01 13:43:32 -07:00
George Mitenkov
e850558cdc [MLIR][SPIRVToLLVM] Added a hook for descriptor set / binding encoding
This patch introduces a hook to encode descriptor set
and binding number into `spv.globalVariable`'s symbolic name. This
allows to preserve this information, and at the same time legalize
the global variable for the conversion to LLVM dialect.

This is required for `mlir-spirv-cpu-runner` to convert kernel
arguments into LLVM.

Also, a couple of some nits added:
- removed unused comment
- changed to a capital letter in the comment

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D86515
2020-08-27 08:27:42 +03:00
George Mitenkov
dc693a036d [MLIR][SPIRVToLLVM] Removed std to llvm patterns from the conversion
Removed the Standard to LLVM conversion patterns that were previously
pulled in for testing purposes. This helps to separate the conversion
to LLVM dialect of the MLIR module with both SPIR-V and Standard
dialects in it (particularly helpful for SPIR-V cpu runner). Also,
tests were changed accordingly.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D86285
2020-08-21 00:26:33 +03:00
George Mitenkov
cc98a0fbe4 [MLIR][SPIRVToLLVM] Additional conversions for spirv-runner
This patch adds more op/type conversion support
necessary for `spirv-runner`:
- EntryPoint/ExecutionMode: currently removed since we assume
having only one kernel function in the kernel module.
- StorageBuffer storage class is now supported. We are not
concerned with multithreading so this is fine for now.
- Type conversion enhanced, now regular offsets and strides
for structs and arrays are supported (based on
`VulkanLayoutUtils`).
- Support of `spc.AccessChain` that is modelled with GEP op
in LLVM dialect.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D86109
2020-08-18 19:09:59 +03:00
George Mitenkov
2ad7e1a301 [MLIR][SPIRVToLLVM] Conversion for global and addressof
Inital conversion of `spv._address_of` and `spv.globalVariable`.
In SPIR-V, the global returns a pointer, whereas in LLVM dialect
the global holds an actual value. This difference is handled by
`spv._address_of` and `llvm.mlir.addressof`ops that both return
a pointer. Moreover, only current invocation is in conversion's
scope.

Reviewed By: antiagainst, mravishankar

Differential Revision: https://reviews.llvm.org/D84626
2020-08-12 09:41:14 +03:00
Alex Zinenko
5446ec8507 [mlir] take MLIRContext instead of LLVMDialect in getters of LLVMType's
Historical modeling of the LLVM dialect types had been wrapping LLVM IR types
and therefore needed access to the instance of LLVMContext stored in the
LLVMDialect. The new modeling does not rely on that and only needs the
MLIRContext that is used for uniquing, similarly to other MLIR types. Change
LLVMType::get<Kind>Ty functions to take `MLIRContext *` instead of
`LLVMDialect *` as first argument. This brings the code base closer to
completely removing the dependence on LLVMContext from the LLVMDialect,
together with additional support for thread-safety of its use.

Depends On D85371

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D85372
2020-08-06 11:05:40 +02:00
George Mitenkov
e739648cfa [MLIR][SPIRVToLLVM] Conversion pattern for loop op
This patch introduces a conversion of `spv.loop` to LLVM dialect.
Similarly to `spv.selection`, op's control attributes are not mapped
to LLVM yet and therefore the conversion fails if the loop control is
not `None`. Also, all blocks within the loop should be reachable in
order for conversion to succeed.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D84245
2020-08-05 10:33:54 +03:00
George Mitenkov
1880532036 [MLIR][SPIRVToLLVM] Conversion of GLSL ops to LLVM intrinsics
This patch introduces new intrinsics in LLVM dialect:
-  `llvm.intr.floor`
-  `llvm.intr.maxnum`
-  `llvm.intr.minnum`
-  `llvm.intr.smax`
-  `llvm.intr.smin`
These intrinsics correspond to SPIR-V ops from GLSL
extended instruction set (`spv.GLSL.Floor`, `spv.GLSL.FMax`,
`spv.GLSL.FMin`,  `spv.GLSL.SMax` and `spv.GLSL.SMin`
respectively). Also conversion patterns for them were added.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D84661
2020-07-30 11:22:44 +03:00
George Mitenkov
3aab320557 [MLIR][SPIRVToLLVM] Conversion for inverse sqrt and tanh
This is a second patch on conversion of GLSL ops to LLVM dialect.
It introduces patterns to convert `spv.InverseSqrt` and `spv.Tanh`.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D84633
2020-07-30 10:50:48 +03:00
George Mitenkov
647e9a54c7 [MLIR][SPIRVToLLVM] Conversion patterns for GLSL ops
This is the first patch that adds support for GLSL extended
instruction set ops. These are direct conversions, apart from `spv.Tan`
that is lowered to `sin() / cos()`.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D84627
2020-07-30 10:20:11 +03: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
George Mitenkov
1f4aa30a4f [MLIR][SPIRVToLLVM] Branch weights support for BranchConditional conversion
Conversion of `spv.BranchConditional` now supports branch weights
that are mapped to weights vector in `llvm.cond_br`.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D84657
2020-07-29 10:11:10 +03:00
George Mitenkov
b1e398920f [MLIR][SPIRVToLLVM] Support of volatile/nontemporal memory access in load/store
This patch adds support of Volatile and Nontemporal
memory accesses to `spv.Load` and `spv.Store`. These attributes are
modelled with a `volatile` and `nontemporal` flags.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D84739
2020-07-29 08:45:40 +03:00
George Mitenkov
8be0371eb7 [MLIR][SPIRVToLLVM] Conversion of load and store SPIR-V ops
This patch introduces conversion pattern for `spv.Store` and `spv.Load`.
Only op with `Function` Storage Class is supported at the moment
because `spv.GlobalVariable` has not been introduced yet. If the op
has memory access attribute, then there are the following cases.
If the access is `Aligned`, add alignment to the op builder. Otherwise
the conversion fails as other cases are not supported yet because they
require additional attributes for `llvm.store`/`llvm.load` ops: e.g.
`volatile` and `nontemporal`.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D84236
2020-07-24 16:31:45 +03:00
George Mitenkov
5c98631391 [MLIR][SPIRVToLLVM] Conversion of SPIR-V variable op
The patch introduces the conversion pattern for function-level
`spv.Variable`. It is modelled as `llvm.alloca` op. If initialized, then
additional store instruction is used. Note that there is no initialization
for arrays and structs since constants of these types are not supported in
LLVM dialect yet. Also, at the moment initialisation is only possible via
`spv.constant` (since `spv.GlobalVariable` conversion is not implemented
yet).

The input code has some scoping is not taken into account and will be
addressed in a different patch.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D84224
2020-07-24 15:49:55 +03:00
George Mitenkov
61dd481f11 [MLIR][LLVMDialect] SelectionOp conversion pattern
This patch introduces conversion pattern for `spv.selection` op.
The conversion can only be applied to selection with all blocks being
reachable. Moreover, selection with control attributes "Flatten" and
"DontFlatten" is not supported.
Since the `PatternRewriter` hook for block merging has not been implemented
for `ConversionPatternRewriter`, merge and continue blocks are kept
separately.

Reviewed By: antiagainst, ftynse

Differential Revision: https://reviews.llvm.org/D83860
2020-07-21 17:11:46 +03:00
George Mitenkov
05d3160c9c [MLIR][SPIRVToLLVM] Conversion of SPIR-V branch ops
This patch introduces conversion for `spv.Branch` and `spv.BranchConditional`
ops. Branch weigths for `spv.BranchConditional` are not supported at the
moment, and conversion in this case fails.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D83784
2020-07-21 10:52:20 +03:00
George Mitenkov
d431951343 [MLIR][SPIRVToLLVM] SPIRV function fix and nits
This patch addresses the comments from https://reviews.llvm.org/D83030 and
https://reviews.llvm.org/D82639. `this->` is removed when not inside the
template. Also, type conversion for `spv.func` takes `convertRegionTypes()`
in order to apply type conversion on all blocks within the function.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D83786
2020-07-15 10:29:46 +03:00
George Mitenkov
eb6b7c5d4f [MLIR][SPIRVToLLVM] Conversion of SPIR-V struct type without offset
This patch introduces type conversion for SPIR-V structs. Since
handling offset case requires thorough testing, it was left out
for now. Hence, only structs with no offset are currently
supported. Also, structs containing member decorations cannot
be translated.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D83403
2020-07-10 10:15:45 +03:00
George Mitenkov
28cd3cbc12 [MLIR][SPIRVToLLVM] Conversion of SPIR-V array, runtime array, and pointer types
This patch adds type conversion for 4 SPIR-V types: array, runtime array, pointer
and struct. This conversion is integrated using a separate function
`populateSPIRVToLLVMTypeConversion()` that adds new type conversions. At the moment,
this is a basic skeleton that allows to perfom conversion from SPIR-V array,
runtime array and pointer types to LLVM typesystem. There is no support of array
strides or storage classes. These will be supported on the case by case basis.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D83399
2020-07-09 18:11:45 +03:00
Benjamin Kramer
b44470547e Make helpers static. NFC. 2020-07-09 13:48:56 +02:00