Skip to content
Draft
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
13 changes: 12 additions & 1 deletion mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td
Original file line number Diff line number Diff line change
Expand Up @@ -1093,8 +1093,9 @@ def LLVM_TBAATagArrayAttr
//===----------------------------------------------------------------------===//
// ConstantRangeAttr
//===----------------------------------------------------------------------===//

def LLVM_ConstantRangeAttr : LLVM_Attr<"ConstantRange", "constant_range"> {
let parameters = (ins
let parameters = (ins
"::llvm::APInt":$lower,
"::llvm::APInt":$upper
);
Expand All @@ -1119,9 +1120,19 @@ def LLVM_ConstantRangeAttr : LLVM_Attr<"ConstantRange", "constant_range"> {
return $_get($_ctxt, ::llvm::APInt(bitWidth, lower), ::llvm::APInt(bitWidth, upper));
}]>
];
/*let extraClassDeclaration = [{
::llvm::APInt getLower() const {
return getImpl()->getLower();
}
::llvm::APInt getUpper() const {
return getImpl()->getUpper();
}
}];*/


let hasCustomAssemblyFormat = 1;
let genVerifyDecl = 1;
let genStorageClass = 0;
}


Expand Down
54 changes: 54 additions & 0 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMAttrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,57 @@
namespace mlir {
namespace LLVM {

namespace detail {
struct ConstantRangeAttrStorage : public AttributeStorage {
ConstantRangeAttrStorage(llvm::APInt lower, llvm::APInt upper)
: lower(lower), upper(upper) {}

/// The hash key for this storage is a pair of the integer and type params.
using KeyTy = std::pair<llvm::APInt, llvm::APInt>;

/// Define the comparison function for the key type.
bool operator==(const KeyTy &key) const {
if (lower.getBitWidth() != key.first.getBitWidth() ||
upper.getBitWidth() != key.second.getBitWidth()) {
return false;
}
return lower == key.first && upper == key.second;
}

/// Define a hash function for the key type.
/// Note: This isn't necessary because std::pair, unsigned, and Type all have
/// hash functions already available.
static llvm::hash_code hashKey(const KeyTy &key) {
return llvm::hash_combine(key.first, key.second);
}

/// Define a construction function for the key type.
/// Note: This isn't necessary because KeyTy can be directly constructed with
/// the given parameters.
static KeyTy getKey(llvm::APInt lower, llvm::APInt upper) {
return KeyTy(lower, upper);
}

/// Define a construction method for creating a new instance of this storage.
static ConstantRangeAttrStorage *construct(mlir::StorageUniquer::StorageAllocator &allocator, const KeyTy &key) {
return new (allocator.allocate<ConstantRangeAttrStorage>())
ConstantRangeAttrStorage(key.first, key.second);
}

/// Construct an instance of the key from this storage class.
KeyTy getAsKey() const {
return KeyTy(lower, upper);
}

llvm::APInt getLower() const { return lower; }
llvm::APInt getUpper() const { return upper; }

/// The parametric data held by the storage class.
llvm::APInt lower;
llvm::APInt upper;
};
}

/// This class represents the base attribute for all debug info attributes.
class DINodeAttr : public Attribute {
public:
Expand Down Expand Up @@ -96,6 +147,9 @@ using linkage::Linkage;

#include "mlir/Dialect/LLVMIR/LLVMAttrInterfaces.h.inc"




#define GET_ATTRDEF_CLASSES
#include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.h.inc"

Expand Down
108 changes: 104 additions & 4 deletions mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1164,12 +1164,12 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
let arguments = (ins FlatSymbolRefAttr:$global_name);
let results = (outs LLVM_AnyPointer:$res);

let summary = "Creates a pointer pointing to a global or a function";
let summary = "Creates a pointer pointing to a global, alias or a function";

let description = [{
Creates an SSA value containing a pointer to a global variable or constant
defined by `llvm.mlir.global`. The global value can be defined after its
first referenced. If the global value is a constant, storing into it is not
Creates an SSA value containing a pointer to a global value (function,
variable or alias). The global value can be defined after its first
referenced. If the global value is a constant, storing into it is not
allowed.

Examples:
Expand All @@ -1187,10 +1187,19 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",

// The function address can be used for indirect calls.
llvm.call %2() : !llvm.ptr, () -> ()

// Get the address of an aliased global.
%3 = llvm.mlir.addressof @const_alias : !llvm.ptr
}

// Define the global.
llvm.mlir.global @const(42 : i32) : i32

// Define an alias.
llvm.mlir.alias @const_alias : i32 {
%0 = llvm.mlir.addressof @const : !llvm.ptr
llvm.return %0 : !llvm.ptr
}
```
}];

Expand All @@ -1209,6 +1218,14 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
build($_builder, $_state,
LLVM::LLVMPointerType::get($_builder.getContext()), func.getName());
$_state.addAttributes(attrs);
}]>,
OpBuilder<(ins "AliasOp":$alias,
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs),
[{
build($_builder, $_state,
LLVM::LLVMPointerType::get($_builder.getContext(), alias.getAddrSpace()),
alias.getSymName());
$_state.addAttributes(attrs);
}]>
];

Expand All @@ -1220,7 +1237,11 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
/// Return the llvm.func operation that is referenced here.
LLVMFuncOp getFunction(SymbolTableCollection &symbolTable);

/// Return the llvm.mlir.alias operation that defined the value referenced
/// here.
AliasOp getAlias(SymbolTableCollection &symbolTable);
}];

let assemblyFormat = "$global_name attr-dict `:` qualified(type($res))";

let hasFolder = 1;
Expand Down Expand Up @@ -1450,6 +1471,85 @@ def LLVM_GlobalDtorsOp : LLVM_Op<"mlir.global_dtors", [
let hasVerifier = 1;
}

def LLVM_AliasOp : LLVM_Op<"mlir.alias",
[IsolatedFromAbove, SingleBlockImplicitTerminator<"ReturnOp">, Symbol]> {
let arguments = (ins
TypeAttr:$alias_type,
StrAttr:$sym_name,
Linkage:$linkage,
UnitAttr:$dso_local,
UnitAttr:$thread_local_,
OptionalAttr<UnnamedAddr>:$unnamed_addr,
DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
);
let summary = "LLVM dialect alias.";
let description = [{
`llvm.mlir.alias` is a top level operation that defines a global alias for
global variables and functions. The operation is always initialized by
using a initializer region which could be a direct map to another global
value or contain some address computation on top of it.

It uses a symbol for its value, which will be uniqued by the module
with respect to other symbols in it.

Similarly to functions and globals, they can also have a linkage attribute.
This attribute is placed between `llvm.mlir.alias` and the symbol name. If
the attribute is omitted, `external` linkage is assumed by default.

Examples:

```mlir
// Global alias use @-identifiers.
llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
%0 = llvm.mlir.addressof @some_function : !llvm.ptr
llvm.return %0 : !llvm.ptr
}

// More complex initialization.
llvm.mlir.alias linkonce_odr hidden @glob
{addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
%0 = llvm.mlir.constant(1234 : i64) : i64
%1 = llvm.mlir.addressof @glob.private : !llvm.ptr
%2 = llvm.ptrtoint %1 : !llvm.ptr to i64
%3 = llvm.add %2, %0 : i64
%4 = llvm.inttoptr %3 : i64 to !llvm.ptr
llvm.return %4 : !llvm.ptr
}
```
}];
let regions = (region SizedRegion<1>:$initializer);

let builders = [
OpBuilder<(ins "Type":$type, "Linkage":$linkage,
"StringRef":$name,
CArg<"bool", "false">:$dsoLocal,
CArg<"bool", "false">:$thread_local_,
CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>
];

let extraClassDeclaration = [{
/// Return the LLVM type of the global alias.
Type getType() {
return getAliasType();
}
/// Return the initializer region. It's always present and terminates
/// with an `llvm.return` op with the initializer value.
Region &getInitializerRegion() {
return getOperation()->getRegion(0);
}
Block &getInitializerBlock() {
return getInitializerRegion().front();
}
// Retrieve address space information from the initializer block
// result.
unsigned getAddrSpace();
}];

let hasCustomAssemblyFormat = 1;
let hasVerifier = 1;
let hasRegionVerifier = 1;
}

def LLVM_ComdatSelectorOp : LLVM_Op<"comdat_selector", [Symbol]> {
let arguments = (ins
SymbolNameAttr:$sym_name,
Expand Down
8 changes: 8 additions & 0 deletions mlir/include/mlir/Target/LLVMIR/ModuleImport.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ class ModuleImport {
/// Converts all global variables of the LLVM module to MLIR global variables.
LogicalResult convertGlobals();

/// Converts all aliases of the LLVM module to MLIR variables.
LogicalResult convertAliases();

/// Converts the data layout of the LLVM module to an MLIR data layout
/// specification.
LogicalResult convertDataLayout();
Expand Down Expand Up @@ -284,6 +287,9 @@ class ModuleImport {
LogicalResult convertGlobal(llvm::GlobalVariable *globalVar);
/// Imports the magic globals "global_ctors" and "global_dtors".
LogicalResult convertGlobalCtorsAndDtors(llvm::GlobalVariable *globalVar);
/// Converts an LLVM global alias variable into an MLIR LLVM dialect alias
/// operation if a conversion exists. Otherwise, returns failure.
LogicalResult convertAlias(llvm::GlobalAlias *alias);
/// Returns personality of `func` as a FlatSymbolRefAttr.
FlatSymbolRefAttr getPersonalityAsAttr(llvm::Function *func);
/// Imports `bb` into `block`, which must be initially empty.
Expand Down Expand Up @@ -393,6 +399,8 @@ class ModuleImport {
Operation *constantInsertionOp = nullptr;
/// Operation to insert the next global after.
Operation *globalInsertionOp = nullptr;
/// Operation to insert the next alias after.
Operation *aliasInsertionOp = nullptr;
/// Operation to insert comdat selector operations into.
ComdatOp globalComdatOp = nullptr;
/// The current context.
Expand Down
18 changes: 17 additions & 1 deletion mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ class ModuleTranslation {
return globalsMapping.lookup(op);
}

/// Finds an LLVM IR global value that corresponds to the given MLIR operation
/// defining a global alias value.
llvm::GlobalValue *lookupAlias(Operation *op) {
return aliasesMapping.lookup(op);
}

/// Returns the OpenMP IR builder associated with the LLVM IR module being
/// constructed.
llvm::OpenMPIRBuilder *getOpenMPBuilder();
Expand Down Expand Up @@ -321,7 +327,13 @@ class ModuleTranslation {
LogicalResult convertFunctionSignatures();
LogicalResult convertFunctions();
LogicalResult convertComdats();
LogicalResult convertGlobals();

/// Handle conversion for both globals and global aliases.
///
/// - Create named global variables that correspond to llvm.mlir.global
/// definitions, similarly Convert llvm.global_ctors and global_dtors ops.
/// - Create global alias that correspond to llvm.mlir.alias.
LogicalResult convertGlobalsAndAliases();
LogicalResult convertOneFunction(LLVMFuncOp func);
LogicalResult convertBlockImpl(Block &bb, bool ignoreArguments,
llvm::IRBuilderBase &builder,
Expand Down Expand Up @@ -366,6 +378,10 @@ class ModuleTranslation {
/// Mappings between llvm.mlir.global definitions and corresponding globals.
DenseMap<Operation *, llvm::GlobalValue *> globalsMapping;

/// Mappings between llvm.mlir.alias definitions and corresponding global
/// aliases.
DenseMap<Operation *, llvm::GlobalValue *> aliasesMapping;

/// A stateful object used to translate types.
TypeToLLVMIRTranslator typeTranslator;

Expand Down
8 changes: 8 additions & 0 deletions mlir/lib/Dialect/LLVMIR/IR/LLVMAttrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,14 @@ DIRecursiveTypeAttrInterface DISubprogramAttr::getRecSelf(DistinctAttr recId) {
// ConstantRangeAttr
//===----------------------------------------------------------------------===//

llvm::APInt ConstantRangeAttr::getLower() const {
return getImpl()->getLower();
}

llvm::APInt ConstantRangeAttr::getUpper() const {
return getImpl()->getUpper();
}

Attribute ConstantRangeAttr::parse(AsmParser &parser, Type odsType) {
llvm::SMLoc loc = parser.getCurrentLocation();
IntegerType widthType;
Expand Down
Loading