Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

include "mlir/Dialect/LLVMIR/LLVMDialect.td"
include "mlir/Dialect/LLVMIR/LLVMInterfaces.td"
include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td"
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/CommonAttrConstraints.td"
include "mlir/Interfaces/DataLayoutInterfaces.td"
Expand All @@ -23,6 +24,41 @@ class LLVM_Attr<string name, string attrMnemonic,
let mnemonic = attrMnemonic;
}

//===----------------------------------------------------------------------===//
// AddressSpaceAttr
//===----------------------------------------------------------------------===//

def LLVM_AddressSpaceAttr :
LLVM_Attr<"AddressSpace", "address_space", [
DeclareAttrInterfaceMethods<MemorySpaceAttrInterface>
]> {
let summary = "LLVM address space";
let description = [{
The `address_space` attribute represents an LLVM address space. It takes an
unsigned integer parameter that specifies the address space number.

Different address spaces in LLVM can have different properties:
- Address space 0 is the default/generic address space
- Other address spaces may have specific semantics (e.g., shared memory,
constant memory, etc.) depending on the target architecture

Example:

```mlir
// Address space 0 (default)
#llvm.address_space<0>

// Address space 1 (e.g., global memory on some targets)
#llvm.address_space<1>

// Address space 3 (e.g., shared memory on some GPU targets)
#llvm.address_space<3>
```
}];
let parameters = (ins "unsigned":$addressSpace);
let assemblyFormat = "`<` $addressSpace `>`";
}

//===----------------------------------------------------------------------===//
// CConvAttr
//===----------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define MLIR_DIALECT_LLVMIR_LLVMATTRS_H_

#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
#include "mlir/IR/OpImplementation.h"
#include "mlir/Interfaces/DataLayoutInterfaces.h"
#include <optional>
Expand Down
10 changes: 10 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ namespace mlir {

class AsmParser;
class AsmPrinter;
class DataLayout;

namespace LLVM {
class LLVMDialect;
Expand Down Expand Up @@ -111,6 +112,15 @@ bool isCompatibleFloatingPointType(Type type);
/// dialect pointers and LLVM dialect scalable vector types.
bool isCompatibleVectorType(Type type);

/// Returns `true` if the given type is a loadable type compatible with the LLVM
/// dialect.
bool isLoadableType(Type type);

/// Returns true if the given type is supported by atomic operations. All
/// integer, float, and pointer types with a power-of-two bitsize and a minimal
/// size of 8 bits are supported.
bool isTypeCompatibleWithAtomicOp(Type type, const DataLayout &dataLayout);

/// Returns the element count of any LLVM-compatible vector type.
llvm::ElementCount getVectorNumElements(Type type);

Expand Down
2 changes: 0 additions & 2 deletions mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ mlir_tablegen(PtrOpsAttrs.cpp.inc -gen-attrdef-defs -attrdefs-dialect=ptr)
add_mlir_dialect_tablegen_target(MLIRPtrOpsAttributesIncGen)

set(LLVM_TARGET_DEFINITIONS MemorySpaceInterfaces.td)
mlir_tablegen(MemorySpaceInterfaces.h.inc -gen-op-interface-decls)
mlir_tablegen(MemorySpaceInterfaces.cpp.inc -gen-op-interface-defs)
mlir_tablegen(MemorySpaceAttrInterfaces.h.inc -gen-attr-interface-decls)
mlir_tablegen(MemorySpaceAttrInterfaces.cpp.inc -gen-attr-interface-defs)
add_mlir_dialect_tablegen_target(MLIRPtrMemorySpaceInterfacesIncGen)
Expand Down
6 changes: 4 additions & 2 deletions mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/OpDefinition.h"

#include <functional>
#include <optional>

namespace mlir {
class Operation;
class DataLayout;
namespace ptr {
enum class AtomicBinOp : uint32_t;
enum class AtomicOrdering : uint32_t;
Expand All @@ -27,6 +31,4 @@ enum class AtomicOrdering : uint32_t;

#include "mlir/Dialect/Ptr/IR/MemorySpaceAttrInterfaces.h.inc"

#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h.inc"

#endif // MLIR_DIALECT_PTR_IR_MEMORYSPACEINTERFACES_H
4 changes: 4 additions & 0 deletions mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def MemorySpaceAttrInterface : AttrInterface<"MemorySpaceAttrInterface"> {
/*args=*/ (ins "::mlir::Type":$type,
"::mlir::ptr::AtomicOrdering":$ordering,
"std::optional<int64_t>":$alignment,
"const ::mlir::DataLayout *":$dataLayout,
"::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError)
>,
InterfaceMethod<
Expand All @@ -58,6 +59,7 @@ def MemorySpaceAttrInterface : AttrInterface<"MemorySpaceAttrInterface"> {
/*args=*/ (ins "::mlir::Type":$type,
"::mlir::ptr::AtomicOrdering":$ordering,
"std::optional<int64_t>":$alignment,
"const ::mlir::DataLayout *":$dataLayout,
"::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError)
>,
InterfaceMethod<
Expand All @@ -74,6 +76,7 @@ def MemorySpaceAttrInterface : AttrInterface<"MemorySpaceAttrInterface"> {
"::mlir::Type":$type,
"::mlir::ptr::AtomicOrdering":$ordering,
"std::optional<int64_t>":$alignment,
"const ::mlir::DataLayout *":$dataLayout,
"::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError)
>,
InterfaceMethod<
Expand All @@ -91,6 +94,7 @@ def MemorySpaceAttrInterface : AttrInterface<"MemorySpaceAttrInterface"> {
"::mlir::ptr::AtomicOrdering":$successOrdering,
"::mlir::ptr::AtomicOrdering":$failureOrdering,
"std::optional<int64_t>":$alignment,
"const ::mlir::DataLayout *":$dataLayout,
"::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError)
>,
InterfaceMethod<
Expand Down
3 changes: 1 addition & 2 deletions mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@
#include "llvm/Support/TypeSize.h"

#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
#include "mlir/Dialect/Ptr/IR/PtrEnums.h"

#define GET_ATTRDEF_CLASSES
#include "mlir/Dialect/Ptr/IR/PtrOpsAttrs.h.inc"

#include "mlir/Dialect/Ptr/IR/PtrOpsEnums.h.inc"

#endif // MLIR_DIALECT_PTR_IR_PTRATTRS_H
21 changes: 21 additions & 0 deletions mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===- PtrEnums.h - `ptr` dialect enums -------------------------*- C++ -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file declares the `ptr` dialect enums.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_DIALECT_PTR_IR_PTRENUMS_H
#define MLIR_DIALECT_PTR_IR_PTRENUMS_H

#include "mlir/IR/BuiltinAttributeInterfaces.h"
#include "mlir/IR/OpImplementation.h"

#include "mlir/Dialect/Ptr/IR/PtrOpsEnums.h.inc"

#endif // MLIR_DIALECT_PTR_IR_PTRENUMS_H
2 changes: 2 additions & 0 deletions mlir/include/mlir/Target/LLVMIR/Dialect/All.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "mlir/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/SPIRV/SPIRVToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h"
Expand All @@ -45,6 +46,7 @@ static inline void registerAllToLLVMIRTranslations(DialectRegistry &registry) {
registerNVVMDialectTranslation(registry);
registerOpenACCDialectTranslation(registry);
registerOpenMPDialectTranslation(registry);
registerPtrDialectTranslation(registry);
registerROCDLDialectTranslation(registry);
registerSPIRVDialectTranslation(registry);
registerVCIXDialectTranslation(registry);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===- PtrToLLVMIRTranslation.h - `ptr` to LLVM IR --------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This provides registration calls for `ptr` dialect to LLVM IR translation.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_TARGET_LLVMIR_DIALECT_PTR_PTRTOLLVMIRTRANSLATION_H
#define MLIR_TARGET_LLVMIR_DIALECT_PTR_PTRTOLLVMIRTRANSLATION_H

namespace mlir {

class DialectRegistry;
class MLIRContext;

/// Register the `ptr` dialect and the translation from it to the LLVM IR in the
/// given registry;
void registerPtrDialectTranslation(DialectRegistry &registry);

/// Register the `ptr` dialect and the translation from it in the registry
/// associated with the given context.
void registerPtrDialectTranslation(MLIRContext &context);

} // namespace mlir

#endif // MLIR_TARGET_LLVMIR_DIALECT_PTR_PTRTOLLVMIRTRANSLATION_H
1 change: 1 addition & 0 deletions mlir/lib/Dialect/LLVMIR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ add_mlir_dialect_library(MLIRLLVMDialect
MLIRInferTypeOpInterface
MLIRIR
MLIRMemorySlotInterfaces
MLIRPtrMemorySpaceInterfaces
MLIRSideEffectInterfaces
MLIRSupport
)
Expand Down
83 changes: 83 additions & 0 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
#include "mlir/Dialect/Ptr/IR/PtrEnums.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/DialectImplementation.h"
#include "mlir/Interfaces/FunctionInterfaces.h"
Expand Down Expand Up @@ -50,6 +52,87 @@ void LLVMDialect::registerAttributes() {
>();
}

//===----------------------------------------------------------------------===//
// AddressSpaceAttr
//===----------------------------------------------------------------------===//

/// Checks whether the given type is an LLVM type that can be loaded or stored.
static bool isValidLoadStoreImpl(Type type, ptr::AtomicOrdering ordering,
std::optional<int64_t> alignment,
const ::mlir::DataLayout *dataLayout,
function_ref<InFlightDiagnostic()> emitError) {
if (!isLoadableType(type)) {
if (emitError)
emitError() << "type must be LLVM type with size, but got " << type;
return false;
}
if (ordering == ptr::AtomicOrdering::not_atomic)
return true;

// To check atomic validity we need a datalayout.
if (!dataLayout) {
if (emitError)
emitError() << "expected a valid data layout";
return false;
}
if (!isTypeCompatibleWithAtomicOp(type, *dataLayout)) {
if (emitError)
emitError() << "unsupported type " << type << " for atomic access";
return false;
}
return true;
}

bool AddressSpaceAttr::isValidLoad(
Type type, ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
const ::mlir::DataLayout *dataLayout,
function_ref<InFlightDiagnostic()> emitError) const {
return isValidLoadStoreImpl(type, ordering, alignment, dataLayout, emitError);
}

bool AddressSpaceAttr::isValidStore(
Type type, ptr::AtomicOrdering ordering, std::optional<int64_t> alignment,
const ::mlir::DataLayout *dataLayout,
function_ref<InFlightDiagnostic()> emitError) const {
return isValidLoadStoreImpl(type, ordering, alignment, dataLayout, emitError);
}

bool AddressSpaceAttr::isValidAtomicOp(
ptr::AtomicBinOp op, Type type, ptr::AtomicOrdering ordering,
std::optional<int64_t> alignment, const ::mlir::DataLayout *dataLayout,
function_ref<InFlightDiagnostic()> emitError) const {
// TODO: update this method once `ptr.atomic_rmw` is implemented.
assert(false && "unimplemented, see TODO in the source.");
return false;
}

bool AddressSpaceAttr::isValidAtomicXchg(
Type type, ptr::AtomicOrdering successOrdering,
ptr::AtomicOrdering failureOrdering, std::optional<int64_t> alignment,
const ::mlir::DataLayout *dataLayout,
function_ref<InFlightDiagnostic()> emitError) const {
// TODO: update this method once `ptr.atomic_cmpxchg` is implemented.
assert(false && "unimplemented, see TODO in the source.");
return false;
}

bool AddressSpaceAttr::isValidAddrSpaceCast(
Type tgt, Type src, function_ref<InFlightDiagnostic()> emitError) const {
// TODO: update this method once the `ptr.addrspace_cast` op is added to the
// dialect.
assert(false && "unimplemented, see TODO in the source.");
return false;
}

bool AddressSpaceAttr::isValidPtrIntCast(
Type intLikeTy, Type ptrLikeTy,
function_ref<InFlightDiagnostic()> emitError) const {
// TODO: update this method once the int-cast ops are added to the `ptr`
// dialect.
assert(false && "unimplemented, see TODO in the source.");
return false;
}

//===----------------------------------------------------------------------===//
// AliasScopeAttr
//===----------------------------------------------------------------------===//
Expand Down
4 changes: 2 additions & 2 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -853,8 +853,8 @@ void LoadOp::getEffects(
/// Returns true if the given type is supported by atomic operations. All
/// integer, float, and pointer types with a power-of-two bitsize and a minimal
/// size of 8 bits are supported.
static bool isTypeCompatibleWithAtomicOp(Type type,
const DataLayout &dataLayout) {
bool LLVM::isTypeCompatibleWithAtomicOp(Type type,
const DataLayout &dataLayout) {
if (!isa<IntegerType, LLVMPointerType>(type))
if (!isCompatibleFloatingPointType(type))
return false;
Expand Down
4 changes: 3 additions & 1 deletion mlir/lib/Dialect/LLVMIR/IR/LLVMTypeSyntax.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ using namespace mlir::LLVM;
/// prints it as usual.
static void dispatchPrint(AsmPrinter &printer, Type type) {
if (isCompatibleType(type) &&
!llvm::isa<IntegerType, FloatType, VectorType>(type))
!(llvm::isa<IntegerType, FloatType, VectorType>(type) ||
(llvm::isa<PtrLikeTypeInterface>(type) &&
!llvm::isa<LLVMPointerType>(type))))
return mlir::LLVM::detail::printType(type, printer);
printer.printType(type);
}
Expand Down
Loading
Loading