2019-01-15 10:53:22 -08:00
|
|
|
//===- LLVMDialect.cpp - LLVM IR Ops and Dialect registration -------------===//
|
|
|
|
//
|
|
|
|
// Copyright 2019 The MLIR Authors.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
// =============================================================================
|
|
|
|
//
|
|
|
|
// This file defines the types and operation details for the LLVM IR dialect in
|
|
|
|
// MLIR, and the LLVM IR dialect. It also registers the dialect.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/LLVMIR/LLVMDialect.h"
|
|
|
|
#include "mlir/IR/MLIRContext.h"
|
2019-03-06 09:34:53 -08:00
|
|
|
#include "llvm/IR/Function.h"
|
2019-01-15 10:53:22 -08:00
|
|
|
|
|
|
|
#include "llvm/AsmParser/Parser.h"
|
2019-03-06 09:34:53 -08:00
|
|
|
#include "llvm/IR/Attributes.h"
|
2019-01-15 10:53:22 -08:00
|
|
|
#include "llvm/IR/Type.h"
|
|
|
|
#include "llvm/Support/SourceMgr.h"
|
|
|
|
|
|
|
|
using namespace mlir;
|
|
|
|
using namespace mlir::LLVM;
|
|
|
|
|
|
|
|
namespace mlir {
|
|
|
|
namespace LLVM {
|
|
|
|
namespace detail {
|
2019-01-15 12:54:01 -08:00
|
|
|
struct LLVMTypeStorage : public ::mlir::detail::TypeStorage {
|
|
|
|
LLVMTypeStorage(llvm::Type *ty) : underlyingType(ty) {}
|
|
|
|
|
2019-01-15 10:53:22 -08:00
|
|
|
// LLVM types are pointer-unique.
|
|
|
|
using KeyTy = llvm::Type *;
|
2019-01-15 12:54:01 -08:00
|
|
|
bool operator==(const KeyTy &key) const { return key == underlyingType; }
|
2019-01-15 10:53:22 -08:00
|
|
|
|
|
|
|
static LLVMTypeStorage *construct(TypeStorageAllocator &allocator,
|
2019-01-15 12:54:01 -08:00
|
|
|
llvm::Type *ty) {
|
|
|
|
return new (allocator.allocate<LLVMTypeStorage>()) LLVMTypeStorage(ty);
|
2019-01-15 10:53:22 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
llvm::Type *underlyingType;
|
|
|
|
};
|
|
|
|
} // end namespace detail
|
|
|
|
} // end namespace LLVM
|
|
|
|
} // end namespace mlir
|
|
|
|
|
|
|
|
char LLVMType::typeID = '\0';
|
|
|
|
|
|
|
|
LLVMType LLVMType::get(MLIRContext *context, llvm::Type *llvmType) {
|
|
|
|
return Base::get(context, FIRST_LLVM_TYPE, llvmType);
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm::Type *LLVMType::getUnderlyingType() const {
|
|
|
|
return static_cast<ImplType *>(type)->underlyingType;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---- LLVM IR Dialect and its registration ----------------------------- */
|
|
|
|
|
|
|
|
LLVMDialect::LLVMDialect(MLIRContext *context)
|
|
|
|
: Dialect("llvm", context), module("LLVMDialectModule", llvmContext) {
|
|
|
|
addTypes<LLVMType>();
|
|
|
|
#define GET_OP_LIST
|
|
|
|
addOperations<
|
2019-03-01 13:48:24 -08:00
|
|
|
#include "mlir/LLVMIR/LLVMOps.inc"
|
2019-01-15 10:53:22 -08:00
|
|
|
>();
|
2019-02-25 13:16:24 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Parse a type registered to this dialect.
|
|
|
|
Type LLVMDialect::parseType(StringRef tyData, Location loc,
|
|
|
|
MLIRContext *context) const {
|
|
|
|
llvm::SMDiagnostic errorMessage;
|
|
|
|
llvm::Type *type = llvm::parseType(tyData, errorMessage, module);
|
|
|
|
if (!type)
|
|
|
|
return (context->emitError(loc, errorMessage.getMessage()), nullptr);
|
|
|
|
return LLVMType::get(context, type);
|
|
|
|
}
|
2019-01-15 10:53:22 -08:00
|
|
|
|
2019-02-25 13:16:24 -08:00
|
|
|
/// Print a type registered to this dialect.
|
|
|
|
void LLVMDialect::printType(Type type, raw_ostream &os) const {
|
|
|
|
auto llvmType = type.dyn_cast<LLVMType>();
|
|
|
|
assert(llvmType && "printing wrong type");
|
|
|
|
assert(llvmType.getUnderlyingType() && "no underlying LLVM type");
|
|
|
|
llvmType.getUnderlyingType()->print(os);
|
2019-01-15 10:53:22 -08:00
|
|
|
}
|
|
|
|
|
2019-03-06 09:34:53 -08:00
|
|
|
/// Verify LLVMIR function argument attributes.
|
|
|
|
bool LLVMDialect::verifyFunctionArgAttribute(const Function *func,
|
|
|
|
unsigned argIdx,
|
|
|
|
NamedAttribute argAttr) {
|
|
|
|
// Check that llvm.noalias is a boolean attribute.
|
|
|
|
if (argAttr.first == StringRef("llvm.noalias"))
|
|
|
|
return (!argAttr.second.isa<BoolAttr>());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-01-15 10:53:22 -08:00
|
|
|
static DialectRegistration<LLVMDialect> llvmDialect;
|